summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaud A. de Grandmaison <arnaud.adegm@gmail.com>2013-03-22 08:25:01 +0000
committerArnaud A. de Grandmaison <arnaud.adegm@gmail.com>2013-03-22 08:25:01 +0000
commitf364bc63e71355a94ca1ef442e7e5af64973239d (patch)
tree4edb459905de7e6370ae14926a0437201e04e252
parentf1311dfce1d434c724cd6ec5c1cf13e268b23511 (diff)
downloadbcm5719-llvm-f364bc63e71355a94ca1ef442e7e5af64973239d.tar.gz
bcm5719-llvm-f364bc63e71355a94ca1ef442e7e5af64973239d.zip
InstCombine: Improve the result bitvect type when folding (cmp pred (load (gep GV, i)) C) to a bit test.
The original code used i32, and i64 if legal. This introduced unneeded casts when they aren't legal, or when the index variable i has another type. In order of preference: try to use i's type; use the smallest fitting legal type (using an added DataLayout method); default to i32. A testcase checks that this works when the index gep operand is i16. Patch by : Ahmed Bougacha <ahmed.bougacha@gmail.com> Reviewed by : Duncan llvm-svn: 177712
-rw-r--r--llvm/include/llvm/IR/DataLayout.h4
-rw-r--r--llvm/lib/IR/DataLayout.cpp7
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp31
-rw-r--r--llvm/test/Transforms/InstCombine/load-cmp.ll12
4 files changed, 43 insertions, 11 deletions
diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index 72b4eedabdc..547d857b7b7 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -352,6 +352,10 @@ public:
/// type.
Type *getIntPtrType(Type *) const;
+ /// getSmallestLegalIntType - Return the smallest integer type with size at
+ /// least as big as Width bits.
+ Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const;
+
/// getIndexedOffset - return the offset from the beginning of the type for
/// the specified indices. This is used to implement getelementptr.
uint64_t getIndexedOffset(Type *Ty, ArrayRef<Value *> Indices) const;
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index 95966749127..ecd5216f20a 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -621,6 +621,13 @@ Type *DataLayout::getIntPtrType(Type *Ty) const {
return IntTy;
}
+Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const {
+ for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i)
+ if (Width <= LegalIntWidths[i])
+ return Type::getIntNTy(C, LegalIntWidths[i]);
+ return 0;
+}
+
uint64_t DataLayout::getIndexedOffset(Type *ptrTy,
ArrayRef<Value *> Indices) const {
Type *Ty = ptrTy;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 32fdb9b708b..a4e117e4c4b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -443,20 +443,29 @@ FoldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP, GlobalVariable *GV,
}
- // If a 32-bit or 64-bit magic bitvector captures the entire comparison state
+ // If a magic bitvector captures the entire comparison state
// of this load, replace it with computation that does:
// ((magic_cst >> i) & 1) != 0
- if (ArrayElementCount <= 32 ||
- (TD && ArrayElementCount <= 64 && TD->isLegalInteger(64))) {
- Type *Ty;
- if (ArrayElementCount <= 32)
+ {
+ Type *Ty = 0;
+
+ // Look for an appropriate type:
+ // - The type of Idx if the magic fits
+ // - The smallest fitting legal type if we have a DataLayout
+ // - Default to i32
+ if (ArrayElementCount <= Idx->getType()->getIntegerBitWidth())
+ Ty = Idx->getType();
+ else if (TD)
+ Ty = TD->getSmallestLegalIntType(Init->getContext(), ArrayElementCount);
+ else if (ArrayElementCount <= 32)
Ty = Type::getInt32Ty(Init->getContext());
- else
- Ty = Type::getInt64Ty(Init->getContext());
- Value *V = Builder->CreateIntCast(Idx, Ty, false);
- V = Builder->CreateLShr(ConstantInt::get(Ty, MagicBitvector), V);
- V = Builder->CreateAnd(ConstantInt::get(Ty, 1), V);
- return new ICmpInst(ICmpInst::ICMP_NE, V, ConstantInt::get(Ty, 0));
+
+ if (Ty != 0) {
+ Value *V = Builder->CreateIntCast(Idx, Ty, false);
+ V = Builder->CreateLShr(ConstantInt::get(Ty, MagicBitvector), V);
+ V = Builder->CreateAnd(ConstantInt::get(Ty, 1), V);
+ return new ICmpInst(ICmpInst::ICMP_NE, V, ConstantInt::get(Ty, 0));
+ }
}
return 0;
diff --git a/llvm/test/Transforms/InstCombine/load-cmp.ll b/llvm/test/Transforms/InstCombine/load-cmp.ll
index 5cafb7787e3..d88188e4109 100644
--- a/llvm/test/Transforms/InstCombine/load-cmp.ll
+++ b/llvm/test/Transforms/InstCombine/load-cmp.ll
@@ -47,6 +47,18 @@ define i1 @test4(i32 %X) {
; CHECK-NEXT: ret i1 %R
}
+define i1 @test4_i16(i16 %X) {
+ %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i16 %X
+ %Q = load i16* %P
+ %R = icmp sle i16 %Q, 73
+ ret i1 %R
+; CHECK: @test4_i16
+; CHECK-NEXT: lshr i16 933, %X
+; CHECK-NEXT: and i16 {{.*}}, 1
+; CHECK-NEXT: %R = icmp ne i16 {{.*}}, 0
+; CHECK-NEXT: ret i1 %R
+}
+
define i1 @test5(i32 %X) {
%P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
%Q = load i16* %P
OpenPOWER on IntegriCloud