[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / Attributor / lvi-after-jumpthreading.ll
blobd99f4f8ffcc22485a7bf9140301e18838db7e7a9
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4 ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
7 define i8 @test1(i32 %a, i32 %length) {
8 ; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
9 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test1
10 ; IS__TUNIT_OPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]]) #[[ATTR0:[0-9]+]] {
11 ; IS__TUNIT_OPM-NEXT:  entry:
12 ; IS__TUNIT_OPM-NEXT:    br label [[LOOP:%.*]]
13 ; IS__TUNIT_OPM:       loop:
14 ; IS__TUNIT_OPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
15 ; IS__TUNIT_OPM-NEXT:    [[CND:%.*]] = icmp sge i32 [[IV]], 0
16 ; IS__TUNIT_OPM-NEXT:    br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
17 ; IS__TUNIT_OPM:       backedge:
18 ; IS__TUNIT_OPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
19 ; IS__TUNIT_OPM-NEXT:    [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
20 ; IS__TUNIT_OPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
21 ; IS__TUNIT_OPM:       exit:
22 ; IS__TUNIT_OPM-NEXT:    ret i8 0
24 ; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
25 ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test1
26 ; IS__TUNIT_NPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]]) #[[ATTR0:[0-9]+]] {
27 ; IS__TUNIT_NPM-NEXT:  entry:
28 ; IS__TUNIT_NPM-NEXT:    br label [[LOOP:%.*]]
29 ; IS__TUNIT_NPM:       loop:
30 ; IS__TUNIT_NPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
31 ; IS__TUNIT_NPM-NEXT:    br label [[BACKEDGE]]
32 ; IS__TUNIT_NPM:       backedge:
33 ; IS__TUNIT_NPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
34 ; IS__TUNIT_NPM-NEXT:    [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
35 ; IS__TUNIT_NPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT:%.*]]
36 ; IS__TUNIT_NPM:       exit:
37 ; IS__TUNIT_NPM-NEXT:    ret i8 0
39 ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
40 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test1
41 ; IS__CGSCC_OPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]]) #[[ATTR0:[0-9]+]] {
42 ; IS__CGSCC_OPM-NEXT:  entry:
43 ; IS__CGSCC_OPM-NEXT:    br label [[LOOP:%.*]]
44 ; IS__CGSCC_OPM:       loop:
45 ; IS__CGSCC_OPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
46 ; IS__CGSCC_OPM-NEXT:    [[CND:%.*]] = icmp sge i32 [[IV]], 0
47 ; IS__CGSCC_OPM-NEXT:    br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
48 ; IS__CGSCC_OPM:       backedge:
49 ; IS__CGSCC_OPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
50 ; IS__CGSCC_OPM-NEXT:    [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
51 ; IS__CGSCC_OPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
52 ; IS__CGSCC_OPM:       exit:
53 ; IS__CGSCC_OPM-NEXT:    ret i8 0
55 ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
56 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test1
57 ; IS__CGSCC_NPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]]) #[[ATTR0:[0-9]+]] {
58 ; IS__CGSCC_NPM-NEXT:  entry:
59 ; IS__CGSCC_NPM-NEXT:    br label [[LOOP:%.*]]
60 ; IS__CGSCC_NPM:       loop:
61 ; IS__CGSCC_NPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
62 ; IS__CGSCC_NPM-NEXT:    br label [[BACKEDGE]]
63 ; IS__CGSCC_NPM:       backedge:
64 ; IS__CGSCC_NPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
65 ; IS__CGSCC_NPM-NEXT:    [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
66 ; IS__CGSCC_NPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT:%.*]]
67 ; IS__CGSCC_NPM:       exit:
68 ; IS__CGSCC_NPM-NEXT:    ret i8 0
70 entry:
71   br label %loop
73 loop:
74   %iv = phi i32 [0, %entry], [%iv.next, %backedge]
75   %cnd = icmp sge i32 %iv, 0
76   br i1 %cnd, label %backedge, label %exit
78 backedge:
79   %iv.next = add nsw i32 %iv, 1
80   %cont = icmp slt i32 %iv.next, 400
81   br i1 %cont, label %loop, label %exit
83 exit:
84   ret i8 0
87 define i8 @test2(i32 %n) {
88 ; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
89 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test2
90 ; IS__TUNIT_OPM-SAME: (i32 [[N:%.*]]) #[[ATTR0]] {
91 ; IS__TUNIT_OPM-NEXT:  entry:
92 ; IS__TUNIT_OPM-NEXT:    br label [[LOOP:%.*]]
93 ; IS__TUNIT_OPM:       loop:
94 ; IS__TUNIT_OPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
95 ; IS__TUNIT_OPM-NEXT:    [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
96 ; IS__TUNIT_OPM-NEXT:    [[CND1:%.*]] = icmp sge i32 [[IV]], 0
97 ; IS__TUNIT_OPM-NEXT:    [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
98 ; IS__TUNIT_OPM-NEXT:    [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
99 ; IS__TUNIT_OPM-NEXT:    br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
100 ; IS__TUNIT_OPM:       backedge:
101 ; IS__TUNIT_OPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
102 ; IS__TUNIT_OPM-NEXT:    [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
103 ; IS__TUNIT_OPM-NEXT:    [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
104 ; IS__TUNIT_OPM-NEXT:    [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
105 ; IS__TUNIT_OPM-NEXT:    [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
106 ; IS__TUNIT_OPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
107 ; IS__TUNIT_OPM:       exit:
108 ; IS__TUNIT_OPM-NEXT:    ret i8 0
110 ; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
111 ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test2
112 ; IS__TUNIT_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR0]] {
113 ; IS__TUNIT_NPM-NEXT:  entry:
114 ; IS__TUNIT_NPM-NEXT:    br label [[LOOP:%.*]]
115 ; IS__TUNIT_NPM:       loop:
116 ; IS__TUNIT_NPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
117 ; IS__TUNIT_NPM-NEXT:    [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
118 ; IS__TUNIT_NPM-NEXT:    [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
119 ; IS__TUNIT_NPM-NEXT:    br i1 [[CND2]], label [[BACKEDGE]], label [[EXIT:%.*]]
120 ; IS__TUNIT_NPM:       backedge:
121 ; IS__TUNIT_NPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
122 ; IS__TUNIT_NPM-NEXT:    [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
123 ; IS__TUNIT_NPM-NEXT:    [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
124 ; IS__TUNIT_NPM-NEXT:    [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
125 ; IS__TUNIT_NPM-NEXT:    [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
126 ; IS__TUNIT_NPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
127 ; IS__TUNIT_NPM:       exit:
128 ; IS__TUNIT_NPM-NEXT:    ret i8 0
130 ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
131 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2
132 ; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) #[[ATTR0]] {
133 ; IS__CGSCC_OPM-NEXT:  entry:
134 ; IS__CGSCC_OPM-NEXT:    br label [[LOOP:%.*]]
135 ; IS__CGSCC_OPM:       loop:
136 ; IS__CGSCC_OPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
137 ; IS__CGSCC_OPM-NEXT:    [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
138 ; IS__CGSCC_OPM-NEXT:    [[CND1:%.*]] = icmp sge i32 [[IV]], 0
139 ; IS__CGSCC_OPM-NEXT:    [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
140 ; IS__CGSCC_OPM-NEXT:    [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
141 ; IS__CGSCC_OPM-NEXT:    br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
142 ; IS__CGSCC_OPM:       backedge:
143 ; IS__CGSCC_OPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
144 ; IS__CGSCC_OPM-NEXT:    [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
145 ; IS__CGSCC_OPM-NEXT:    [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
146 ; IS__CGSCC_OPM-NEXT:    [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
147 ; IS__CGSCC_OPM-NEXT:    [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
148 ; IS__CGSCC_OPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
149 ; IS__CGSCC_OPM:       exit:
150 ; IS__CGSCC_OPM-NEXT:    ret i8 0
152 ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
153 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test2
154 ; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR0]] {
155 ; IS__CGSCC_NPM-NEXT:  entry:
156 ; IS__CGSCC_NPM-NEXT:    br label [[LOOP:%.*]]
157 ; IS__CGSCC_NPM:       loop:
158 ; IS__CGSCC_NPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
159 ; IS__CGSCC_NPM-NEXT:    [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
160 ; IS__CGSCC_NPM-NEXT:    [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
161 ; IS__CGSCC_NPM-NEXT:    br i1 [[CND2]], label [[BACKEDGE]], label [[EXIT:%.*]]
162 ; IS__CGSCC_NPM:       backedge:
163 ; IS__CGSCC_NPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
164 ; IS__CGSCC_NPM-NEXT:    [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
165 ; IS__CGSCC_NPM-NEXT:    [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
166 ; IS__CGSCC_NPM-NEXT:    [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
167 ; IS__CGSCC_NPM-NEXT:    [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
168 ; IS__CGSCC_NPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
169 ; IS__CGSCC_NPM:       exit:
170 ; IS__CGSCC_NPM-NEXT:    ret i8 0
172 entry:
173   br label %loop
175 loop:
176   %iv = phi i32 [0, %entry], [%iv.next, %backedge]
177   %iv2 = phi i32 [%n, %entry], [%iv2.next, %backedge]
179   %cnd1 = icmp sge i32 %iv, 0
180   %cnd2 = icmp sgt i32 %iv2, 0
181   %cnd = and i1 %cnd1, %cnd2
182   br i1 %cnd, label %backedge, label %exit
184 backedge:
185   %iv.next = add nsw i32 %iv, 1
186   %iv2.next = sub nsw i32 %iv2, 1
187   %cont1 = icmp slt i32 %iv.next, 400
188   %cont2 = icmp sgt i32 %iv2.next, 0
189   %cont = and i1 %cont1, %cont2
190   br i1 %cont, label %loop, label %exit
192 exit:
193   ret i8 0
196 ; Merging cont block into do block.
197 define i32 @test3(i32 %i, i1 %f, i32 %n) {
198 ; IS________OPM-LABEL: define {{[^@]+}}@test3
199 ; IS________OPM-SAME: (i32 [[I:%.*]], i1 [[F:%.*]], i32 [[N:%.*]]) {
200 ; IS________OPM-NEXT:  entry:
201 ; IS________OPM-NEXT:    [[C:%.*]] = icmp ne i32 [[I]], -2134
202 ; IS________OPM-NEXT:    br i1 [[C]], label [[DO:%.*]], label [[EXIT:%.*]]
203 ; IS________OPM:       exit:
204 ; IS________OPM-NEXT:    [[C1:%.*]] = icmp ne i32 [[I]], -42
205 ; IS________OPM-NEXT:    br i1 [[C1]], label [[EXIT2:%.*]], label [[EXIT]]
206 ; IS________OPM:       cont:
207 ; IS________OPM-NEXT:    [[COND_3:%.*]] = icmp sgt i32 [[I]], [[N]]
208 ; IS________OPM-NEXT:    br i1 [[COND_3]], label [[EXIT2]], label [[EXIT]]
209 ; IS________OPM:       do:
210 ; IS________OPM-NEXT:    [[COND_0:%.*]] = icmp sgt i32 [[I]], 0
211 ; IS________OPM-NEXT:    [[CONSUME:%.*]] = call i32 @consume(i1 [[COND_0]])
212 ; IS________OPM-NEXT:    [[COND:%.*]] = icmp eq i32 [[I]], 0
213 ; IS________OPM-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND]]) [ "deopt"() ]
214 ; IS________OPM-NEXT:    [[COND_2:%.*]] = icmp sgt i32 [[I]], 0
215 ; IS________OPM-NEXT:    br i1 [[COND_2]], label [[EXIT]], label [[CONT:%.*]]
216 ; IS________OPM:       exit2:
217 ; IS________OPM-NEXT:    ret i32 30
219 ; IS________NPM-LABEL: define {{[^@]+}}@test3
220 ; IS________NPM-SAME: (i32 [[I:%.*]], i1 [[F:%.*]], i32 [[N:%.*]]) {
221 ; IS________NPM-NEXT:  entry:
222 ; IS________NPM-NEXT:    [[C:%.*]] = icmp ne i32 [[I]], -2134
223 ; IS________NPM-NEXT:    br i1 [[C]], label [[DO:%.*]], label [[EXIT:%.*]]
224 ; IS________NPM:       exit:
225 ; IS________NPM-NEXT:    [[C1:%.*]] = icmp ne i32 [[I]], -42
226 ; IS________NPM-NEXT:    br i1 [[C1]], label [[EXIT2:%.*]], label [[EXIT]]
227 ; IS________NPM:       cont:
228 ; IS________NPM-NEXT:    [[COND_3:%.*]] = icmp sgt i32 [[I]], [[N]]
229 ; IS________NPM-NEXT:    br i1 [[COND_3]], label [[EXIT2]], label [[EXIT]]
230 ; IS________NPM:       do:
231 ; IS________NPM-NEXT:    [[COND_0:%.*]] = icmp sgt i32 [[I]], 0
232 ; IS________NPM-NEXT:    [[CONSUME:%.*]] = call i32 @consume(i1 [[COND_0]])
233 ; IS________NPM-NEXT:    [[COND:%.*]] = icmp eq i32 [[I]], 0
234 ; IS________NPM-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND]]) [ "deopt"() ]
235 ; IS________NPM-NEXT:    br label [[CONT:%.*]]
236 ; IS________NPM:       exit2:
237 ; IS________NPM-NEXT:    ret i32 30
239 entry:
240   %c = icmp ne i32 %i, -2134
241   br i1 %c, label %do, label %exit
243 exit:
244   %c1 = icmp ne i32 %i, -42
245   br i1 %c1, label %exit2, label %exit
247 ; Here cont is merged to do and i is any value except -2134.
248 ; i is not the single value: zero.
249 cont:
250   %cond.3 = icmp sgt i32 %i, %n
251   br i1 %cond.3, label %exit2, label %exit
254   %cond.0 = icmp sgt i32 %i, 0
255   %consume = call i32 @consume(i1 %cond.0)
256   %cond = icmp eq i32 %i, 0
257   call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
258   %cond.2 = icmp sgt i32 %i, 0
259   br i1 %cond.2, label %exit, label %cont
261 exit2:
262 ; LatticeVal for: 'i32 %i' is: constantrange<-2134, 1>
263   ret i32 30
266 ; FIXME: We should be able to merge cont into do.
267 ; FIXME: COND should be replaced with false. This will be fixed by improving LVI.
268 define i32 @test4(i32 %i, i1 %f, i32 %n) {
269 ; CHECK-LABEL: define {{[^@]+}}@test4
270 ; CHECK-SAME: (i32 [[I:%.*]], i1 [[F:%.*]], i32 [[N:%.*]]) {
271 ; CHECK-NEXT:  entry:
272 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I]], -2134
273 ; CHECK-NEXT:    br i1 [[C]], label [[DO:%.*]], label [[EXIT:%.*]]
274 ; CHECK:       exit:
275 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i32 [[I]], -42
276 ; CHECK-NEXT:    br i1 [[C1]], label [[EXIT2:%.*]], label [[EXIT]]
277 ; CHECK:       cont:
278 ; CHECK-NEXT:    call void @dummy(i1 [[F]]) #[[ATTR2:[0-9]+]]
279 ; CHECK-NEXT:    br label [[EXIT2]]
280 ; CHECK:       do:
281 ; CHECK-NEXT:    call void @dummy(i1 [[F]]) #[[ATTR2]]
282 ; CHECK-NEXT:    [[CONSUME:%.*]] = call i32 @exit()
283 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[F]])
284 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i1 [[F]], false
285 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[CONT:%.*]]
286 ; CHECK:       exit2:
287 ; CHECK-NEXT:    ret i32 30
289 entry:
290   %c = icmp ne i32 %i, -2134
291   br i1 %c, label %do, label %exit
293 exit:                                             ; preds = %do, %cont, %exit, %entry
294   %c1 = icmp ne i32 %i, -42
295   br i1 %c1, label %exit2, label %exit
297 cont:                                             ; preds = %do
298   call void @dummy(i1 %f)
299   br label %exit2
301 do:                                               ; preds = %entry
302   call void @dummy(i1 %f)
303   %consume = call i32 @exit()
304   call void @llvm.assume(i1 %f)
305   %cond = icmp eq i1 %f, false
306   br i1 %cond, label %exit, label %cont
308 exit2:                                            ; preds = %cont, %exit
309   ret i32 30
312 declare i32 @exit()
313 declare i32 @consume(i1)
314 declare void @llvm.assume(i1) nounwind
315 declare void @dummy(i1) nounwind
316 declare void @llvm.experimental.guard(i1, ...)
318 ; IS__TUNIT_OPM: attributes #[[ATTR0]] = { nofree nosync nounwind readnone }
319 ; IS__TUNIT_OPM: attributes #[[ATTR1:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
320 ; IS__TUNIT_OPM: attributes #[[ATTR2]] = { nounwind }
321 ; IS__TUNIT_OPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync willreturn }
323 ; IS__TUNIT_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
324 ; IS__TUNIT_NPM: attributes #[[ATTR1:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
325 ; IS__TUNIT_NPM: attributes #[[ATTR2]] = { nounwind }
326 ; IS__TUNIT_NPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync willreturn }
328 ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone }
329 ; IS__CGSCC_OPM: attributes #[[ATTR1:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
330 ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nounwind }
331 ; IS__CGSCC_OPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync willreturn }
333 ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
334 ; IS__CGSCC_NPM: attributes #[[ATTR1:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
335 ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nounwind }
336 ; IS__CGSCC_NPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync willreturn }