[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / Util / assume-simplify.ll
blob8e76c0cdb57db10005877ee2dbeaac7ba94a5c2d
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2 ; RUN: opt -enable-new-pm=0 -domtree -assumption-cache-tracker -assume-simplify -verify --enable-knowledge-retention -S %s | FileCheck %s
3 ; RUN: opt -passes='require<domtree>,require<assumptions>,assume-simplify,verify' --enable-knowledge-retention -S %s | FileCheck %s
5 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
7 declare void @may_throw()
8 declare void @llvm.assume(i1)
10 define i32 @test1(i32* %0, i32* %1, i32 %2, i32 %3) {
11 ; CHECK-LABEL: define {{[^@]+}}@test1
12 ; CHECK-SAME: (i32* nonnull dereferenceable(4) [[TMP0:%.*]], i32* [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]])
13 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp ne i32 [[TMP2]], 4
14 ; CHECK-NEXT:    br i1 [[TMP5]], label [[TMP6:%.*]], label [[A:%.*]]
15 ; CHECK:       6:
16 ; CHECK-NEXT:    [[TMP7:%.*]] = add nsw i32 [[TMP3]], [[TMP2]]
17 ; CHECK-NEXT:    call void @may_throw()
18 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[TMP0]], i64 4), "align"(i32* [[TMP1]], i64 4), "nonnull"(i32* [[TMP1]]) ]
19 ; CHECK-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP0]], align 4
20 ; CHECK-NEXT:    [[TMP9:%.*]] = add nsw i32 [[TMP7]], [[TMP8]]
21 ; CHECK-NEXT:    store i32 0, i32* [[TMP0]], align 4
22 ; CHECK-NEXT:    [[TMP10:%.*]] = load i32, i32* [[TMP1]], align 4
23 ; CHECK-NEXT:    [[TMP11:%.*]] = add nsw i32 [[TMP9]], [[TMP10]]
24 ; CHECK-NEXT:    call void @may_throw()
25 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP1]], i64 4), "ignore"(i32* undef) ]
26 ; CHECK-NEXT:    store i32 [[TMP11]], i32* [[TMP1]], align 4
27 ; CHECK-NEXT:    br label [[B:%.*]]
28 ; CHECK:       A:
29 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[TMP0]], i64 4), "ignore"(i32* undef, i64 4), "ignore"(i32* undef) ]
30 ; CHECK-NEXT:    br label [[B]]
31 ; CHECK:       B:
32 ; CHECK-NEXT:    ret i32 0
34   %5 = icmp ne i32 %2, 4
35   call void @llvm.assume(i1 true) ["dereferenceable"(i32* %0, i64 4), "nonnull"(i32* %0) ]
36   br i1 %5, label %6, label %A
38 6:                                                ; preds = %4
39   %7 = add nsw i32 %3, %2
40   call void @may_throw()
41   %8 = load i32, i32* %0, align 4
42   %9 = add nsw i32 %7, %8
43   store i32 0, i32* %0, align 4
44   call void @llvm.assume(i1 true) [ "align"(i32* %0, i64 4), "dereferenceable"(i32* %0, i64 4) ]
45   %10 = load i32, i32* %1, align 4
46   %11 = add nsw i32 %9, %10
47   call void @llvm.assume(i1 true) [ "align"(i32* %1, i64 4), "nonnull"(i32* %1) ]
48   call void @may_throw()
49   call void @llvm.assume(i1 true) [ "dereferenceable"(i32* %1, i64 4), "nonnull"(i32* %1) ]
50   store i32 %11, i32* %1, align 4
51   br label %B
54   call void @llvm.assume(i1 true) [ "align"(i32* %0, i64 4), "dereferenceable"(i32* %0, i64 4), "nonnull"(i32* %0) ]
55   br label %B
57 B:                                               ; preds = %6, %4
58   ret i32 0
61 define i32 @test2(i32** %0, i32* %1, i32 %2, i32 %3) {
62 ; CHECK-LABEL: define {{[^@]+}}@test2
63 ; CHECK-SAME: (i32** [[TMP0:%.*]], i32* nonnull align 4 dereferenceable(4) [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]])
64 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 0
65 ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[TMP5]], align 4
66 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp ne i32 [[TMP6]], 0
67 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 0
68 ; CHECK-NEXT:    br i1 [[TMP7]], label [[TMP9:%.*]], label [[TMP19:%.*]]
69 ; CHECK:       9:
70 ; CHECK-NEXT:    call void @may_throw()
71 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[TMP8]], i64 4), "dereferenceable"(i32* [[TMP8]], i64 4), "nonnull"(i32* [[TMP8]]) ]
72 ; CHECK-NEXT:    [[TMP10:%.*]] = load i32, i32* [[TMP8]], align 4
73 ; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 2
74 ; CHECK-NEXT:    store i32 [[TMP10]], i32* [[TMP11]], align 4
75 ; CHECK-NEXT:    call void @may_throw()
76 ; CHECK-NEXT:    call void @may_throw()
77 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i32*, i32** [[TMP0]], i64 1
78 ; CHECK-NEXT:    [[TMP13:%.*]] = load i32*, i32** [[TMP12]], align 8
79 ; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds i32, i32* [[TMP13]], i64 0
80 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP1]], i64 12), "align"(i32* [[TMP13]], i64 4), "dereferenceable"(i32* [[TMP13]], i64 4), "nonnull"(i32* [[TMP13]]) ]
81 ; CHECK-NEXT:    [[TMP15:%.*]] = load i32, i32* [[TMP14]], align 4
82 ; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr inbounds i32*, i32** [[TMP0]], i64 1
83 ; CHECK-NEXT:    [[TMP17:%.*]] = load i32*, i32** [[TMP16]], align 8
84 ; CHECK-NEXT:    [[TMP18:%.*]] = getelementptr inbounds i32, i32* [[TMP17]], i64 2
85 ; CHECK-NEXT:    store i32 [[TMP15]], i32* [[TMP18]], align 4
86 ; CHECK-NEXT:    call void @may_throw()
87 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32** [[TMP0]], i64 4), "dereferenceable"(i32** [[TMP0]], i64 4), "nonnull"(i32** [[TMP0]]) ]
88 ; CHECK-NEXT:    br label [[TMP35:%.*]]
89 ; CHECK:       19:
90 ; CHECK-NEXT:    [[TMP20:%.*]] = getelementptr inbounds i32*, i32** [[TMP0]], i64 7
91 ; CHECK-NEXT:    [[TMP21:%.*]] = load i32*, i32** [[TMP20]], align 8
92 ; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i32, i32* [[TMP21]], i64 0
93 ; CHECK-NEXT:    [[TMP23:%.*]] = load i32, i32* [[TMP22]], align 4
94 ; CHECK-NEXT:    [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0
95 ; CHECK-NEXT:    br i1 [[TMP24]], label [[TMP25:%.*]], label [[TMP33:%.*]]
96 ; CHECK:       25:
97 ; CHECK-NEXT:    call void @may_throw()
98 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32** [[TMP0]], i64 4), "dereferenceable"(i32** [[TMP0]], i64 4), "nonnull"(i32** [[TMP0]]) ]
99 ; CHECK-NEXT:    [[TMP26:%.*]] = getelementptr inbounds i32*, i32** [[TMP0]], i64 2
100 ; CHECK-NEXT:    [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8
101 ; CHECK-NEXT:    [[TMP28:%.*]] = getelementptr inbounds i32, i32* [[TMP27]], i64 0
102 ; CHECK-NEXT:    [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4
103 ; CHECK-NEXT:    [[TMP30:%.*]] = getelementptr inbounds i32*, i32** [[TMP0]], i64 2
104 ; CHECK-NEXT:    [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8
105 ; CHECK-NEXT:    [[TMP32:%.*]] = getelementptr inbounds i32, i32* [[TMP31]], i64 2
106 ; CHECK-NEXT:    store i32 [[TMP29]], i32* [[TMP32]], align 4
107 ; CHECK-NEXT:    call void @may_throw()
108 ; CHECK-NEXT:    br label [[TMP33]]
109 ; CHECK:       33:
110 ; CHECK-NEXT:    br label [[TMP34:%.*]]
111 ; CHECK:       34:
112 ; CHECK-NEXT:    br label [[TMP35]]
113 ; CHECK:       35:
114 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32** [[TMP0]], i64 4), "dereferenceable"(i32** [[TMP0]], i64 4), "nonnull"(i32** [[TMP0]]) ]
115 ; CHECK-NEXT:    ret i32 0
117   %5 = getelementptr inbounds i32, i32* %1, i64 0
118   %6 = load i32, i32* %5, align 4
119   %7 = icmp ne i32 %6, 0
120   call void @llvm.assume(i1 true) [ "align"(i32* %1, i64 4), "dereferenceable"(i32* %1, i64 4) ]
121   call void @llvm.assume(i1 true) [ "align"(i32* %1, i64 4), "nonnull"(i32* %1) ]
122   %8 = getelementptr inbounds i32, i32* %1, i64 0
123   br i1 %7, label %9, label %19
125 9:                                                ; preds = %4
126   call void @may_throw()
127   call void @llvm.assume(i1 true) [ "align"(i32* %8, i64 4), "dereferenceable"(i32* %8, i64 4), "nonnull"(i32* %8) ]
128   %10 = load i32, i32* %8, align 4
129   %11 = getelementptr inbounds i32, i32* %1, i64 2
130   store i32 %10, i32* %11, align 4
131   call void @may_throw()
132   call void @may_throw()
133   call void @llvm.assume(i1 true) [ "align"(i32* %11, i64 4), "dereferenceable"(i32* %11, i64 4), "nonnull"(i32* %11) ]
134   %12 = getelementptr inbounds i32*, i32** %0, i64 1
135   %13 = load i32*, i32** %12, align 8
136   %14 = getelementptr inbounds i32, i32* %13, i64 0
137   %15 = load i32, i32* %14, align 4
138   call void @llvm.assume(i1 true) [ "align"(i32* %14, i64 4), "dereferenceable"(i32* %14, i64 4), "nonnull"(i32* %14) ]
139   %16 = getelementptr inbounds i32*, i32** %0, i64 1
140   %17 = load i32*, i32** %16, align 8
141   %18 = getelementptr inbounds i32, i32* %17, i64 2
142   store i32 %15, i32* %18, align 4
143   call void @may_throw()
144   call void @llvm.assume(i1 true) [ "align"(i32** %0, i64 4), "dereferenceable"(i32** %0, i64 4), "nonnull"(i32** %0) ]
145   br label %35
147 19:                                               ; preds = %4
148   %20 = getelementptr inbounds i32*, i32** %0, i64 7
149   %21 = load i32*, i32** %20, align 8
150   %22 = getelementptr inbounds i32, i32* %21, i64 0
151   %23 = load i32, i32* %22, align 4
152   %24 = icmp ne i32 %23, 0
153   br i1 %24, label %25, label %33
155 25:                                               ; preds = %19
156   call void @may_throw()
157   call void @llvm.assume(i1 true) [ "align"(i32** %0, i64 4), "dereferenceable"(i32** %0, i64 4), "nonnull"(i32** %0) ]
158   %26 = getelementptr inbounds i32*, i32** %0, i64 2
159   %27 = load i32*, i32** %26, align 8
160   %28 = getelementptr inbounds i32, i32* %27, i64 0
161   %29 = load i32, i32* %28, align 4
162   %30 = getelementptr inbounds i32*, i32** %0, i64 2
163   %31 = load i32*, i32** %30, align 8
164   %32 = getelementptr inbounds i32, i32* %31, i64 2
165   store i32 %29, i32* %32, align 4
166   call void @may_throw()
167   br label %33
169 33:                                               ; preds = %25, %19
170   br label %34
172 34:                                               ; preds = %33
173   br label %35
175 35:                                               ; preds = %34, %8
176   call void @llvm.assume(i1 true) [ "align"(i32** %0, i64 4), "dereferenceable"(i32** %0, i64 4), "nonnull"(i32** %0) ]
177   ret i32 0
180 define i32 @test3(i32* nonnull %p, i32 %i) {
181 ; CHECK-LABEL: define {{[^@]+}}@test3
182 ; CHECK-SAME: (i32* nonnull [[P:%.*]], i32 [[I:%.*]])
183 ; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[I]], 0
184 ; CHECK-NEXT:    br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
185 ; CHECK:       A:
186 ; CHECK-NEXT:    ret i32 0
187 ; CHECK:       B:
188 ; CHECK-NEXT:    [[RET:%.*]] = load i32, i32* [[P]]
189 ; CHECK-NEXT:    ret i32 [[RET]]
191   %cond = icmp ne i32 %i, 0
192   call void @llvm.assume(i1 true) [ "nonnull"(i32* %p) ]
193   br i1 %cond, label %A, label %B
195   ret i32 0
197   %ret = load i32, i32* %p
198   ret i32 %ret
201 define i32 @test4(i32* %p, i32 %i) {
202 ; CHECK-LABEL: define {{[^@]+}}@test4
203 ; CHECK-SAME: (i32* nonnull dereferenceable(32) [[P:%.*]], i32 [[I:%.*]])
204 ; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[I]], 0
205 ; CHECK-NEXT:    br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
206 ; CHECK:       A:
207 ; CHECK-NEXT:    ret i32 0
208 ; CHECK:       B:
209 ; CHECK-NEXT:    [[RET:%.*]] = load i32, i32* [[P]]
210 ; CHECK-NEXT:    ret i32 [[RET]]
212   %cond = icmp ne i32 %i, 0
213   call void @llvm.assume(i1 true) [ "nonnull"(i32* %p), "dereferenceable"(i32* %p, i32 32) ]
214   br i1 %cond, label %A, label %B
216   ret i32 0
218   %ret = load i32, i32* %p
219   ret i32 %ret
222 define i32 @test4A(i32* %p, i32 %i) {
223 ; CHECK-LABEL: define {{[^@]+}}@test4A
224 ; CHECK-SAME: (i32* [[P:%.*]], i32 [[I:%.*]])
225 ; CHECK-NEXT:    call void @may_throw()
226 ; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[I]], 0
227 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P]]), "dereferenceable"(i32* [[P]], i32 32) ]
228 ; CHECK-NEXT:    br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
229 ; CHECK:       A:
230 ; CHECK-NEXT:    ret i32 0
231 ; CHECK:       B:
232 ; CHECK-NEXT:    [[RET:%.*]] = load i32, i32* [[P]]
233 ; CHECK-NEXT:    ret i32 [[RET]]
235   call void @may_throw()
236   %cond = icmp ne i32 %i, 0
237   call void @llvm.assume(i1 true) [ "nonnull"(i32* %p), "dereferenceable"(i32* %p, i32 32) ]
238   br i1 %cond, label %A, label %B
240   ret i32 0
242   %ret = load i32, i32* %p
243   ret i32 %ret
246 define i32 @test5(i32* dereferenceable(64) %p, i32 %i) {
247 ; CHECK-LABEL: define {{[^@]+}}@test5
248 ; CHECK-SAME: (i32* nonnull dereferenceable(64) [[P:%.*]], i32 [[I:%.*]])
249 ; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[I]], 0
250 ; CHECK-NEXT:    br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
251 ; CHECK:       A:
252 ; CHECK-NEXT:    ret i32 0
253 ; CHECK:       B:
254 ; CHECK-NEXT:    [[RET:%.*]] = load i32, i32* [[P]]
255 ; CHECK-NEXT:    ret i32 [[RET]]
257   %cond = icmp ne i32 %i, 0
258   call void @llvm.assume(i1 true) [ "nonnull"(i32* %p), "dereferenceable"(i32* %p, i32 32) ]
259   br i1 %cond, label %A, label %B
261   ret i32 0
263   %ret = load i32, i32* %p
264   ret i32 %ret
268 define i32 @test5A(i32* dereferenceable(8) %p, i32 %i) {
269 ; CHECK-LABEL: define {{[^@]+}}@test5A
270 ; CHECK-SAME: (i32* dereferenceable(32) [[P:%.*]], i32 [[I:%.*]])
271 ; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[I]], 0
272 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "cold"(), "ignore"(i32* undef, i32 32) ]
273 ; CHECK-NEXT:    br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
274 ; CHECK:       A:
275 ; CHECK-NEXT:    ret i32 0
276 ; CHECK:       B:
277 ; CHECK-NEXT:    [[RET:%.*]] = load i32, i32* [[P]]
278 ; CHECK-NEXT:    ret i32 [[RET]]
280   %cond = icmp ne i32 %i, 0
281   call void @llvm.assume(i1 true) [ "cold"(), "dereferenceable"(i32* %p, i32 32) ]
282   br i1 %cond, label %A, label %B
284   ret i32 0
286   %ret = load i32, i32* %p
287   ret i32 %ret
290 define i32 @test6() {
291 ; CHECK-LABEL: define {{[^@]+}}@test6()
292 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "cold"() ]
293 ; CHECK-NEXT:    call void @may_throw()
294 ; CHECK-NEXT:    ret i32 0
296   call void @llvm.assume(i1 true) [ "cold"() ]
297   call void @llvm.assume(i1 true) [ "cold"() ]
298   call void @may_throw()
299   call void @llvm.assume(i1 true) [ "cold"() ]
300   ret i32 0
303 define i32 @test7(i32* %p) {
304 ; CHECK-LABEL: define {{[^@]+}}@test7
305 ; CHECK-SAME: (i32* align 4 dereferenceable(4) [[P:%.*]])
306 ; CHECK-NEXT:    [[P1:%.*]] = bitcast i32* [[P]] to i8*
307 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "cold"(), "nonnull"(i32* [[P]]) ]
308 ; CHECK-NEXT:    ret i32 0
310   %p1 = bitcast i32* %p to i8*
311   call void @llvm.assume(i1 true) [ "cold"() ]
312   call void @llvm.assume(i1 true) [ "align"(i32* %p, i32 4) ]
313   call void @llvm.assume(i1 true) [ "dereferenceable"(i32* %p, i32 4) ]
314   call void @llvm.assume(i1 true) [ "align"(i8* %p1, i32 4), "nonnull"(i8* %p1) ]
315   ret i32 0