Truncate GEP indexes larger than the pointer size down to pointer size
authorChris Lattner <sabre@nondot.org>
Mon, 4 Jan 2010 18:57:15 +0000 (18:57 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 4 Jan 2010 18:57:15 +0000 (18:57 +0000)
when doing this transform if the GEP is not inbounds.  No testcase because
it is very difficult to trigger this: instcombine already canonicalizes
GEP indices to pointer size, so it relies specific permutations of the
instcombine worklist.

Thanks to Duncan for pointing this possible problem out.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92495 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstCombine/load-cmp.ll

index 005f1a0bc4fc9c984695c77e77564c4dd831bd87..90ab4f43df0933fb476a7645256b69493f8761e8 100644 (file)
@@ -197,6 +197,9 @@ static void ComputeUnsignedMinMaxValuesFromKnownBits(const APInt &KnownZero,
 Instruction *InstCombiner::
 FoldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP, GlobalVariable *GV,
                              CmpInst &ICI, ConstantInt *AndCst) {
+  // We need TD information to know the pointer size unless this is inbounds.
+  if (!GEP->isInBounds() && TD == 0) return 0;
+  
   ConstantArray *Init = dyn_cast<ConstantArray>(GV->getInitializer());
   if (Init == 0 || Init->getNumOperands() > 1024) return 0;
   
@@ -354,6 +357,12 @@ FoldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP, GlobalVariable *GV,
   // order the state machines in complexity of the generated code.
   Value *Idx = GEP->getOperand(2);
 
+  // If the index is larger than the pointer size of the target, truncate the
+  // index down like the GEP would do implicitly.  We don't have to do this for
+  // an inbounds GEP because the index can't be out of range.
+  if (!GEP->isInBounds() &&
+      Idx->getType()->getPrimitiveSizeInBits() > TD->getPointerSizeInBits())
+    Idx = Builder->CreateTrunc(Idx, TD->getIntPtrType(Idx->getContext()));
   
   // If the comparison is only true for one or two elements, emit direct
   // comparisons.
index a3b68316aa5ed22013de49a08628592bc4b693af..fe5df928439b2100722d26da4ff081dc62cdc3dd 100644 (file)
@@ -6,7 +6,7 @@
    [double -10.0, double 1.0, double 4.0, double 2.0, double -20.0, double -40.0]
 
 define i1 @test1(i32 %X) {
-  %P = getelementptr [10 x i16]* @G16, i32 0, i32 %X
+  %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
   %Q = load i16* %P
   %R = icmp eq i16 %Q, 0
   ret i1 %R
@@ -16,7 +16,7 @@ define i1 @test1(i32 %X) {
 }
 
 define i1 @test2(i32 %X) {
-  %P = getelementptr [10 x i16]* @G16, i32 0, i32 %X
+  %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
   %Q = load i16* %P
   %R = icmp slt i16 %Q, 85
   ret i1 %R
@@ -26,7 +26,7 @@ define i1 @test2(i32 %X) {
 }
 
 define i1 @test3(i32 %X) {
-  %P = getelementptr [6 x double]* @GD, i32 0, i32 %X
+  %P = getelementptr inbounds [6 x double]* @GD, i32 0, i32 %X
   %Q = load double* %P
   %R = fcmp oeq double %Q, 1.0
   ret i1 %R
@@ -36,7 +36,7 @@ define i1 @test3(i32 %X) {
 }
 
 define i1 @test4(i32 %X) {
-  %P = getelementptr [10 x i16]* @G16, i32 0, i32 %X
+  %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
   %Q = load i16* %P
   %R = icmp sle i16 %Q, 73
   ret i1 %R
@@ -48,7 +48,7 @@ define i1 @test4(i32 %X) {
 }
 
 define i1 @test5(i32 %X) {
-  %P = getelementptr [10 x i16]* @G16, i32 0, i32 %X
+  %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
   %Q = load i16* %P
   %R = icmp eq i16 %Q, 69
   ret i1 %R
@@ -60,7 +60,7 @@ define i1 @test5(i32 %X) {
 }
 
 define i1 @test6(i32 %X) {
-  %P = getelementptr [6 x double]* @GD, i32 0, i32 %X
+  %P = getelementptr inbounds [6 x double]* @GD, i32 0, i32 %X
   %Q = load double* %P
   %R = fcmp ogt double %Q, 0.0
   ret i1 %R
@@ -71,7 +71,7 @@ define i1 @test6(i32 %X) {
 }
 
 define i1 @test7(i32 %X) {
-  %P = getelementptr [6 x double]* @GD, i32 0, i32 %X
+  %P = getelementptr inbounds [6 x double]* @GD, i32 0, i32 %X
   %Q = load double* %P
   %R = fcmp olt double %Q, 0.0
   ret i1 %R
@@ -82,7 +82,7 @@ define i1 @test7(i32 %X) {
 }
 
 define i1 @test8(i32 %X) {
-  %P = getelementptr [10 x i16]* @G16, i32 0, i32 %X
+  %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
   %Q = load i16* %P
   %R = and i16 %Q, 3
   %S = icmp eq i16 %R, 0
@@ -101,7 +101,7 @@ define i1 @test8(i32 %X) {
 ]
 
 define i1 @test9(i32 %X) {
-  %P = getelementptr [4 x { i32, i32 } ]* @GA, i32 0, i32 %X, i32 1
+  %P = getelementptr inbounds [4 x { i32, i32 } ]* @GA, i32 0, i32 %X, i32 1
   %Q = load i32* %P
   %R = icmp eq i32 %Q, 1
   ret i1 %R