diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index aaf9de28da4..bb70d1cfc3c 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -710,7 +710,7 @@ static Constant *stripAndComputeConstantOffsets(const TargetData &TD, Visited.insert(V); do { if (GEPOperator *GEP = dyn_cast(V)) { - if (!accumulateGEPOffset(TD, GEP, Offset)) + if (!GEP->isInBounds() || !accumulateGEPOffset(TD, GEP, Offset)) break; V = GEP->getPointerOperand(); } else if (Operator::getOpcode(V) == Instruction::BitCast) { diff --git a/test/Transforms/InstSimplify/ptr_diff.ll b/test/Transforms/InstSimplify/ptr_diff.ll index 013964ccfec..1eb1fd4c097 100644 --- a/test/Transforms/InstSimplify/ptr_diff.ll +++ b/test/Transforms/InstSimplify/ptr_diff.ll @@ -6,8 +6,8 @@ define i64 @ptrdiff1(i8* %ptr) { ; CHECK: @ptrdiff1 ; CHECK-NEXT: ret i64 42 - %first = getelementptr i8* %ptr, i32 0 - %last = getelementptr i8* %ptr, i32 42 + %first = getelementptr inbounds i8* %ptr, i32 0 + %last = getelementptr inbounds i8* %ptr, i32 42 %first.int = ptrtoint i8* %first to i64 %last.int = ptrtoint i8* %last to i64 %diff = sub i64 %last.int, %first.int @@ -18,16 +18,31 @@ define i64 @ptrdiff2(i8* %ptr) { ; CHECK: @ptrdiff2 ; CHECK-NEXT: ret i64 42 - %first1 = getelementptr i8* %ptr, i32 0 - %first2 = getelementptr i8* %first1, i32 1 - %first3 = getelementptr i8* %first2, i32 2 - %first4 = getelementptr i8* %first3, i32 4 - %last1 = getelementptr i8* %first2, i32 48 - %last2 = getelementptr i8* %last1, i32 8 - %last3 = getelementptr i8* %last2, i32 -4 - %last4 = getelementptr i8* %last3, i32 -4 + %first1 = getelementptr inbounds i8* %ptr, i32 0 + %first2 = getelementptr inbounds i8* %first1, i32 1 + %first3 = getelementptr inbounds i8* %first2, i32 2 + %first4 = getelementptr inbounds i8* %first3, i32 4 + %last1 = getelementptr inbounds i8* %first2, i32 48 + %last2 = getelementptr inbounds i8* %last1, i32 8 + %last3 = getelementptr inbounds i8* %last2, i32 -4 + %last4 = getelementptr inbounds i8* %last3, i32 -4 %first.int = ptrtoint i8* %first4 to i64 %last.int = ptrtoint i8* %last4 to i64 %diff = sub i64 %last.int, %first.int ret i64 %diff } + +define i64 @ptrdiff3(i8* %ptr) { +; Don't bother with non-inbounds GEPs. +; CHECK: @ptrdiff3 +; CHECK: getelementptr +; CHECK: sub +; CHECK: ret + + %first = getelementptr i8* %ptr, i32 0 + %last = getelementptr i8* %ptr, i32 42 + %first.int = ptrtoint i8* %first to i64 + %last.int = ptrtoint i8* %last to i64 + %diff = sub i64 %last.int, %first.int + ret i64 %diff +}