aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-03-25 20:43:07 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-03-25 20:43:07 +0000
commit9d9e29b4a83818b066c09c8f832cec7641aa2115 (patch)
treecba92b550738be6765b9571bba387862602a9e0a
parent805853bc59ecdae1746473d2b4178e9275a1b997 (diff)
downloadexternal_llvm-9d9e29b4a83818b066c09c8f832cec7641aa2115.zip
external_llvm-9d9e29b4a83818b066c09c8f832cec7641aa2115.tar.gz
external_llvm-9d9e29b4a83818b066c09c8f832cec7641aa2115.tar.bz2
Switch the pointer-difference simplification logic to only work with
inbounds GEPs. This isn't really necessary for simplifying pointer differences, but I'm planning to re-use the same code to simplify pointer comparisons where it is necessary. Since real code almost exclusively uses inbounds GEPs, it doesn't seem worth it to support the extra complexity of turning it on and off. If anyone would like that back, feel free to shout. Note that instcombine will still catch any of these patterns. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153418 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/InstructionSimplify.cpp2
-rw-r--r--test/Transforms/InstSimplify/ptr_diff.ll35
2 files changed, 26 insertions, 11 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index aaf9de2..bb70d1c 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<GEPOperator>(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 013964c..1eb1fd4 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
+}