Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / Attributor / value-simplify-assume.ll
blob0ccad5cf21e2712920c4882af1e843ce20518a2a
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:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 0, align 4
14 ; CHECK: @[[GSTATIC_INT2:[a-zA-Z0-9_$"\\.-]+]] = 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]]
23   %l = load i1, ptr %p
24   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]]
38   %stack = alloca i1
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)
43   ret 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
59   %stack = alloca i1
60   store i1 true, ptr %stack
61   %l = load i1, ptr %stack
62   call void @llvm.assume(i1 %l)
63   ret 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]]
79   %stack = alloca i1
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)
84   call void @unknown()
85   %l2 = load i1, ptr %stack
86   ret i1 %l2
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]]
111   %stack = alloca i1
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)
116   ret i1 %l
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
138   %stack = alloca i1
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)
143   ret i1 %l4
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]]
157   %stack = alloca i1
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)
162   ret 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]]
182   %stack = alloca i1
183   store i1 %arg, ptr %stack
184   %l = load i1, ptr %stack
185   call void @llvm.assume(i1 %l)
186   ret 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]]
202   %stack = alloca i1
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)
207   call void @unknown()
208   %l2 = load i1, ptr %stack
209   ret i1 %l2
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]]
234   %stack = alloca i1
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)
239   ret i1 %l
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]]
262   %stack = alloca i1
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)
267   ret i1 %l
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:%.*]]
278 ; TUNIT:       t:
279 ; TUNIT-NEXT:    br label [[M:%.*]]
280 ; TUNIT:       f:
281 ; TUNIT-NEXT:    br label [[M]]
282 ; TUNIT:       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:%.*]]
292 ; CGSCC:       t:
293 ; CGSCC-NEXT:    br label [[M:%.*]]
294 ; CGSCC:       f:
295 ; CGSCC-NEXT:    br label [[M]]
296 ; CGSCC:       m:
297 ; CGSCC-NEXT:    ret i1 [[ARG]]
299   %stack = alloca i1
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
306   br label %m
308   store i1 false, ptr %stack
309   br label %m
311   ret i1 %l
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:%.*]]
319 ; CHECK:       t:
320 ; CHECK-NEXT:    br label [[M:%.*]]
321 ; CHECK:       f:
322 ; CHECK-NEXT:    br label [[M]]
323 ; CHECK:       m:
324 ; CHECK-NEXT:    ret void
326   %stack = alloca i1
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
333   br label %m
335   store i1 false, ptr %stack
336   br label %m
338   ret void
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:%.*]]
347 ; TUNIT:       t:
348 ; TUNIT-NEXT:    store i1 true, ptr [[STACK]], align 1
349 ; TUNIT-NEXT:    br label [[M:%.*]]
350 ; TUNIT:       f:
351 ; TUNIT-NEXT:    store i1 false, ptr [[STACK]], align 1
352 ; TUNIT-NEXT:    br label [[M]]
353 ; TUNIT:       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:%.*]]
363 ; CGSCC:       t:
364 ; CGSCC-NEXT:    store i1 true, ptr [[STACK]], align 1
365 ; CGSCC-NEXT:    br label [[M:%.*]]
366 ; CGSCC:       f:
367 ; CGSCC-NEXT:    store i1 false, ptr [[STACK]], align 1
368 ; CGSCC-NEXT:    br label [[M]]
369 ; CGSCC:       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]]
374   %stack = alloca i1
375   store i1 %arg, ptr %stack
376   br i1 %cond, label %t, label %f
378   store i1 true, ptr %stack
379   br label %m
381   store i1 false, ptr %stack
382   br label %m
384   %l = load i1, ptr %stack
385   call void @llvm.assume(i1 %l)
386   ret 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:%.*]]
395 ; CHECK:       t:
396 ; CHECK-NEXT:    br label [[M:%.*]]
397 ; CHECK:       f:
398 ; CHECK-NEXT:    br label [[M]]
399 ; CHECK:       m:
400 ; CHECK-NEXT:    [[L:%.*]] = load i1, ptr [[STACK]], align 1
401 ; CHECK-NEXT:    ret void
403   %stack = alloca i1
404   store i1 %arg, ptr %stack
405   br i1 %cond, label %t, label %f
407   store i1 true, ptr %stack
408   br label %m
410   store i1 false, ptr %stack
411   br label %m
413   %l = load i1, ptr %stack
414   call void @llvm.assume(i1 %l)
415   ret void
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:%.*]]
424 ; TUNIT:       t:
425 ; TUNIT-NEXT:    store i1 true, ptr [[STACK]], align 1
426 ; TUNIT-NEXT:    br label [[M:%.*]]
427 ; TUNIT:       f:
428 ; TUNIT-NEXT:    store i1 false, ptr [[STACK]], align 1
429 ; TUNIT-NEXT:    br label [[M]]
430 ; TUNIT:       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:%.*]]
442 ; CGSCC:       t:
443 ; CGSCC-NEXT:    store i1 true, ptr [[STACK]], align 1
444 ; CGSCC-NEXT:    br label [[M:%.*]]
445 ; CGSCC:       f:
446 ; CGSCC-NEXT:    store i1 false, ptr [[STACK]], align 1
447 ; CGSCC-NEXT:    br label [[M]]
448 ; CGSCC:       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]]
452   %stack = alloca i1
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
459   br label %m
461   store i1 false, ptr %stack
462   br label %m
464   %r = call i1 @readI1p(ptr %stack)
465   ret i1 %r
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:%.*]]
474 ; TUNIT:       t:
475 ; TUNIT-NEXT:    store i1 true, ptr [[STACK]], align 1
476 ; TUNIT-NEXT:    br label [[M:%.*]]
477 ; TUNIT:       f:
478 ; TUNIT-NEXT:    store i1 false, ptr [[STACK]], align 1
479 ; TUNIT-NEXT:    br label [[M]]
480 ; TUNIT:       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:%.*]]
492 ; CGSCC:       t:
493 ; CGSCC-NEXT:    store i1 true, ptr [[STACK]], align 1
494 ; CGSCC-NEXT:    br label [[M:%.*]]
495 ; CGSCC:       f:
496 ; CGSCC-NEXT:    store i1 false, ptr [[STACK]], align 1
497 ; CGSCC-NEXT:    br label [[M]]
498 ; CGSCC:       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]]
504   %stack = alloca i1
505   store i1 %arg, ptr %stack
506   br i1 %cond, label %t, label %f
508   store i1 true, ptr %stack
509   br label %m
511   store i1 false, ptr %stack
512   br label %m
514   %l = load i1, ptr %stack
515   call void @llvm.assume(i1 %l)
516   %r = call i1 @readI1p(ptr %stack)
517   ret i1 %r
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:%.*]]
526 ; TUNIT:       t:
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:%.*]]
531 ; TUNIT:       f:
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]]
536 ; TUNIT:       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:%.*]]
550 ; CGSCC:       t:
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:%.*]]
555 ; CGSCC:       f:
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]]
560 ; CGSCC:       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]]
566   %stack = alloca i1
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)
575   br label %m
577   store i1 false, ptr %stack
578   %l3 = load i1, ptr %stack
579   call void @llvm.assume(i1 %l3)
580   br label %m
582   %l4 = load i1, ptr %stack
583   call void @llvm.assume(i1 %l4)
584   %r = call i1 @readI1p(ptr %stack)
585   ret i1 %r
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:%.*]]
595 ; TUNIT:       t:
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:%.*]]
600 ; TUNIT:       f:
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]]
605 ; TUNIT:       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:%.*]]
619 ; CGSCC:       t:
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:%.*]]
624 ; CGSCC:       f:
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]]
629 ; CGSCC:       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]]
635   %stack = alloca i1
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)
644   br label %m
646   store i1 false, ptr %stack
647   %l3 = load i1, ptr %stack
648   call void @llvm.assume(i1 %l3)
649   br label %m
651   %l4 = load i1, ptr %stack
652   call void @llvm.assume(i1 %l4)
653   %r = call i1 @readI1p(ptr %stack)
654   ret i1 %r
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]]
667   %stack = alloca i1
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)
672   ret 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
688   %stack = alloca i1
689   store i1 true, ptr %stack
690   %l = load i1, ptr %stack
691   call void @llvm.assume(i1 %l)
692   ret 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]]
706   %stack = alloca i1
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)
711   call void @unknown()
712   %l2 = load i1, ptr %stack
713   ret i1 %l2
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]]
734   %stack = alloca i1
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)
739   ret i1 %l
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]]
759   %stack = alloca i1
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)
764   ret i1 %l4
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]]
777   %stack = alloca i1
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)
782   ret 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]]
802   %stack = alloca i1
803   store i1 %arg, ptr %stack
804   %l = load i1, ptr %stack
805   call void @llvm.assume(i1 %l)
806   ret 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]]
821   %stack = alloca i1
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)
826   call void @unknown()
827   %l2 = load i1, ptr %stack
828   ret i1 %l2
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]]
851   %stack = alloca i1
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)
856   ret i1 %l
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]]
879   %stack = alloca i1
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)
884   ret i1 %l
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:%.*]]
895 ; TUNIT:       t:
896 ; TUNIT-NEXT:    br label [[M:%.*]]
897 ; TUNIT:       f:
898 ; TUNIT-NEXT:    br label [[M]]
899 ; TUNIT:       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:%.*]]
909 ; CGSCC:       t:
910 ; CGSCC-NEXT:    br label [[M:%.*]]
911 ; CGSCC:       f:
912 ; CGSCC-NEXT:    br label [[M]]
913 ; CGSCC:       m:
914 ; CGSCC-NEXT:    ret i1 [[ARG]]
916   %stack = alloca i1
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
923   br label %m
925   store i1 false, ptr %stack
926   br label %m
928   ret i1 %l
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:%.*]]
936 ; CHECK:       t:
937 ; CHECK-NEXT:    br label [[M:%.*]]
938 ; CHECK:       f:
939 ; CHECK-NEXT:    br label [[M]]
940 ; CHECK:       m:
941 ; CHECK-NEXT:    ret void
943   %stack = alloca i1
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
950   br label %m
952   store i1 false, ptr %stack
953   br label %m
955   ret void
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:%.*]]
964 ; TUNIT:       t:
965 ; TUNIT-NEXT:    store i1 true, ptr [[STACK]], align 1
966 ; TUNIT-NEXT:    br label [[M:%.*]]
967 ; TUNIT:       f:
968 ; TUNIT-NEXT:    store i1 false, ptr [[STACK]], align 1
969 ; TUNIT-NEXT:    br label [[M]]
970 ; TUNIT:       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:%.*]]
980 ; CGSCC:       t:
981 ; CGSCC-NEXT:    store i1 true, ptr [[STACK]], align 1
982 ; CGSCC-NEXT:    br label [[M:%.*]]
983 ; CGSCC:       f:
984 ; CGSCC-NEXT:    store i1 false, ptr [[STACK]], align 1
985 ; CGSCC-NEXT:    br label [[M]]
986 ; CGSCC:       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]]
991   %stack = alloca i1
992   store i1 %arg, ptr %stack
993   br i1 %cond, label %t, label %f
995   store i1 true, ptr %stack
996   br label %m
998   store i1 false, ptr %stack
999   br label %m
1001   %l = load i1, ptr %stack
1002   call void @llvm.assume(i1 %l)
1003   ret 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:%.*]]
1012 ; CHECK:       t:
1013 ; CHECK-NEXT:    br label [[M:%.*]]
1014 ; CHECK:       f:
1015 ; CHECK-NEXT:    br label [[M]]
1016 ; CHECK:       m:
1017 ; CHECK-NEXT:    [[L:%.*]] = load i1, ptr [[STACK]], align 1
1018 ; CHECK-NEXT:    ret void
1020   %stack = alloca i1
1021   store i1 %arg, ptr %stack
1022   br i1 %cond, label %t, label %f
1024   store i1 true, ptr %stack
1025   br label %m
1027   store i1 false, ptr %stack
1028   br label %m
1030   %l = load i1, ptr %stack
1031   call void @llvm.assume(i1 %l)
1032   ret void
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:%.*]]
1041 ; TUNIT:       t:
1042 ; TUNIT-NEXT:    store i1 true, ptr [[STACK]], align 1
1043 ; TUNIT-NEXT:    br label [[M:%.*]]
1044 ; TUNIT:       f:
1045 ; TUNIT-NEXT:    store i1 false, ptr [[STACK]], align 1
1046 ; TUNIT-NEXT:    br label [[M]]
1047 ; TUNIT:       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:%.*]]
1059 ; CGSCC:       t:
1060 ; CGSCC-NEXT:    store i1 true, ptr [[STACK]], align 1
1061 ; CGSCC-NEXT:    br label [[M:%.*]]
1062 ; CGSCC:       f:
1063 ; CGSCC-NEXT:    store i1 false, ptr [[STACK]], align 1
1064 ; CGSCC-NEXT:    br label [[M]]
1065 ; CGSCC:       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]]
1069   %stack = alloca i1
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
1076   br label %m
1078   store i1 false, ptr %stack
1079   br label %m
1081   %r = call i1 @readI1p(ptr %stack)
1082   ret i1 %r
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:%.*]]
1091 ; TUNIT:       t:
1092 ; TUNIT-NEXT:    store i1 true, ptr [[STACK]], align 1
1093 ; TUNIT-NEXT:    br label [[M:%.*]]
1094 ; TUNIT:       f:
1095 ; TUNIT-NEXT:    store i1 false, ptr [[STACK]], align 1
1096 ; TUNIT-NEXT:    br label [[M]]
1097 ; TUNIT:       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:%.*]]
1109 ; CGSCC:       t:
1110 ; CGSCC-NEXT:    store i1 true, ptr [[STACK]], align 1
1111 ; CGSCC-NEXT:    br label [[M:%.*]]
1112 ; CGSCC:       f:
1113 ; CGSCC-NEXT:    store i1 false, ptr [[STACK]], align 1
1114 ; CGSCC-NEXT:    br label [[M]]
1115 ; CGSCC:       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]]
1121   %stack = alloca i1
1122   store i1 %arg, ptr %stack
1123   br i1 %cond, label %t, label %f
1125   store i1 true, ptr %stack
1126   br label %m
1128   store i1 false, ptr %stack
1129   br label %m
1131   %l = load i1, ptr %stack
1132   call void @llvm.assume(i1 %l)
1133   %r = call i1 @readI1p(ptr %stack)
1134   ret i1 %r
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:%.*]]
1143 ; TUNIT:       t:
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:%.*]]
1148 ; TUNIT:       f:
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]]
1153 ; TUNIT:       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:%.*]]
1167 ; CGSCC:       t:
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:%.*]]
1172 ; CGSCC:       f:
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]]
1177 ; CGSCC:       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]]
1183   %stack = alloca i1
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)
1192   br label %m
1194   store i1 false, ptr %stack
1195   %l3 = load i1, ptr %stack
1196   call void @llvm.assume(i1 %l3)
1197   br label %m
1199   %l4 = load i1, ptr %stack
1200   call void @llvm.assume(i1 %l4)
1201   %r = call i1 @readI1p(ptr %stack)
1202   ret i1 %r
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:%.*]]
1212 ; TUNIT:       t:
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:%.*]]
1217 ; TUNIT:       f:
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]]
1222 ; TUNIT:       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:%.*]]
1236 ; CGSCC:       t:
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:%.*]]
1241 ; CGSCC:       f:
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]]
1246 ; CGSCC:       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]]
1252   %stack = alloca i1
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)
1261   br label %m
1263   store i1 false, ptr %stack
1264   %l3 = load i1, ptr %stack
1265   call void @llvm.assume(i1 %l3)
1266   br label %m
1268   %l4 = load i1, ptr %stack
1269   call void @llvm.assume(i1 %l4)
1270   %r = call i1 @readI1p(ptr %stack)
1271   ret i1 %r
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
1309   ret i32 %add
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
1343   ret i32 %lgs2
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
1364   ret void
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 }