diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 21108c64535..599a6f650fd 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -687,7 +687,7 @@ BasicAliasAnalysis::CheckGEPInstructions( if (isa(GEP1Ops[i]) && !cast(GEP1Ops[i])->isZero()) { // Yup, there's a constant in the tail. Set all variables to - // constants in the GEP instruction to make it suiteable for + // constants in the GEP instruction to make it suitable for // TargetData::getIndexedOffset. for (i = 0; i != MaxOperands; ++i) if (!isa(GEP1Ops[i])) @@ -702,9 +702,15 @@ BasicAliasAnalysis::CheckGEPInstructions( int64_t Offset2 = TD.getIndexedOffset(GEPPointerTy, GEP1Ops, MinOperands); + // Make sure we compare the absolute difference. + if (Offset1 > Offset2) + std::swap(Offset1, Offset2); + // If the tail provided a bit enough offset, return noalias! if ((uint64_t)(Offset2-Offset1) >= SizeMax) return NoAlias; + // Otherwise break - we don't look for another constant in the tail. + break; } } diff --git a/test/Analysis/BasicAA/2008-06-02-GEPTailCrash.ll b/test/Analysis/BasicAA/2008-06-02-GEPTailCrash.ll new file mode 100644 index 00000000000..40d1e32d673 --- /dev/null +++ b/test/Analysis/BasicAA/2008-06-02-GEPTailCrash.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | opt -gvn -disable-output +; PR2395 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + %struct.S291 = type <{ %union.anon, i32 }> + %union.anon = type { } +@a291 = external global [5 x %struct.S291] ; <[5 x %struct.S291]*> [#uses=2] + +define void @test291() nounwind { +entry: + store i32 1138410269, i32* getelementptr ([5 x %struct.S291]* @a291, i32 0, i32 2, i32 1) + %tmp54 = load i32* bitcast (%struct.S291* getelementptr ([5 x %struct.S291]* @a291, i32 0, i32 2) to i32*), align 4 ; [#uses=0] + unreachable +}