1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 @Gstatic_int1 = internal global i32 zeroinitializer, align 4
6 @Gstatic_int2 = internal global i32 zeroinitializer, align 4
8 declare void @llvm.assume(i1)
9 declare void @useI1p(ptr)
10 declare void @unknown()
13 ; CHECK: @Gstatic_int1 = internal global i32 0, align 4
14 ; CHECK: @Gstatic_int2 = internal global i32 0, align 4
16 define i1 @readI1p(ptr %p) {
17 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
18 ; CHECK-LABEL: define {{[^@]+}}@readI1p
19 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR1:[0-9]+]] {
20 ; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[P]], align 1
21 ; CHECK-NEXT: ret i1 [[L]]
27 define i1 @keep_assume_1c_nr() norecurse {
28 ; CHECK: Function Attrs: norecurse
29 ; CHECK-LABEL: define {{[^@]+}}@keep_assume_1c_nr
30 ; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
31 ; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
32 ; CHECK-NEXT: store i1 true, ptr [[STACK]], align 1
33 ; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
34 ; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
35 ; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])
36 ; CHECK-NEXT: ret i1 [[L]]
39 store i1 true, ptr %stack
40 call void @useI1p(ptr %stack)
41 %l = load i1, ptr %stack
42 call void @llvm.assume(i1 %l)
46 define i1 @drop_assume_1c_nr() norecurse {
47 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
48 ; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1c_nr
49 ; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {
50 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7:[0-9]+]]
51 ; TUNIT-NEXT: ret i1 true
53 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
54 ; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c_nr
55 ; CGSCC-SAME: () #[[ATTR3:[0-9]+]] {
56 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8:[0-9]+]]
57 ; CGSCC-NEXT: ret i1 true
60 store i1 true, ptr %stack
61 %l = load i1, ptr %stack
62 call void @llvm.assume(i1 %l)
66 define i1 @keep_assume_2c_nr() norecurse {
67 ; CHECK: Function Attrs: norecurse
68 ; CHECK-LABEL: define {{[^@]+}}@keep_assume_2c_nr
69 ; CHECK-SAME: () #[[ATTR2]] {
70 ; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
71 ; CHECK-NEXT: store i1 true, ptr [[STACK]], align 1
72 ; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
73 ; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
74 ; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])
75 ; CHECK-NEXT: call void @unknown()
76 ; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
77 ; CHECK-NEXT: ret i1 [[L2]]
80 store i1 true, ptr %stack
81 call void @useI1p(ptr %stack)
82 %l1 = load i1, ptr %stack
83 call void @llvm.assume(i1 %l1)
85 %l2 = load i1, ptr %stack
89 define i1 @keep_assume_3c_nr() norecurse {
91 ; TUNIT: Function Attrs: norecurse
92 ; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3c_nr
93 ; TUNIT-SAME: () #[[ATTR2]] {
94 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
95 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
96 ; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
97 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
98 ; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
99 ; TUNIT-NEXT: ret i1 [[L]]
101 ; CGSCC: Function Attrs: norecurse
102 ; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3c_nr
103 ; CGSCC-SAME: () #[[ATTR2]] {
104 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
105 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
106 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
107 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
108 ; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
109 ; CGSCC-NEXT: ret i1 [[L]]
112 store i1 true, ptr %stack
113 %l = load i1, ptr %stack
114 call void @llvm.assume(i1 %l)
115 call void @useI1p(ptr %stack)
118 define i1 @keep_assume_4c_nr() norecurse {
120 ; TUNIT: Function Attrs: norecurse
121 ; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4c_nr
122 ; TUNIT-SAME: () #[[ATTR2]] {
123 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
124 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
125 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]
126 ; TUNIT-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
127 ; TUNIT-NEXT: ret i1 true
129 ; CGSCC: Function Attrs: norecurse
130 ; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4c_nr
131 ; CGSCC-SAME: () #[[ATTR2]] {
132 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
133 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
134 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]]
135 ; CGSCC-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
136 ; CGSCC-NEXT: ret i1 true
139 store i1 true, ptr %stack
140 %l4 = load i1, ptr %stack
141 call void @llvm.assume(i1 %l4)
142 call void @useI1p(ptr nocapture %stack)
146 define i1 @keep_assume_1_nr(i1 %arg) norecurse {
147 ; CHECK: Function Attrs: norecurse
148 ; CHECK-LABEL: define {{[^@]+}}@keep_assume_1_nr
149 ; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
150 ; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
151 ; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
152 ; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
153 ; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
154 ; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])
155 ; CHECK-NEXT: ret i1 [[L]]
158 store i1 %arg, ptr %stack
159 call void @useI1p(ptr %stack)
160 %l = load i1, ptr %stack
161 call void @llvm.assume(i1 %l)
165 define i1 @drop_assume_1_nr(i1 %arg) norecurse {
166 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
167 ; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1_nr
168 ; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
169 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
170 ; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
171 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
172 ; TUNIT-NEXT: ret i1 [[ARG]]
174 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
175 ; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1_nr
176 ; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
177 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
178 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
179 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
180 ; CGSCC-NEXT: ret i1 [[ARG]]
183 store i1 %arg, ptr %stack
184 %l = load i1, ptr %stack
185 call void @llvm.assume(i1 %l)
189 define i1 @keep_assume_2_nr(i1 %arg) norecurse {
190 ; CHECK: Function Attrs: norecurse
191 ; CHECK-LABEL: define {{[^@]+}}@keep_assume_2_nr
192 ; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
193 ; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
194 ; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
195 ; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
196 ; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
197 ; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])
198 ; CHECK-NEXT: call void @unknown()
199 ; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
200 ; CHECK-NEXT: ret i1 [[L2]]
203 store i1 %arg, ptr %stack
204 call void @useI1p(ptr %stack)
205 %l1 = load i1, ptr %stack
206 call void @llvm.assume(i1 %l1)
208 %l2 = load i1, ptr %stack
212 define i1 @keep_assume_3_nr(i1 %arg) norecurse {
214 ; TUNIT: Function Attrs: norecurse
215 ; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3_nr
216 ; TUNIT-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
217 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
218 ; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
219 ; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
220 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
221 ; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
222 ; TUNIT-NEXT: ret i1 [[L]]
224 ; CGSCC: Function Attrs: norecurse
225 ; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3_nr
226 ; CGSCC-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
227 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
228 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
229 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
230 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
231 ; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
232 ; CGSCC-NEXT: ret i1 [[L]]
235 store i1 %arg, ptr %stack
236 %l = load i1, ptr %stack
237 call void @llvm.assume(i1 %l)
238 call void @useI1p(ptr %stack)
242 define i1 @keep_assume_4_nr(i1 %arg) norecurse {
244 ; TUNIT: Function Attrs: norecurse
245 ; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4_nr
246 ; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] {
247 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
248 ; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
249 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
250 ; TUNIT-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
251 ; TUNIT-NEXT: ret i1 [[ARG]]
253 ; CGSCC: Function Attrs: norecurse
254 ; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4_nr
255 ; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] {
256 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
257 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
258 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
259 ; CGSCC-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
260 ; CGSCC-NEXT: ret i1 [[ARG]]
263 store i1 %arg, ptr %stack
264 %l = load i1, ptr %stack
265 call void @llvm.assume(i1 %l)
266 call void @useI1p(ptr nocapture %stack)
270 define i1 @assume_1_nr(i1 %arg, i1 %cond) norecurse {
271 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
272 ; TUNIT-LABEL: define {{[^@]+}}@assume_1_nr
273 ; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
274 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
275 ; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
276 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
277 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
279 ; TUNIT-NEXT: br label [[M:%.*]]
281 ; TUNIT-NEXT: br label [[M]]
283 ; TUNIT-NEXT: ret i1 [[ARG]]
285 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
286 ; CGSCC-LABEL: define {{[^@]+}}@assume_1_nr
287 ; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
288 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
289 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
290 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
291 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
293 ; CGSCC-NEXT: br label [[M:%.*]]
295 ; CGSCC-NEXT: br label [[M]]
297 ; CGSCC-NEXT: ret i1 [[ARG]]
300 store i1 %arg, ptr %stack
301 %l = load i1, ptr %stack
302 call void @llvm.assume(i1 %l)
303 br i1 %cond, label %t, label %f
305 store i1 true, ptr %stack
308 store i1 false, ptr %stack
314 define void @assume_1b_nr(i1 %arg, i1 %cond) norecurse {
315 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
316 ; CHECK-LABEL: define {{[^@]+}}@assume_1b_nr
317 ; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4:[0-9]+]] {
318 ; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
320 ; CHECK-NEXT: br label [[M:%.*]]
322 ; CHECK-NEXT: br label [[M]]
324 ; CHECK-NEXT: ret void
327 store i1 %arg, ptr %stack
328 %l = load i1, ptr %stack
329 call void @llvm.assume(i1 %l)
330 br i1 %cond, label %t, label %f
332 store i1 true, ptr %stack
335 store i1 false, ptr %stack
341 define i1 @assume_2_nr(i1 %arg, i1 %cond) norecurse {
342 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
343 ; TUNIT-LABEL: define {{[^@]+}}@assume_2_nr
344 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
345 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
346 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
348 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
349 ; TUNIT-NEXT: br label [[M:%.*]]
351 ; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
352 ; TUNIT-NEXT: br label [[M]]
354 ; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
355 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
356 ; TUNIT-NEXT: ret i1 [[L]]
358 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
359 ; CGSCC-LABEL: define {{[^@]+}}@assume_2_nr
360 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
361 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
362 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
364 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
365 ; CGSCC-NEXT: br label [[M:%.*]]
367 ; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
368 ; CGSCC-NEXT: br label [[M]]
370 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
371 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
372 ; CGSCC-NEXT: ret i1 [[L]]
375 store i1 %arg, ptr %stack
376 br i1 %cond, label %t, label %f
378 store i1 true, ptr %stack
381 store i1 false, ptr %stack
384 %l = load i1, ptr %stack
385 call void @llvm.assume(i1 %l)
389 define void @assume_2b_nr(i1 %arg, i1 %cond) norecurse {
390 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
391 ; CHECK-LABEL: define {{[^@]+}}@assume_2b_nr
392 ; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
393 ; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
394 ; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
396 ; CHECK-NEXT: br label [[M:%.*]]
398 ; CHECK-NEXT: br label [[M]]
400 ; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
401 ; CHECK-NEXT: ret void
404 store i1 %arg, ptr %stack
405 br i1 %cond, label %t, label %f
407 store i1 true, ptr %stack
410 store i1 false, ptr %stack
413 %l = load i1, ptr %stack
414 call void @llvm.assume(i1 %l)
418 define i1 @assume_3_nr(i1 %arg, i1 %cond) norecurse {
419 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
420 ; TUNIT-LABEL: define {{[^@]+}}@assume_3_nr
421 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
422 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
423 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
425 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
426 ; TUNIT-NEXT: br label [[M:%.*]]
428 ; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
429 ; TUNIT-NEXT: br label [[M]]
431 ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8:[0-9]+]]
432 ; TUNIT-NEXT: ret i1 [[R]]
434 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
435 ; CGSCC-LABEL: define {{[^@]+}}@assume_3_nr
436 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
437 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
438 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
439 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
440 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
441 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
443 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
444 ; CGSCC-NEXT: br label [[M:%.*]]
446 ; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
447 ; CGSCC-NEXT: br label [[M]]
449 ; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR9:[0-9]+]]
450 ; CGSCC-NEXT: ret i1 [[R]]
453 store i1 %arg, ptr %stack
454 %l = load i1, ptr %stack
455 call void @llvm.assume(i1 %l)
456 br i1 %cond, label %t, label %f
458 store i1 true, ptr %stack
461 store i1 false, ptr %stack
464 %r = call i1 @readI1p(ptr %stack)
468 define i1 @assume_4_nr(i1 %arg, i1 %cond) norecurse {
469 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
470 ; TUNIT-LABEL: define {{[^@]+}}@assume_4_nr
471 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
472 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
473 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
475 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
476 ; TUNIT-NEXT: br label [[M:%.*]]
478 ; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
479 ; TUNIT-NEXT: br label [[M]]
481 ; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
482 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
483 ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
484 ; TUNIT-NEXT: ret i1 [[R]]
486 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
487 ; CGSCC-LABEL: define {{[^@]+}}@assume_4_nr
488 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
489 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
490 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
491 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
493 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
494 ; CGSCC-NEXT: br label [[M:%.*]]
496 ; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
497 ; CGSCC-NEXT: br label [[M]]
499 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
500 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
501 ; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR9]]
502 ; CGSCC-NEXT: ret i1 [[R]]
505 store i1 %arg, ptr %stack
506 br i1 %cond, label %t, label %f
508 store i1 true, ptr %stack
511 store i1 false, ptr %stack
514 %l = load i1, ptr %stack
515 call void @llvm.assume(i1 %l)
516 %r = call i1 @readI1p(ptr %stack)
520 define i1 @assume_5_nr(i1 %arg, i1 %cond) norecurse {
521 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
522 ; TUNIT-LABEL: define {{[^@]+}}@assume_5_nr
523 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
524 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
525 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
527 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
528 ; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
529 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]
530 ; TUNIT-NEXT: br label [[M:%.*]]
532 ; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
533 ; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
534 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]
535 ; TUNIT-NEXT: br label [[M]]
537 ; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
538 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9:[0-9]+]]
539 ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
540 ; TUNIT-NEXT: ret i1 [[R]]
542 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
543 ; CGSCC-LABEL: define {{[^@]+}}@assume_5_nr
544 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
545 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
546 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
547 ; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
548 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]
549 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
551 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
552 ; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
553 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10:[0-9]+]]
554 ; CGSCC-NEXT: br label [[M:%.*]]
556 ; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
557 ; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
558 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
559 ; CGSCC-NEXT: br label [[M]]
561 ; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
562 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
563 ; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR10]]
564 ; CGSCC-NEXT: ret i1 [[R]]
567 store i1 %arg, ptr %stack
568 %l1 = load i1, ptr %stack
569 call void @llvm.assume(i1 %l1)
570 br i1 %cond, label %t, label %f
572 store i1 true, ptr %stack
573 %l2 = load i1, ptr %stack
574 call void @llvm.assume(i1 %l2)
577 store i1 false, ptr %stack
578 %l3 = load i1, ptr %stack
579 call void @llvm.assume(i1 %l3)
582 %l4 = load i1, ptr %stack
583 call void @llvm.assume(i1 %l4)
584 %r = call i1 @readI1p(ptr %stack)
588 define i1 @assume_5c_nr(i1 %cond) norecurse {
589 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
590 ; TUNIT-LABEL: define {{[^@]+}}@assume_5c_nr
591 ; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {
592 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
593 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]
594 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
596 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
597 ; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
598 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]
599 ; TUNIT-NEXT: br label [[M:%.*]]
601 ; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
602 ; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
603 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]
604 ; TUNIT-NEXT: br label [[M]]
606 ; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
607 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
608 ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
609 ; TUNIT-NEXT: ret i1 [[R]]
611 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
612 ; CGSCC-LABEL: define {{[^@]+}}@assume_5c_nr
613 ; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {
614 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
615 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
616 ; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
617 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]
618 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
620 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
621 ; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
622 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
623 ; CGSCC-NEXT: br label [[M:%.*]]
625 ; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
626 ; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
627 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
628 ; CGSCC-NEXT: br label [[M]]
630 ; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
631 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
632 ; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR10]]
633 ; CGSCC-NEXT: ret i1 [[R]]
636 store i1 true, ptr %stack
637 %l1 = load i1, ptr %stack
638 call void @llvm.assume(i1 %l1)
639 br i1 %cond, label %t, label %f
641 store i1 true, ptr %stack
642 %l2 = load i1, ptr %stack
643 call void @llvm.assume(i1 %l2)
646 store i1 false, ptr %stack
647 %l3 = load i1, ptr %stack
648 call void @llvm.assume(i1 %l3)
651 %l4 = load i1, ptr %stack
652 call void @llvm.assume(i1 %l4)
653 %r = call i1 @readI1p(ptr %stack)
658 define i1 @keep_assume_1c() {
659 ; CHECK-LABEL: define {{[^@]+}}@keep_assume_1c() {
660 ; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
661 ; CHECK-NEXT: store i1 true, ptr [[STACK]], align 1
662 ; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
663 ; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
664 ; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])
665 ; CHECK-NEXT: ret i1 [[L]]
668 store i1 true, ptr %stack
669 call void @useI1p(ptr %stack)
670 %l = load i1, ptr %stack
671 call void @llvm.assume(i1 %l)
675 define i1 @drop_assume_1c() {
676 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
677 ; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1c
678 ; TUNIT-SAME: () #[[ATTR3]] {
679 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]
680 ; TUNIT-NEXT: ret i1 true
682 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
683 ; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c
684 ; CGSCC-SAME: () #[[ATTR3]] {
685 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]]
686 ; CGSCC-NEXT: ret i1 true
689 store i1 true, ptr %stack
690 %l = load i1, ptr %stack
691 call void @llvm.assume(i1 %l)
695 define i1 @keep_assume_2c() {
696 ; CHECK-LABEL: define {{[^@]+}}@keep_assume_2c() {
697 ; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
698 ; CHECK-NEXT: store i1 true, ptr [[STACK]], align 1
699 ; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
700 ; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
701 ; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])
702 ; CHECK-NEXT: call void @unknown()
703 ; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
704 ; CHECK-NEXT: ret i1 [[L2]]
707 store i1 true, ptr %stack
708 call void @useI1p(ptr %stack)
709 %l1 = load i1, ptr %stack
710 call void @llvm.assume(i1 %l1)
712 %l2 = load i1, ptr %stack
716 define i1 @keep_assume_3c() {
718 ; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3c() {
719 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
720 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
721 ; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
722 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
723 ; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
724 ; TUNIT-NEXT: ret i1 [[L]]
726 ; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3c() {
727 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
728 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
729 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
730 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
731 ; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
732 ; CGSCC-NEXT: ret i1 [[L]]
735 store i1 true, ptr %stack
736 %l = load i1, ptr %stack
737 call void @llvm.assume(i1 %l)
738 call void @useI1p(ptr %stack)
741 define i1 @keep_assume_4c() {
743 ; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4c() {
744 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
745 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
746 ; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
747 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR7]]
748 ; TUNIT-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
749 ; TUNIT-NEXT: ret i1 [[L4]]
751 ; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4c() {
752 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
753 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
754 ; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
755 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR8]]
756 ; CGSCC-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
757 ; CGSCC-NEXT: ret i1 [[L4]]
760 store i1 true, ptr %stack
761 %l4 = load i1, ptr %stack
762 call void @llvm.assume(i1 %l4)
763 call void @useI1p(ptr nocapture %stack)
767 define i1 @keep_assume_1(i1 %arg) {
768 ; CHECK-LABEL: define {{[^@]+}}@keep_assume_1
769 ; CHECK-SAME: (i1 [[ARG:%.*]]) {
770 ; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
771 ; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
772 ; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
773 ; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
774 ; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])
775 ; CHECK-NEXT: ret i1 [[L]]
778 store i1 %arg, ptr %stack
779 call void @useI1p(ptr %stack)
780 %l = load i1, ptr %stack
781 call void @llvm.assume(i1 %l)
785 define i1 @drop_assume_1(i1 %arg) {
786 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
787 ; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1
788 ; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4]] {
789 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
790 ; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
791 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
792 ; TUNIT-NEXT: ret i1 [[ARG]]
794 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
795 ; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1
796 ; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4]] {
797 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
798 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
799 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
800 ; CGSCC-NEXT: ret i1 [[ARG]]
803 store i1 %arg, ptr %stack
804 %l = load i1, ptr %stack
805 call void @llvm.assume(i1 %l)
809 define i1 @keep_assume_2(i1 %arg) {
810 ; CHECK-LABEL: define {{[^@]+}}@keep_assume_2
811 ; CHECK-SAME: (i1 [[ARG:%.*]]) {
812 ; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
813 ; CHECK-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
814 ; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
815 ; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
816 ; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])
817 ; CHECK-NEXT: call void @unknown()
818 ; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
819 ; CHECK-NEXT: ret i1 [[L2]]
822 store i1 %arg, ptr %stack
823 call void @useI1p(ptr %stack)
824 %l1 = load i1, ptr %stack
825 call void @llvm.assume(i1 %l1)
827 %l2 = load i1, ptr %stack
831 define i1 @keep_assume_3(i1 %arg) {
833 ; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3
834 ; TUNIT-SAME: (i1 [[ARG:%.*]]) {
835 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
836 ; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
837 ; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
838 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
839 ; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
840 ; TUNIT-NEXT: ret i1 [[L]]
842 ; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3
843 ; CGSCC-SAME: (i1 [[ARG:%.*]]) {
844 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
845 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
846 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
847 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
848 ; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
849 ; CGSCC-NEXT: ret i1 [[L]]
852 store i1 %arg, ptr %stack
853 %l = load i1, ptr %stack
854 call void @llvm.assume(i1 %l)
855 call void @useI1p(ptr %stack)
859 define i1 @keep_assume_4(i1 %arg) {
861 ; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4
862 ; TUNIT-SAME: (i1 [[ARG:%.*]]) {
863 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
864 ; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
865 ; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
866 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
867 ; TUNIT-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
868 ; TUNIT-NEXT: ret i1 [[L]]
870 ; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4
871 ; CGSCC-SAME: (i1 [[ARG:%.*]]) {
872 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
873 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
874 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
875 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
876 ; CGSCC-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
877 ; CGSCC-NEXT: ret i1 [[L]]
880 store i1 %arg, ptr %stack
881 %l = load i1, ptr %stack
882 call void @llvm.assume(i1 %l)
883 call void @useI1p(ptr nocapture %stack)
887 define i1 @assume_1(i1 %arg, i1 %cond) {
888 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
889 ; TUNIT-LABEL: define {{[^@]+}}@assume_1
890 ; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
891 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
892 ; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
893 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
894 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
896 ; TUNIT-NEXT: br label [[M:%.*]]
898 ; TUNIT-NEXT: br label [[M]]
900 ; TUNIT-NEXT: ret i1 [[ARG]]
902 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
903 ; CGSCC-LABEL: define {{[^@]+}}@assume_1
904 ; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
905 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
906 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
907 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
908 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
910 ; CGSCC-NEXT: br label [[M:%.*]]
912 ; CGSCC-NEXT: br label [[M]]
914 ; CGSCC-NEXT: ret i1 [[ARG]]
917 store i1 %arg, ptr %stack
918 %l = load i1, ptr %stack
919 call void @llvm.assume(i1 %l)
920 br i1 %cond, label %t, label %f
922 store i1 true, ptr %stack
925 store i1 false, ptr %stack
931 define void @assume_1b(i1 %arg, i1 %cond) {
932 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
933 ; CHECK-LABEL: define {{[^@]+}}@assume_1b
934 ; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
935 ; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
937 ; CHECK-NEXT: br label [[M:%.*]]
939 ; CHECK-NEXT: br label [[M]]
941 ; CHECK-NEXT: ret void
944 store i1 %arg, ptr %stack
945 %l = load i1, ptr %stack
946 call void @llvm.assume(i1 %l)
947 br i1 %cond, label %t, label %f
949 store i1 true, ptr %stack
952 store i1 false, ptr %stack
958 define i1 @assume_2(i1 %arg, i1 %cond) {
959 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
960 ; TUNIT-LABEL: define {{[^@]+}}@assume_2
961 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
962 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
963 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
965 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
966 ; TUNIT-NEXT: br label [[M:%.*]]
968 ; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
969 ; TUNIT-NEXT: br label [[M]]
971 ; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
972 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
973 ; TUNIT-NEXT: ret i1 [[L]]
975 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
976 ; CGSCC-LABEL: define {{[^@]+}}@assume_2
977 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
978 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
979 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
981 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
982 ; CGSCC-NEXT: br label [[M:%.*]]
984 ; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
985 ; CGSCC-NEXT: br label [[M]]
987 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
988 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
989 ; CGSCC-NEXT: ret i1 [[L]]
992 store i1 %arg, ptr %stack
993 br i1 %cond, label %t, label %f
995 store i1 true, ptr %stack
998 store i1 false, ptr %stack
1001 %l = load i1, ptr %stack
1002 call void @llvm.assume(i1 %l)
1006 define void @assume_2b(i1 %arg, i1 %cond) {
1007 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
1008 ; CHECK-LABEL: define {{[^@]+}}@assume_2b
1009 ; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
1010 ; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
1011 ; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
1013 ; CHECK-NEXT: br label [[M:%.*]]
1015 ; CHECK-NEXT: br label [[M]]
1017 ; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
1018 ; CHECK-NEXT: ret void
1021 store i1 %arg, ptr %stack
1022 br i1 %cond, label %t, label %f
1024 store i1 true, ptr %stack
1027 store i1 false, ptr %stack
1030 %l = load i1, ptr %stack
1031 call void @llvm.assume(i1 %l)
1035 define i1 @assume_3(i1 %arg, i1 %cond) {
1036 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
1037 ; TUNIT-LABEL: define {{[^@]+}}@assume_3
1038 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
1039 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
1040 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
1042 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
1043 ; TUNIT-NEXT: br label [[M:%.*]]
1045 ; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
1046 ; TUNIT-NEXT: br label [[M]]
1048 ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
1049 ; TUNIT-NEXT: ret i1 [[R]]
1051 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
1052 ; CGSCC-LABEL: define {{[^@]+}}@assume_3
1053 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5:[0-9]+]] {
1054 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
1055 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
1056 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
1057 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
1058 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
1060 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
1061 ; CGSCC-NEXT: br label [[M:%.*]]
1063 ; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
1064 ; CGSCC-NEXT: br label [[M]]
1066 ; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR9]]
1067 ; CGSCC-NEXT: ret i1 [[R]]
1070 store i1 %arg, ptr %stack
1071 %l = load i1, ptr %stack
1072 call void @llvm.assume(i1 %l)
1073 br i1 %cond, label %t, label %f
1075 store i1 true, ptr %stack
1078 store i1 false, ptr %stack
1081 %r = call i1 @readI1p(ptr %stack)
1085 define i1 @assume_4(i1 %arg, i1 %cond) {
1086 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
1087 ; TUNIT-LABEL: define {{[^@]+}}@assume_4
1088 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
1089 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
1090 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
1092 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
1093 ; TUNIT-NEXT: br label [[M:%.*]]
1095 ; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
1096 ; TUNIT-NEXT: br label [[M]]
1098 ; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
1099 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
1100 ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
1101 ; TUNIT-NEXT: ret i1 [[R]]
1103 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
1104 ; CGSCC-LABEL: define {{[^@]+}}@assume_4
1105 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5]] {
1106 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
1107 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
1108 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
1110 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
1111 ; CGSCC-NEXT: br label [[M:%.*]]
1113 ; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
1114 ; CGSCC-NEXT: br label [[M]]
1116 ; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
1117 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
1118 ; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR9]]
1119 ; CGSCC-NEXT: ret i1 [[R]]
1122 store i1 %arg, ptr %stack
1123 br i1 %cond, label %t, label %f
1125 store i1 true, ptr %stack
1128 store i1 false, ptr %stack
1131 %l = load i1, ptr %stack
1132 call void @llvm.assume(i1 %l)
1133 %r = call i1 @readI1p(ptr %stack)
1137 define i1 @assume_5(i1 %arg, i1 %cond) {
1138 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
1139 ; TUNIT-LABEL: define {{[^@]+}}@assume_5
1140 ; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
1141 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
1142 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
1144 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
1145 ; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
1146 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]
1147 ; TUNIT-NEXT: br label [[M:%.*]]
1149 ; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
1150 ; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
1151 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]
1152 ; TUNIT-NEXT: br label [[M]]
1154 ; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
1155 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
1156 ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
1157 ; TUNIT-NEXT: ret i1 [[R]]
1159 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
1160 ; CGSCC-LABEL: define {{[^@]+}}@assume_5
1161 ; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5]] {
1162 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
1163 ; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
1164 ; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
1165 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]
1166 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
1168 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
1169 ; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
1170 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
1171 ; CGSCC-NEXT: br label [[M:%.*]]
1173 ; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
1174 ; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
1175 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
1176 ; CGSCC-NEXT: br label [[M]]
1178 ; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
1179 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
1180 ; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR10]]
1181 ; CGSCC-NEXT: ret i1 [[R]]
1184 store i1 %arg, ptr %stack
1185 %l1 = load i1, ptr %stack
1186 call void @llvm.assume(i1 %l1)
1187 br i1 %cond, label %t, label %f
1189 store i1 true, ptr %stack
1190 %l2 = load i1, ptr %stack
1191 call void @llvm.assume(i1 %l2)
1194 store i1 false, ptr %stack
1195 %l3 = load i1, ptr %stack
1196 call void @llvm.assume(i1 %l3)
1199 %l4 = load i1, ptr %stack
1200 call void @llvm.assume(i1 %l4)
1201 %r = call i1 @readI1p(ptr %stack)
1205 define i1 @assume_5c(i1 %cond) {
1206 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
1207 ; TUNIT-LABEL: define {{[^@]+}}@assume_5c
1208 ; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {
1209 ; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
1210 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]
1211 ; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
1213 ; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
1214 ; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
1215 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]
1216 ; TUNIT-NEXT: br label [[M:%.*]]
1218 ; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
1219 ; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
1220 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]
1221 ; TUNIT-NEXT: br label [[M]]
1223 ; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
1224 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
1225 ; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
1226 ; TUNIT-NEXT: ret i1 [[R]]
1228 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
1229 ; CGSCC-LABEL: define {{[^@]+}}@assume_5c
1230 ; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR5]] {
1231 ; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
1232 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
1233 ; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
1234 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]
1235 ; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
1237 ; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
1238 ; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
1239 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
1240 ; CGSCC-NEXT: br label [[M:%.*]]
1242 ; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
1243 ; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
1244 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
1245 ; CGSCC-NEXT: br label [[M]]
1247 ; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
1248 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
1249 ; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR10]]
1250 ; CGSCC-NEXT: ret i1 [[R]]
1253 store i1 true, ptr %stack
1254 %l1 = load i1, ptr %stack
1255 call void @llvm.assume(i1 %l1)
1256 br i1 %cond, label %t, label %f
1258 store i1 true, ptr %stack
1259 %l2 = load i1, ptr %stack
1260 call void @llvm.assume(i1 %l2)
1263 store i1 false, ptr %stack
1264 %l3 = load i1, ptr %stack
1265 call void @llvm.assume(i1 %l3)
1268 %l4 = load i1, ptr %stack
1269 call void @llvm.assume(i1 %l4)
1270 %r = call i1 @readI1p(ptr %stack)
1274 define i32 @assume_read_global_good() {
1277 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
1278 ; TUNIT-LABEL: define {{[^@]+}}@assume_read_global_good
1279 ; TUNIT-SAME: () #[[ATTR5:[0-9]+]] {
1280 ; TUNIT-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int1, align 4
1281 ; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42
1282 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR7]]
1283 ; TUNIT-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int1, align 4
1284 ; TUNIT-NEXT: store i32 17, ptr @Gstatic_int1, align 4
1285 ; TUNIT-NEXT: [[LGS3:%.*]] = load i32, ptr @Gstatic_int1, align 4
1286 ; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[LGS2]], [[LGS3]]
1287 ; TUNIT-NEXT: ret i32 [[ADD]]
1289 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
1290 ; CGSCC-LABEL: define {{[^@]+}}@assume_read_global_good
1291 ; CGSCC-SAME: () #[[ATTR6:[0-9]+]] {
1292 ; CGSCC-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int1, align 4
1293 ; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42
1294 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR8]]
1295 ; CGSCC-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int1, align 4
1296 ; CGSCC-NEXT: store i32 17, ptr @Gstatic_int1, align 4
1297 ; CGSCC-NEXT: [[LGS3:%.*]] = load i32, ptr @Gstatic_int1, align 4
1298 ; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[LGS2]], [[LGS3]]
1299 ; CGSCC-NEXT: ret i32 [[ADD]]
1301 %lgs1 = load i32, ptr @Gstatic_int1
1302 %c = icmp eq i32 %lgs1, 42
1303 call void @llvm.assume(i1 %c)
1304 %lgs2 = load i32, ptr @Gstatic_int1
1305 store i32 13, ptr @Gstatic_int1, align 4
1306 store i32 17, ptr @Gstatic_int1, align 4
1307 %lgs3 = load i32, ptr @Gstatic_int1
1308 %add = add i32 %lgs2, %lgs3
1312 ; TODO: Technically we could still utilize the assumption if we employ AA.
1313 define i32 @assume_read_global_bad(ptr %p) {
1315 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
1316 ; TUNIT-LABEL: define {{[^@]+}}@assume_read_global_bad
1317 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR5]] {
1318 ; TUNIT-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int2, align 4
1319 ; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42
1320 ; TUNIT-NEXT: store i32 13, ptr [[P]], align 4
1321 ; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR7]]
1322 ; TUNIT-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int2, align 4
1323 ; TUNIT-NEXT: store i32 17, ptr @Gstatic_int2, align 4
1324 ; TUNIT-NEXT: ret i32 [[LGS2]]
1326 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
1327 ; CGSCC-LABEL: define {{[^@]+}}@assume_read_global_bad
1328 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR6]] {
1329 ; CGSCC-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int2, align 4
1330 ; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42
1331 ; CGSCC-NEXT: store i32 13, ptr [[P]], align 4
1332 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR8]]
1333 ; CGSCC-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int2, align 4
1334 ; CGSCC-NEXT: store i32 17, ptr @Gstatic_int2, align 4
1335 ; CGSCC-NEXT: ret i32 [[LGS2]]
1337 %lgs1 = load i32, ptr @Gstatic_int2
1338 %c = icmp eq i32 %lgs1, 42
1339 store i32 13, ptr %p, align 4
1340 call void @llvm.assume(i1 %c)
1341 %lgs2 = load i32, ptr @Gstatic_int2
1342 store i32 17, ptr @Gstatic_int2, align 4
1346 define void @assume_write_globals() {
1348 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1349 ; TUNIT-LABEL: define {{[^@]+}}@assume_write_globals
1350 ; TUNIT-SAME: () #[[ATTR6:[0-9]+]] {
1351 ; TUNIT-NEXT: store i32 42, ptr @Gstatic_int1, align 4
1352 ; TUNIT-NEXT: store i32 42, ptr @Gstatic_int2, align 4
1353 ; TUNIT-NEXT: ret void
1355 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1356 ; CGSCC-LABEL: define {{[^@]+}}@assume_write_globals
1357 ; CGSCC-SAME: () #[[ATTR7:[0-9]+]] {
1358 ; CGSCC-NEXT: store i32 42, ptr @Gstatic_int1, align 4
1359 ; CGSCC-NEXT: store i32 42, ptr @Gstatic_int2, align 4
1360 ; CGSCC-NEXT: ret void
1362 store i32 42, ptr @Gstatic_int1, align 4
1363 store i32 42, ptr @Gstatic_int2, align 4
1368 ; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
1369 ; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
1370 ; TUNIT: attributes #[[ATTR2]] = { norecurse }
1371 ; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) }
1372 ; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
1373 ; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn }
1374 ; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
1375 ; TUNIT: attributes #[[ATTR7]] = { nofree willreturn memory(write) }
1376 ; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn memory(read) }
1377 ; TUNIT: attributes #[[ATTR9]] = { nofree willreturn }
1379 ; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
1380 ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
1381 ; CGSCC: attributes #[[ATTR2]] = { norecurse }
1382 ; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) }
1383 ; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
1384 ; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
1385 ; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn }
1386 ; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
1387 ; CGSCC: attributes #[[ATTR8]] = { nofree willreturn memory(write) }
1388 ; CGSCC: attributes #[[ATTR9]] = { nofree willreturn memory(read) }
1389 ; CGSCC: attributes #[[ATTR10]] = { nofree willreturn }