diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 005f1a0bc4f..90ab4f43df0 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -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(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. diff --git a/test/Transforms/InstCombine/load-cmp.ll b/test/Transforms/InstCombine/load-cmp.ll index a3b68316aa5..fe5df928439 100644 --- a/test/Transforms/InstCombine/load-cmp.ll +++ b/test/Transforms/InstCombine/load-cmp.ll @@ -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