[SLP] Add cost model for `llvm.powi.*` intrinsics
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / dom.ll
blob80d843eaf8ed83948aacc21d9eb269ff60fb48a6
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 ; Test cases where both the true and false successors reach the same block,
5 ; dominated by one of them.
7 declare void @use(i1)
9 define i1 @test1(i8 %x) {
10 ; CHECK-LABEL: @test1(
11 ; CHECK-NEXT:  entry:
12 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
13 ; CHECK-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
14 ; CHECK:       bb1:
15 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 10
16 ; CHECK-NEXT:    call void @use(i1 true)
17 ; CHECK-NEXT:    br label [[BB2]]
18 ; CHECK:       bb2:
19 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 10
20 ; CHECK-NEXT:    ret i1 [[C_3]]
22 entry:
23   %c.1 = icmp ule i8 %x, 10
24   br i1 %c.1, label %bb1, label %bb2
26 bb1:
27   %c.2 = icmp ule i8 %x, 10
28   call void @use(i1 %c.2)
29   br label %bb2
31 bb2:
32   %c.3 = icmp ugt i8 %x, 10
33   ret i1 %c.3
36 define i1 @test_chain_1(i8 %x) {
37 ; CHECK-LABEL: @test_chain_1(
38 ; CHECK-NEXT:  entry:
39 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
40 ; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
41 ; CHECK:       then:
42 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 10
43 ; CHECK-NEXT:    call void @use(i1 true)
44 ; CHECK-NEXT:    br label [[EXIT:%.*]]
45 ; CHECK:       else:
46 ; CHECK-NEXT:    br label [[EXIT]]
47 ; CHECK:       exit:
48 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 10
49 ; CHECK-NEXT:    ret i1 [[C_3]]
51 entry:
52   %c.1 = icmp ule i8 %x, 10
53   br i1 %c.1, label %then, label %else
55 then:
56   %c.2 = icmp ule i8 %x, 10
57   call void @use(i1 %c.2)
58   br label %exit
60 else:
61   br label %exit
63 exit:
64   %c.3 = icmp ugt i8 %x, 10
65   ret i1 %c.3
68 define i1 @test_chain_2(i8 %x) {
69 ; CHECK-LABEL: @test_chain_2(
70 ; CHECK-NEXT:  entry:
71 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
72 ; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
73 ; CHECK:       then:
74 ; CHECK-NEXT:    br label [[EXIT:%.*]]
75 ; CHECK:       else:
76 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 10
77 ; CHECK-NEXT:    call void @use(i1 false)
78 ; CHECK-NEXT:    br label [[EXIT]]
79 ; CHECK:       exit:
80 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 10
81 ; CHECK-NEXT:    ret i1 [[C_3]]
83 entry:
84   %c.1 = icmp ule i8 %x, 10
85   br i1 %c.1, label %then, label %else
87 then:
88   br label %exit
90 else:
91   %c.2 = icmp ule i8 %x, 10
92   call void @use(i1 %c.2)
93   br label %exit
95 exit:
96   %c.3 = icmp ugt i8 %x, 10
97   ret i1 %c.3
100 define i1 @test2(i8 %x) {
101 ; CHECK-LABEL: @test2(
102 ; CHECK-NEXT:  entry:
103 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
104 ; CHECK-NEXT:    br i1 [[C_1]], label [[BB2:%.*]], label [[BB1:%.*]]
105 ; CHECK:       bb1:
106 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 10
107 ; CHECK-NEXT:    ret i1 [[C_2]]
108 ; CHECK:       bb2:
109 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i8 [[X]], 10
110 ; CHECK-NEXT:    call void @use(i1 true)
111 ; CHECK-NEXT:    br label [[BB1]]
113 entry:
114   %c.1 = icmp ule i8 %x, 10
115   br i1 %c.1, label %bb2, label %bb1
117 bb1:
118   %c.2 = icmp ugt i8 %x, 10
119   ret i1 %c.2
121 bb2:
122   %c.3 = icmp ule i8 %x, 10
123   call void @use(i1 %c.3)
124   br label %bb1
127 ; Test cases where the true/false successors are not domianted by the conditional branching block.
128 define i1 @test3(i8 %x, i1 %c) {
129 ; CHECK-LABEL: @test3(
130 ; CHECK-NEXT:  entry:
131 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB_COND:%.*]], label [[BB1:%.*]]
132 ; CHECK:       bb.cond:
133 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
134 ; CHECK-NEXT:    br i1 [[C_1]], label [[BB1]], label [[BB2:%.*]]
135 ; CHECK:       bb1:
136 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 10
137 ; CHECK-NEXT:    ret i1 [[C_2]]
138 ; CHECK:       bb2:
139 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 10
140 ; CHECK-NEXT:    ret i1 true
142 entry:
143   br i1 %c, label %bb.cond, label %bb1
145 bb.cond:
146   %c.1 = icmp ule i8 %x, 10
147   br i1 %c.1, label %bb1, label %bb2
149 bb1:
150   %c.2 = icmp ule i8 %x, 10
151   ret i1 %c.2
153 bb2:
154   %c.3 = icmp ugt i8 %x, 10
155   ret i1 %c.3
158 define i1 @test4(i8 %x, i1 %c) {
159 ; CHECK-LABEL: @test4(
160 ; CHECK-NEXT:  entry:
161 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB_COND:%.*]], label [[BB2:%.*]]
162 ; CHECK:       bb.cond:
163 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
164 ; CHECK-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[BB2]]
165 ; CHECK:       bb1:
166 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 10
167 ; CHECK-NEXT:    ret i1 true
168 ; CHECK:       bb2:
169 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 10
170 ; CHECK-NEXT:    ret i1 [[C_3]]
172 entry:
173   br i1 %c, label %bb.cond, label %bb2
175 bb.cond:
176   %c.1 = icmp ule i8 %x, 10
177   br i1 %c.1, label %bb1, label %bb2
179 bb1:
180   %c.2 = icmp ule i8 %x, 10
181   ret i1 %c.2
183 bb2:
184   %c.3 = icmp ugt i8 %x, 10
185   ret i1 %c.3
189 define i1 @test_cond_from_preheader(i8 %x, i1 %c) {
190 ; CHECK-LABEL: @test_cond_from_preheader(
191 ; CHECK-NEXT:  entry:
192 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[BB2:%.*]]
193 ; CHECK:       pre:
194 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
195 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP:%.*]], label [[BB2]]
196 ; CHECK:       loop:
197 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[X]], 10
198 ; CHECK-NEXT:    call void @use(i1 true)
199 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ugt i8 [[X]], 10
200 ; CHECK-NEXT:    call void @use(i1 false)
201 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 9
202 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
203 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 9
204 ; CHECK-NEXT:    call void @use(i1 [[C_3]])
205 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP]]
206 ; CHECK:       exit:
207 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ule i8 [[X]], 10
208 ; CHECK-NEXT:    ret i1 true
209 ; CHECK:       bb2:
210 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[X]], 10
211 ; CHECK-NEXT:    ret i1 [[C_5]]
213 entry:
214   br i1 %c, label %pre, label %bb2
216 pre:
217   %c.1 = icmp ule i8 %x, 10
218   br i1 %c.1, label %loop, label %bb2
220 loop:
221   %t.1 = icmp ule i8 %x, 10
222   call void @use(i1 %t.1)
223   %f.1 = icmp ugt i8 %x, 10
224   call void @use(i1 %f.1)
226   %c.2 = icmp ule i8 %x, 9
227   call void @use(i1 %c.2)
228   %c.3 = icmp ugt i8 %x, 9
229   call void @use(i1 %c.3)
231   br i1 true, label %exit, label %loop
233 exit:
234   %c.4 = icmp ule i8 %x, 10
235   ret i1 %c.4
237 bb2:
238   %c.5 = icmp ugt i8 %x, 10
239   ret i1 %c.5
242 define i1 @test_cond_from_preheader_successors_flipped(i8 %x, i1 %c) {
243 ; CHECK-LABEL: @test_cond_from_preheader_successors_flipped(
244 ; CHECK-NEXT:  entry:
245 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[BB2:%.*]]
246 ; CHECK:       pre:
247 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
248 ; CHECK-NEXT:    br i1 [[C_1]], label [[BB2]], label [[LOOP:%.*]]
249 ; CHECK:       loop:
250 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ule i8 [[X]], 10
251 ; CHECK-NEXT:    call void @use(i1 false)
252 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 10
253 ; CHECK-NEXT:    call void @use(i1 true)
254 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 11
255 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
256 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 11
257 ; CHECK-NEXT:    call void @use(i1 [[C_3]])
258 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP]]
259 ; CHECK:       exit:
260 ; CHECK-NEXT:    [[F_2:%.*]] = icmp ule i8 [[X]], 10
261 ; CHECK-NEXT:    ret i1 false
262 ; CHECK:       bb2:
263 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[X]], 10
264 ; CHECK-NEXT:    ret i1 [[C_5]]
266 entry:
267   br i1 %c, label %pre, label %bb2
269 pre:
270   %c.1 = icmp ule i8 %x, 10
271   br i1 %c.1, label %bb2, label %loop
273 loop:
274   %f.1 = icmp ule i8 %x, 10
275   call void @use(i1 %f.1)
276   %t.1 = icmp ugt i8 %x, 10
277   call void @use(i1 %t.1)
279   %c.2 = icmp ule i8 %x, 11
280   call void @use(i1 %c.2)
281   %c.3 = icmp ugt i8 %x, 11
282   call void @use(i1 %c.3)
284   br i1 true, label %exit, label %loop
286 exit:
287   %f.2 = icmp ule i8 %x, 10
288   ret i1 %f.2
290 bb2:
291   %c.5 = icmp ugt i8 %x, 10
292   ret i1 %c.5
295 define i1 @test_cond_from_preheader_and(i8 %x, i8 %y, i1 %c) {
296 ; CHECK-LABEL: @test_cond_from_preheader_and(
297 ; CHECK-NEXT:  entry:
298 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
299 ; CHECK:       exit:
300 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[Y:%.*]], 10
301 ; CHECK-NEXT:    ret i1 [[C_5]]
302 ; CHECK:       pre:
303 ; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10
304 ; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99
305 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_1]], [[Y_1]]
306 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP:%.*]], label [[EXIT_1:%.*]]
307 ; CHECK:       loop:
308 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[X]], 10
309 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ugt i8 [[X]], 10
310 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 true, false
311 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X]], 9
312 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_1]]
313 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 9
314 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], [[C_2]]
315 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ugt i8 [[Y]], 99
316 ; CHECK-NEXT:    [[R_4:%.*]] = xor i1 [[R_3]], true
317 ; CHECK-NEXT:    [[F_2:%.*]] = icmp ule i8 [[Y]], 99
318 ; CHECK-NEXT:    [[R_5:%.*]] = xor i1 [[R_4]], false
319 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[Y]], 100
320 ; CHECK-NEXT:    [[R_6:%.*]] = xor i1 [[R_5]], [[C_3]]
321 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i8 [[Y]], 100
322 ; CHECK-NEXT:    [[R_7:%.*]] = xor i1 [[R_6]], [[C_4]]
323 ; CHECK-NEXT:    call void @use(i1 [[R_7]])
324 ; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
325 ; CHECK:       exit.1:
326 ; CHECK-NEXT:    [[C_6:%.*]] = icmp ugt i8 [[Y]], 10
327 ; CHECK-NEXT:    ret i1 [[C_6]]
329 entry:
330   br i1 %c, label %pre, label %exit
332 exit:
333   %c.5 = icmp ugt i8 %y, 10
334   ret i1 %c.5
336 pre:
337   %x.1 = icmp ule i8 %x, 10
338   %y.1 = icmp ugt i8 %y, 99
339   %and = and i1 %x.1, %y.1
340   br i1 %and, label %loop, label %exit.1
342 loop:
343   %t.1 = icmp ule i8 %x, 10
344   %f.1 = icmp ugt i8 %x, 10
345   %r.1 = xor i1 %t.1, %f.1
347   %c.1 = icmp ule i8 %x, 9
348   %r.2 = xor i1 %r.1, %c.1
350   %c.2 = icmp ugt i8 %x, 9
351   %r.3 = xor i1 %r.2, %c.2
353   %t.2 = icmp ugt i8 %y, 99
354   %r.4 = xor i1 %r.3, %t.2
356   %f.2 = icmp ule i8 %y, 99
357   %r.5 = xor i1 %r.4, %f.2
359   %c.3 = icmp ugt i8 %y, 100
360   %r.6 = xor i1 %r.5, %c.3
362   %c.4 = icmp ugt i8 %y, 100
363   %r.7 = xor i1 %r.6, %c.4
364   call void @use(i1 %r.7)
366   br i1 true, label %exit, label %loop
368 exit.1:
369   %c.6 = icmp ugt i8 %y, 10
370   ret i1 %c.6
374 define i1 @test_cond_from_preheader_and_successors_flipped(i8 %x, i8 %y, i1 %c) {
375 ; CHECK-LABEL: @test_cond_from_preheader_and_successors_flipped(
376 ; CHECK-NEXT:  entry:
377 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
378 ; CHECK:       exit:
379 ; CHECK-NEXT:    [[C_9:%.*]] = icmp ugt i8 [[Y:%.*]], 10
380 ; CHECK-NEXT:    ret i1 [[C_9]]
381 ; CHECK:       pre:
382 ; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10
383 ; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99
384 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_1]], [[Y_1]]
385 ; CHECK-NEXT:    br i1 [[AND]], label [[EXIT_1:%.*]], label [[LOOP:%.*]]
386 ; CHECK:       loop:
387 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X]], 10
388 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 10
389 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 [[C_1]], [[C_2]]
390 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i8 [[X]], 9
391 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]]
392 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i8 [[X]], 9
393 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], [[C_4]]
394 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[Y]], 99
395 ; CHECK-NEXT:    [[R_4:%.*]] = xor i1 [[R_3]], [[C_5]]
396 ; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i8 [[Y]], 99
397 ; CHECK-NEXT:    [[R_5:%.*]] = xor i1 [[R_4]], [[C_6]]
398 ; CHECK-NEXT:    [[C_7:%.*]] = icmp ugt i8 [[Y]], 100
399 ; CHECK-NEXT:    [[R_6:%.*]] = xor i1 [[R_5]], [[C_7]]
400 ; CHECK-NEXT:    [[C_8:%.*]] = icmp ugt i8 [[Y]], 100
401 ; CHECK-NEXT:    [[R_7:%.*]] = xor i1 [[R_6]], [[C_8]]
402 ; CHECK-NEXT:    call void @use(i1 [[R_7]])
403 ; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
404 ; CHECK:       exit.1:
405 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[Y]], 10
406 ; CHECK-NEXT:    ret i1 true
408 entry:
409   br i1 %c, label %pre, label %exit
411 exit:
412   %c.9 = icmp ugt i8 %y, 10
413   ret i1 %c.9
415 pre:
416   %x.1 = icmp ule i8 %x, 10
417   %y.1 = icmp ugt i8 %y, 99
418   %and = and i1 %x.1, %y.1
419   br i1 %and, label %exit.1, label %loop
421 loop:
422   %c.1 = icmp ule i8 %x, 10
423   %c.2 = icmp ugt i8 %x, 10
424   %r.1 = xor i1 %c.1, %c.2
425   %c.3 = icmp ule i8 %x, 9
426   %r.2 = xor i1 %r.1, %c.3
427   %c.4 = icmp ugt i8 %x, 9
428   %r.3 = xor i1 %r.2, %c.4
430   %c.5 = icmp ugt i8 %y, 99
431   %r.4 = xor i1 %r.3, %c.5
432   %c.6 = icmp ule i8 %y, 99
433   %r.5 = xor i1 %r.4, %c.6
435   %c.7 = icmp ugt i8 %y, 100
436   %r.6 = xor i1 %r.5, %c.7
437   %c.8 = icmp ugt i8 %y, 100
438   %r.7 = xor i1 %r.6, %c.8
439   call void @use(i1 %r.7)
441   br i1 true, label %exit, label %loop
443 exit.1:
444   %t.1 = icmp ugt i8 %y, 10
445   ret i1 %t.1
448 define i1 @test_cond_from_preheader_or(i8 %x, i8 %y, i1 %c) {
449 ; CHECK-LABEL: @test_cond_from_preheader_or(
450 ; CHECK-NEXT:  entry:
451 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
452 ; CHECK:       exit:
453 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[Y:%.*]], 10
454 ; CHECK-NEXT:    ret i1 [[C_5]]
455 ; CHECK:       pre:
456 ; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10
457 ; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99
458 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_1]], [[Y_1]]
459 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT_1:%.*]], label [[LOOP:%.*]]
460 ; CHECK:       loop:
461 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 10
462 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ule i8 [[X]], 10
463 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 true, false
464 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X]], 11
465 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_1]]
466 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 11
467 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], [[C_2]]
468 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[Y]], 99
469 ; CHECK-NEXT:    [[R_4:%.*]] = xor i1 [[R_3]], true
470 ; CHECK-NEXT:    [[F_2:%.*]] = icmp ugt i8 [[Y]], 99
471 ; CHECK-NEXT:    [[R_5:%.*]] = xor i1 [[R_4]], false
472 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i8 [[Y]], 98
473 ; CHECK-NEXT:    [[R_6:%.*]] = xor i1 [[R_5]], [[C_3]]
474 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ule i8 [[Y]], 98
475 ; CHECK-NEXT:    [[R_7:%.*]] = xor i1 [[R_6]], [[C_4]]
476 ; CHECK-NEXT:    call void @use(i1 [[R_7]])
477 ; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
478 ; CHECK:       exit.1:
479 ; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i8 [[Y]], 100
480 ; CHECK-NEXT:    ret i1 [[C_6]]
482 entry:
483   br i1 %c, label %pre, label %exit
485 exit:
486   %c.5 = icmp ugt i8 %y, 10
487   ret i1 %c.5
489 pre:
490   %x.1 = icmp ule i8 %x, 10
491   %y.1 = icmp ugt i8 %y, 99
492   %or = or i1 %x.1, %y.1
493   br i1 %or, label %exit.1, label %loop
495 loop:
496   %t.1 = icmp ugt i8 %x, 10
497   %f.1 = icmp ule i8 %x, 10
498   %r.1 = xor i1 %t.1, %f.1
499   %c.1 = icmp ugt i8 %x, 11
500   %r.2 = xor i1 %r.1, %c.1
501   %c.2 = icmp ule i8 %x, 11
502   %r.3 = xor i1 %r.2, %c.2
504   %t.2 = icmp ule i8 %y, 99
505   %r.4 = xor i1 %r.3, %t.2
506   %f.2 = icmp ugt i8 %y, 99
507   %r.5 = xor i1 %r.4, %f.2
509   %c.3 = icmp ule i8 %y, 98
510   %r.6 = xor i1 %r.5, %c.3
511   %c.4 = icmp ule i8 %y, 98
512   %r.7 = xor i1 %r.6, %c.4
513   call void @use(i1 %r.7)
515   br i1 true, label %exit, label %loop
517 exit.1:
518   %c.6 = icmp ule i8 %y, 100
519   ret i1 %c.6
522 define i1 @test_cond_from_preheader_or_successor_flipped(i8 %x, i8 %y, i1 %c) {
523 ; CHECK-LABEL: @test_cond_from_preheader_or_successor_flipped(
524 ; CHECK-NEXT:  entry:
525 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
526 ; CHECK:       exit:
527 ; CHECK-NEXT:    [[C_9:%.*]] = icmp ugt i8 [[Y:%.*]], 10
528 ; CHECK-NEXT:    ret i1 [[C_9]]
529 ; CHECK:       pre:
530 ; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10
531 ; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99
532 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_1]], [[Y_1]]
533 ; CHECK-NEXT:    br i1 [[OR]], label [[LOOP:%.*]], label [[EXIT_1:%.*]]
534 ; CHECK:       loop:
535 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X]], 10
536 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 10
537 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 [[C_1]], [[C_2]]
538 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i8 [[X]], 9
539 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]]
540 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i8 [[X]], 9
541 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], [[C_4]]
542 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[Y]], 99
543 ; CHECK-NEXT:    [[R_4:%.*]] = xor i1 [[R_3]], [[C_5]]
544 ; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i8 [[Y]], 99
545 ; CHECK-NEXT:    [[R_5:%.*]] = xor i1 [[R_4]], [[C_6]]
546 ; CHECK-NEXT:    [[C_7:%.*]] = icmp ugt i8 [[Y]], 100
547 ; CHECK-NEXT:    [[R_6:%.*]] = xor i1 [[R_5]], [[C_7]]
548 ; CHECK-NEXT:    [[C_8:%.*]] = icmp ugt i8 [[Y]], 100
549 ; CHECK-NEXT:    [[R_7:%.*]] = xor i1 [[R_6]], [[C_8]]
550 ; CHECK-NEXT:    call void @use(i1 [[R_7]])
551 ; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
552 ; CHECK:       exit.1:
553 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[Y]], 100
554 ; CHECK-NEXT:    ret i1 true
556 entry:
557   br i1 %c, label %pre, label %exit
559 exit:
560   %c.9 = icmp ugt i8 %y, 10
561   ret i1 %c.9
563 pre:
564   %x.1 = icmp ule i8 %x, 10
565   %y.1 = icmp ugt i8 %y, 99
566   %or = or i1 %x.1, %y.1
567   br i1 %or, label %loop, label %exit.1
569 loop:
570   %c.1 = icmp ule i8 %x, 10
571   %c.2 = icmp ugt i8 %x, 10
572   %r.1 = xor i1 %c.1, %c.2
573   %c.3 = icmp ule i8 %x, 9
574   %r.2 = xor i1 %r.1, %c.3
575   %c.4 = icmp ugt i8 %x, 9
576   %r.3 = xor i1 %r.2, %c.4
578   %c.5 = icmp ugt i8 %y, 99
579   %r.4 = xor i1 %r.3, %c.5
580   %c.6 = icmp ule i8 %y, 99
581   %r.5 = xor i1 %r.4, %c.6
583   %c.7 = icmp ugt i8 %y, 100
584   %r.6 = xor i1 %r.5, %c.7
585   %c.8 = icmp ugt i8 %y, 100
586   %r.7 = xor i1 %r.6, %c.8
587   call void @use(i1 %r.7)
589   br i1 true, label %exit, label %loop
591 exit.1:
592   %t.1 = icmp ule i8 %y, 100
593   ret i1 %t.1
596 ; Test case from PR49819.
597 define i1 @both_branch_to_same_block(i4 %x) {
598 ; CHECK-LABEL: @both_branch_to_same_block(
599 ; CHECK-NEXT:  entry:
600 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i4 [[X:%.*]], 0
601 ; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT:%.*]], label [[EXIT]]
602 ; CHECK:       exit:
603 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i4 [[X]], 0
604 ; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i4 [[X]], 0
605 ; CHECK-NEXT:    [[RES:%.*]] = xor i1 [[C_2]], [[C_3]]
606 ; CHECK-NEXT:    ret i1 [[RES]]
608 entry:
609   %c.1 = icmp ne i4 %x, 0
610   br i1 %c.1, label %exit, label %exit
612 exit:
613   %c.2 = icmp ne i4 %x, 0
614   %c.3 = icmp eq i4 %x, 0
615   %res = xor i1 %c.2, %c.3
616   ret i1 %res
619 define i1 @both_branch_to_same_block_and(i4 %x, i4 %y) {
620 ; CHECK-LABEL: @both_branch_to_same_block_and(
621 ; CHECK-NEXT:  entry:
622 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i4 [[X:%.*]], 0
623 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i4 [[Y:%.*]], -6
624 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
625 ; CHECK-NEXT:    br i1 [[AND]], label [[EXIT:%.*]], label [[EXIT]]
626 ; CHECK:       exit:
627 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ne i4 [[X]], 0
628 ; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i4 [[X]], 0
629 ; CHECK-NEXT:    [[RES:%.*]] = xor i1 [[C_3]], [[C_4]]
630 ; CHECK-NEXT:    ret i1 [[RES]]
632 entry:
633   %c.1 = icmp ne i4 %x, 0
634   %c.2 = icmp ne i4 %y, 10
635   %and = and i1 %c.1, %c.2
636   br i1 %and, label %exit, label %exit
638 exit:
639   %c.3 = icmp ne i4 %x, 0
640   %c.4 = icmp eq i4 %x, 0
641   %res = xor i1 %c.3, %c.4
642   ret i1 %res
646 define i1 @both_branch_to_same_block_or(i4 %x, i4 %y) {
647 ; CHECK-LABEL: @both_branch_to_same_block_or(
648 ; CHECK-NEXT:  entry:
649 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i4 [[X:%.*]], 0
650 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i4 [[Y:%.*]], -6
651 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_1]], [[C_2]]
652 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[EXIT]]
653 ; CHECK:       exit:
654 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ne i4 [[X]], 0
655 ; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i4 [[X]], 0
656 ; CHECK-NEXT:    [[RES:%.*]] = xor i1 [[C_3]], [[C_4]]
657 ; CHECK-NEXT:    ret i1 [[RES]]
659 entry:
660   %c.1 = icmp ne i4 %x, 0
661   %c.2 = icmp ne i4 %y, 10
662   %or = or i1 %c.1, %c.2
663   br i1 %or, label %exit, label %exit
665 exit:
666   %c.3 = icmp ne i4 %x, 0
667   %c.4 = icmp eq i4 %x, 0
668   %res = xor i1 %c.3, %c.4
669   ret i1 %res