summaryrefslogtreecommitdiff
path: root/test/Transforms/InstSimplify
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-03-12 11:19:31 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-03-12 11:19:31 +0000
commitfc72ae613afd7ca2526bb66156bafe8b0054cb3b (patch)
treec25757bf86fcac9b4b369729c274ef0be0e682ba /test/Transforms/InstSimplify
parent747cccf0dc345ab63894ce498233868cf110b717 (diff)
downloadllvm-fc72ae613afd7ca2526bb66156bafe8b0054cb3b.tar.gz
llvm-fc72ae613afd7ca2526bb66156bafe8b0054cb3b.tar.bz2
llvm-fc72ae613afd7ca2526bb66156bafe8b0054cb3b.tar.xz
Teach instsimplify how to constant fold pointer differences.
Typically instcombine has handled this, but pointer differences show up in several contexts where we would like to get constant folding, and cannot afford to run instcombine. Specifically, I'm working on improving the constant folding of arguments used in inline cost analysis with instsimplify. Doing this in instsimplify implies some algorithm changes. We have to handle multiple layers of all-constant GEPs because instsimplify cannot fold them into a single GEP the way instcombine can. Also, we're only interested in all-constant GEPs. The result is that this doesn't really replace the instcombine logic, it's just complimentary and focused on constant folding. Reviewed on IRC by Benjamin Kramer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152555 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/InstSimplify')
-rw-r--r--test/Transforms/InstSimplify/ptr_diff.ll33
1 files changed, 33 insertions, 0 deletions
diff --git a/test/Transforms/InstSimplify/ptr_diff.ll b/test/Transforms/InstSimplify/ptr_diff.ll
new file mode 100644
index 0000000000..013964ccfe
--- /dev/null
+++ b/test/Transforms/InstSimplify/ptr_diff.ll
@@ -0,0 +1,33 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+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.int = ptrtoint i8* %first to i64
+ %last.int = ptrtoint i8* %last to i64
+ %diff = sub i64 %last.int, %first.int
+ ret i64 %diff
+}
+
+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
+ %first.int = ptrtoint i8* %first4 to i64
+ %last.int = ptrtoint i8* %last4 to i64
+ %diff = sub i64 %last.int, %first.int
+ ret i64 %diff
+}