aboutsummaryrefslogtreecommitdiff
path: root/test/Transforms/InstSimplify/compare.ll
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-12-07 02:08:58 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-12-07 02:08:58 +0000
commit70d3bebc8bc857fcf3d7fac44bda884d5e2a7040 (patch)
tree02d3047cbe28a3ed9cbca567a5e16a3222cfd0d3 /test/Transforms/InstSimplify/compare.ll
parentb02ed5b8eafd11500bbefb7206ecbf5bc3fc324a (diff)
Add support to ValueTracking for determining that a pointer is non-null
by virtue of inbounds GEPs that preclude a null pointer. This is a very common pattern in the code generated by std::vector and other standard library routines which use allocators that test for null pervasively. This is one step closer to teaching Clang+LLVM to be able to produce an empty function for: void f() { std::vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); } Which is related to getting them to completely fold SmallVector push_back sequences into constants when inlining and other optimizations make that a possibility. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169573 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/InstSimplify/compare.ll')
-rw-r--r--test/Transforms/InstSimplify/compare.ll40
1 files changed, 40 insertions, 0 deletions
diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll
index ce2bb799c8..56627b99a4 100644
--- a/test/Transforms/InstSimplify/compare.ll
+++ b/test/Transforms/InstSimplify/compare.ll
@@ -165,6 +165,46 @@ entry:
ret i1 %cmp
}
+define i1 @gep13(i8* %ptr) {
+; CHECK: @gep13
+; We can prove this GEP is non-null because it is inbounds.
+ %x = getelementptr inbounds i8* %ptr, i32 1
+ %cmp = icmp eq i8* %x, null
+ ret i1 %cmp
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @gep14({ {}, i8 }* %ptr) {
+; CHECK: @gep14
+; We can't simplify this because the offset of one in the GEP actually doesn't
+; move the pointer.
+ %x = getelementptr inbounds { {}, i8 }* %ptr, i32 0, i32 1
+ %cmp = icmp eq i8* %x, null
+ ret i1 %cmp
+; CHECK-NOT: ret i1 false
+}
+
+define i1 @gep15({ {}, [4 x {i8, i8}]}* %ptr, i32 %y) {
+; CHECK: @gep15
+; We can prove this GEP is non-null even though there is a user value, as we
+; would necessarily violate inbounds on one side or the other.
+ %x = getelementptr inbounds { {}, [4 x {i8, i8}]}* %ptr, i32 0, i32 1, i32 %y, i32 1
+ %cmp = icmp eq i8* %x, null
+ ret i1 %cmp
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @gep16(i8* %ptr, i32 %a) {
+; CHECK: @gep16
+; We can prove this GEP is non-null because it is inbounds and because we know
+; %b is non-zero even though we don't know its value.
+ %b = or i32 %a, 1
+ %x = getelementptr inbounds i8* %ptr, i32 %b
+ %cmp = icmp eq i8* %x, null
+ ret i1 %cmp
+; CHECK-NEXT: ret i1 false
+}
+
define i1 @zext(i32 %x) {
; CHECK: @zext
%e1 = zext i32 %x to i64