InstCombine: Fold comparisons between unguessable allocas and other pointers
[oota-llvm.git] / test / Transforms / InstCombine / compare-alloca.ll
1 ; RUN: opt -instcombine -S %s | FileCheck %s
2 target datalayout = "p:32:32"
3
4
5 define i1 @alloca_argument_compare(i64* %arg) {
6   %alloc = alloca i64
7   %cmp = icmp eq i64* %arg, %alloc
8   ret i1 %cmp
9   ; CHECK-LABEL: alloca_argument_compare
10   ; CHECK: ret i1 false
11 }
12
13 define i1 @alloca_argument_compare_swapped(i64* %arg) {
14   %alloc = alloca i64
15   %cmp = icmp eq i64* %alloc, %arg
16   ret i1 %cmp
17   ; CHECK-LABEL: alloca_argument_compare_swapped
18   ; CHECK: ret i1 false
19 }
20
21 define i1 @alloca_argument_compare_ne(i64* %arg) {
22   %alloc = alloca i64
23   %cmp = icmp ne i64* %arg, %alloc
24   ret i1 %cmp
25   ; CHECK-LABEL: alloca_argument_compare_ne
26   ; CHECK: ret i1 true
27 }
28
29 define i1 @alloca_argument_compare_derived_ptrs(i64* %arg, i64 %x) {
30   %alloc = alloca i64, i64 8
31   %p = getelementptr i64, i64* %arg, i64 %x
32   %q = getelementptr i64, i64* %alloc, i64 3
33   %cmp = icmp eq i64* %p, %q
34   ret i1 %cmp
35   ; CHECK-LABEL: alloca_argument_compare_derived_ptrs
36   ; CHECK: ret i1 false
37 }
38
39 declare void @escape(i64*)
40 define i1 @alloca_argument_compare_escaped_alloca(i64* %arg) {
41   %alloc = alloca i64
42   call void @escape(i64* %alloc)
43   %cmp = icmp eq i64* %alloc, %arg
44   ret i1 %cmp
45   ; CHECK-LABEL: alloca_argument_compare_escaped_alloca
46   ; CHECK: %cmp = icmp eq i64* %alloc, %arg
47   ; CHECK: ret i1 %cmp
48 }
49
50 declare void @check_compares(i1, i1)
51 define void @alloca_argument_compare_two_compares(i64* %p) {
52   %q = alloca i64, i64 8
53   %r = getelementptr i64, i64* %p, i64 1
54   %s = getelementptr i64, i64* %q, i64 2
55   %cmp1 = icmp eq i64* %p, %q
56   %cmp2 = icmp eq i64* %r, %s
57   call void @check_compares(i1 %cmp1, i1 %cmp2)
58   ret void
59   ; We will only fold if there is a single cmp.
60   ; CHECK-LABEL: alloca_argument_compare_two_compares
61   ; CHECK: call void @check_compares(i1 %cmp1, i1 %cmp2)
62 }
63
64 define i1 @alloca_argument_compare_escaped_through_store(i64* %arg, i64** %ptr) {
65   %alloc = alloca i64
66   %cmp = icmp eq i64* %alloc, %arg
67   %p = getelementptr i64, i64* %alloc, i64 1
68   store i64* %p, i64** %ptr
69   ret i1 %cmp
70   ; CHECK-LABEL: alloca_argument_compare_escaped_through_store
71   ; CHECK: %cmp = icmp eq i64* %alloc, %arg
72   ; CHECK: ret i1 %cmp
73 }
74
75 declare void @llvm.lifetime.start(i64, i8* nocapture)
76 declare void @llvm.lifetime.end(i64, i8* nocapture)
77 define i1 @alloca_argument_compare_benign_instrs(i8* %arg) {
78   %alloc = alloca i8
79   call void @llvm.lifetime.start(i64 1, i8* %alloc)
80   %cmp = icmp eq i8* %arg, %alloc
81   %x = load i8, i8* %arg
82   store i8 %x, i8* %alloc
83   call void @llvm.lifetime.end(i64 1, i8* %alloc)
84   ret i1 %cmp
85   ; CHECK-LABEL: alloca_argument_compare_benign_instrs
86   ; CHECK: ret i1 false
87 }
88
89 declare i64* @allocator()
90 define i1 @alloca_call_compare() {
91   %p = alloca i64
92   %q = call i64* @allocator()
93   %cmp = icmp eq i64* %p, %q
94   ret i1 %cmp
95   ; CHECK-LABEL: alloca_call_compare
96   ; CHECK: ret i1 false
97 }