AMDGPU: Allow f16/bf16 for DS_READ_TR16_B64 gfx950 builtins (#118297)
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / dom.ll
blob7397360b23ec158b3c3d41e032468eab523b53fd
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:    call void @use(i1 true)
16 ; CHECK-NEXT:    br label [[BB2]]
17 ; CHECK:       bb2:
18 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 10
19 ; CHECK-NEXT:    ret i1 [[C_3]]
21 entry:
22   %c.1 = icmp ule i8 %x, 10
23   br i1 %c.1, label %bb1, label %bb2
25 bb1:
26   %c.2 = icmp ule i8 %x, 10
27   call void @use(i1 %c.2)
28   br label %bb2
30 bb2:
31   %c.3 = icmp ugt i8 %x, 10
32   ret i1 %c.3
35 define i1 @test_chain_1(i8 %x) {
36 ; CHECK-LABEL: @test_chain_1(
37 ; CHECK-NEXT:  entry:
38 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
39 ; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
40 ; CHECK:       then:
41 ; CHECK-NEXT:    call void @use(i1 true)
42 ; CHECK-NEXT:    br label [[EXIT:%.*]]
43 ; CHECK:       else:
44 ; CHECK-NEXT:    br label [[EXIT]]
45 ; CHECK:       exit:
46 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 10
47 ; CHECK-NEXT:    ret i1 [[C_3]]
49 entry:
50   %c.1 = icmp ule i8 %x, 10
51   br i1 %c.1, label %then, label %else
53 then:
54   %c.2 = icmp ule i8 %x, 10
55   call void @use(i1 %c.2)
56   br label %exit
58 else:
59   br label %exit
61 exit:
62   %c.3 = icmp ugt i8 %x, 10
63   ret i1 %c.3
66 define i1 @test_chain_2(i8 %x) {
67 ; CHECK-LABEL: @test_chain_2(
68 ; CHECK-NEXT:  entry:
69 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
70 ; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
71 ; CHECK:       then:
72 ; CHECK-NEXT:    br label [[EXIT:%.*]]
73 ; CHECK:       else:
74 ; CHECK-NEXT:    call void @use(i1 false)
75 ; CHECK-NEXT:    br label [[EXIT]]
76 ; CHECK:       exit:
77 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 10
78 ; CHECK-NEXT:    ret i1 [[C_3]]
80 entry:
81   %c.1 = icmp ule i8 %x, 10
82   br i1 %c.1, label %then, label %else
84 then:
85   br label %exit
87 else:
88   %c.2 = icmp ule i8 %x, 10
89   call void @use(i1 %c.2)
90   br label %exit
92 exit:
93   %c.3 = icmp ugt i8 %x, 10
94   ret i1 %c.3
97 define i1 @test2(i8 %x) {
98 ; CHECK-LABEL: @test2(
99 ; CHECK-NEXT:  entry:
100 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
101 ; CHECK-NEXT:    br i1 [[C_1]], label [[BB2:%.*]], label [[BB1:%.*]]
102 ; CHECK:       bb1:
103 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 10
104 ; CHECK-NEXT:    ret i1 [[C_2]]
105 ; CHECK:       bb2:
106 ; CHECK-NEXT:    call void @use(i1 true)
107 ; CHECK-NEXT:    br label [[BB1]]
109 entry:
110   %c.1 = icmp ule i8 %x, 10
111   br i1 %c.1, label %bb2, label %bb1
113 bb1:
114   %c.2 = icmp ugt i8 %x, 10
115   ret i1 %c.2
117 bb2:
118   %c.3 = icmp ule i8 %x, 10
119   call void @use(i1 %c.3)
120   br label %bb1
123 ; Test cases where the true/false successors are not domianted by the conditional branching block.
124 define i1 @test3(i8 %x, i1 %c) {
125 ; CHECK-LABEL: @test3(
126 ; CHECK-NEXT:  entry:
127 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB_COND:%.*]], label [[BB1:%.*]]
128 ; CHECK:       bb.cond:
129 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
130 ; CHECK-NEXT:    br i1 [[C_1]], label [[BB1]], label [[BB2:%.*]]
131 ; CHECK:       bb1:
132 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 10
133 ; CHECK-NEXT:    ret i1 [[C_2]]
134 ; CHECK:       bb2:
135 ; CHECK-NEXT:    ret i1 true
137 entry:
138   br i1 %c, label %bb.cond, label %bb1
140 bb.cond:
141   %c.1 = icmp ule i8 %x, 10
142   br i1 %c.1, label %bb1, label %bb2
144 bb1:
145   %c.2 = icmp ule i8 %x, 10
146   ret i1 %c.2
148 bb2:
149   %c.3 = icmp ugt i8 %x, 10
150   ret i1 %c.3
153 define i1 @test4(i8 %x, i1 %c) {
154 ; CHECK-LABEL: @test4(
155 ; CHECK-NEXT:  entry:
156 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB_COND:%.*]], label [[BB2:%.*]]
157 ; CHECK:       bb.cond:
158 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
159 ; CHECK-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[BB2]]
160 ; CHECK:       bb1:
161 ; CHECK-NEXT:    ret i1 true
162 ; CHECK:       bb2:
163 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 10
164 ; CHECK-NEXT:    ret i1 [[C_3]]
166 entry:
167   br i1 %c, label %bb.cond, label %bb2
169 bb.cond:
170   %c.1 = icmp ule i8 %x, 10
171   br i1 %c.1, label %bb1, label %bb2
173 bb1:
174   %c.2 = icmp ule i8 %x, 10
175   ret i1 %c.2
177 bb2:
178   %c.3 = icmp ugt i8 %x, 10
179   ret i1 %c.3
183 define i1 @test_cond_from_preheader(i8 %x, i1 %c) {
184 ; CHECK-LABEL: @test_cond_from_preheader(
185 ; CHECK-NEXT:  entry:
186 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[BB2:%.*]]
187 ; CHECK:       pre:
188 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
189 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP:%.*]], label [[BB2]]
190 ; CHECK:       loop:
191 ; CHECK-NEXT:    call void @use(i1 true)
192 ; CHECK-NEXT:    call void @use(i1 false)
193 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 9
194 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
195 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 9
196 ; CHECK-NEXT:    call void @use(i1 [[C_3]])
197 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP]]
198 ; CHECK:       exit:
199 ; CHECK-NEXT:    ret i1 true
200 ; CHECK:       bb2:
201 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[X]], 10
202 ; CHECK-NEXT:    ret i1 [[C_5]]
204 entry:
205   br i1 %c, label %pre, label %bb2
207 pre:
208   %c.1 = icmp ule i8 %x, 10
209   br i1 %c.1, label %loop, label %bb2
211 loop:
212   %t.1 = icmp ule i8 %x, 10
213   call void @use(i1 %t.1)
214   %f.1 = icmp ugt i8 %x, 10
215   call void @use(i1 %f.1)
217   %c.2 = icmp ule i8 %x, 9
218   call void @use(i1 %c.2)
219   %c.3 = icmp ugt i8 %x, 9
220   call void @use(i1 %c.3)
222   br i1 true, label %exit, label %loop
224 exit:
225   %c.4 = icmp ule i8 %x, 10
226   ret i1 %c.4
228 bb2:
229   %c.5 = icmp ugt i8 %x, 10
230   ret i1 %c.5
233 define i1 @test_cond_from_preheader_successors_flipped(i8 %x, i1 %c) {
234 ; CHECK-LABEL: @test_cond_from_preheader_successors_flipped(
235 ; CHECK-NEXT:  entry:
236 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[BB2:%.*]]
237 ; CHECK:       pre:
238 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
239 ; CHECK-NEXT:    br i1 [[C_1]], label [[BB2]], label [[LOOP:%.*]]
240 ; CHECK:       loop:
241 ; CHECK-NEXT:    call void @use(i1 false)
242 ; CHECK-NEXT:    call void @use(i1 true)
243 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 11
244 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
245 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[X]], 11
246 ; CHECK-NEXT:    call void @use(i1 [[C_3]])
247 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP]]
248 ; CHECK:       exit:
249 ; CHECK-NEXT:    ret i1 false
250 ; CHECK:       bb2:
251 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[X]], 10
252 ; CHECK-NEXT:    ret i1 [[C_5]]
254 entry:
255   br i1 %c, label %pre, label %bb2
257 pre:
258   %c.1 = icmp ule i8 %x, 10
259   br i1 %c.1, label %bb2, label %loop
261 loop:
262   %f.1 = icmp ule i8 %x, 10
263   call void @use(i1 %f.1)
264   %t.1 = icmp ugt i8 %x, 10
265   call void @use(i1 %t.1)
267   %c.2 = icmp ule i8 %x, 11
268   call void @use(i1 %c.2)
269   %c.3 = icmp ugt i8 %x, 11
270   call void @use(i1 %c.3)
272   br i1 true, label %exit, label %loop
274 exit:
275   %f.2 = icmp ule i8 %x, 10
276   ret i1 %f.2
278 bb2:
279   %c.5 = icmp ugt i8 %x, 10
280   ret i1 %c.5
283 define i1 @test_cond_from_preheader_and(i8 %x, i8 %y, i1 %c) {
284 ; CHECK-LABEL: @test_cond_from_preheader_and(
285 ; CHECK-NEXT:  entry:
286 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
287 ; CHECK:       exit:
288 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[Y:%.*]], 10
289 ; CHECK-NEXT:    ret i1 [[C_5]]
290 ; CHECK:       pre:
291 ; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10
292 ; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99
293 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_1]], [[Y_1]]
294 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP:%.*]], label [[EXIT_1:%.*]]
295 ; CHECK:       loop:
296 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 true, false
297 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X]], 9
298 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_1]]
299 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 9
300 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], [[C_2]]
301 ; CHECK-NEXT:    [[R_4:%.*]] = xor i1 [[R_3]], true
302 ; CHECK-NEXT:    [[R_5:%.*]] = xor i1 [[R_4]], false
303 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i8 [[Y]], 100
304 ; CHECK-NEXT:    [[R_6:%.*]] = xor i1 [[R_5]], [[C_3]]
305 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i8 [[Y]], 100
306 ; CHECK-NEXT:    [[R_7:%.*]] = xor i1 [[R_6]], [[C_4]]
307 ; CHECK-NEXT:    call void @use(i1 [[R_7]])
308 ; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
309 ; CHECK:       exit.1:
310 ; CHECK-NEXT:    [[C_6:%.*]] = icmp ugt i8 [[Y]], 10
311 ; CHECK-NEXT:    ret i1 [[C_6]]
313 entry:
314   br i1 %c, label %pre, label %exit
316 exit:
317   %c.5 = icmp ugt i8 %y, 10
318   ret i1 %c.5
320 pre:
321   %x.1 = icmp ule i8 %x, 10
322   %y.1 = icmp ugt i8 %y, 99
323   %and = and i1 %x.1, %y.1
324   br i1 %and, label %loop, label %exit.1
326 loop:
327   %t.1 = icmp ule i8 %x, 10
328   %f.1 = icmp ugt i8 %x, 10
329   %r.1 = xor i1 %t.1, %f.1
331   %c.1 = icmp ule i8 %x, 9
332   %r.2 = xor i1 %r.1, %c.1
334   %c.2 = icmp ugt i8 %x, 9
335   %r.3 = xor i1 %r.2, %c.2
337   %t.2 = icmp ugt i8 %y, 99
338   %r.4 = xor i1 %r.3, %t.2
340   %f.2 = icmp ule i8 %y, 99
341   %r.5 = xor i1 %r.4, %f.2
343   %c.3 = icmp ugt i8 %y, 100
344   %r.6 = xor i1 %r.5, %c.3
346   %c.4 = icmp ugt i8 %y, 100
347   %r.7 = xor i1 %r.6, %c.4
348   call void @use(i1 %r.7)
350   br i1 true, label %exit, label %loop
352 exit.1:
353   %c.6 = icmp ugt i8 %y, 10
354   ret i1 %c.6
358 define i1 @test_cond_from_preheader_and_successors_flipped(i8 %x, i8 %y, i1 %c) {
359 ; CHECK-LABEL: @test_cond_from_preheader_and_successors_flipped(
360 ; CHECK-NEXT:  entry:
361 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
362 ; CHECK:       exit:
363 ; CHECK-NEXT:    [[C_9:%.*]] = icmp ugt i8 [[Y:%.*]], 10
364 ; CHECK-NEXT:    ret i1 [[C_9]]
365 ; CHECK:       pre:
366 ; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10
367 ; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99
368 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_1]], [[Y_1]]
369 ; CHECK-NEXT:    br i1 [[AND]], label [[EXIT_1:%.*]], label [[LOOP:%.*]]
370 ; CHECK:       loop:
371 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X]], 10
372 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 10
373 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 [[C_1]], [[C_2]]
374 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i8 [[X]], 9
375 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]]
376 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i8 [[X]], 9
377 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], [[C_4]]
378 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[Y]], 99
379 ; CHECK-NEXT:    [[R_4:%.*]] = xor i1 [[R_3]], [[C_5]]
380 ; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i8 [[Y]], 99
381 ; CHECK-NEXT:    [[R_5:%.*]] = xor i1 [[R_4]], [[C_6]]
382 ; CHECK-NEXT:    [[C_7:%.*]] = icmp ugt i8 [[Y]], 100
383 ; CHECK-NEXT:    [[R_6:%.*]] = xor i1 [[R_5]], [[C_7]]
384 ; CHECK-NEXT:    [[C_8:%.*]] = icmp ugt i8 [[Y]], 100
385 ; CHECK-NEXT:    [[R_7:%.*]] = xor i1 [[R_6]], [[C_8]]
386 ; CHECK-NEXT:    call void @use(i1 [[R_7]])
387 ; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
388 ; CHECK:       exit.1:
389 ; CHECK-NEXT:    ret i1 true
391 entry:
392   br i1 %c, label %pre, label %exit
394 exit:
395   %c.9 = icmp ugt i8 %y, 10
396   ret i1 %c.9
398 pre:
399   %x.1 = icmp ule i8 %x, 10
400   %y.1 = icmp ugt i8 %y, 99
401   %and = and i1 %x.1, %y.1
402   br i1 %and, label %exit.1, label %loop
404 loop:
405   %c.1 = icmp ule i8 %x, 10
406   %c.2 = icmp ugt i8 %x, 10
407   %r.1 = xor i1 %c.1, %c.2
408   %c.3 = icmp ule i8 %x, 9
409   %r.2 = xor i1 %r.1, %c.3
410   %c.4 = icmp ugt i8 %x, 9
411   %r.3 = xor i1 %r.2, %c.4
413   %c.5 = icmp ugt i8 %y, 99
414   %r.4 = xor i1 %r.3, %c.5
415   %c.6 = icmp ule i8 %y, 99
416   %r.5 = xor i1 %r.4, %c.6
418   %c.7 = icmp ugt i8 %y, 100
419   %r.6 = xor i1 %r.5, %c.7
420   %c.8 = icmp ugt i8 %y, 100
421   %r.7 = xor i1 %r.6, %c.8
422   call void @use(i1 %r.7)
424   br i1 true, label %exit, label %loop
426 exit.1:
427   %t.1 = icmp ugt i8 %y, 10
428   ret i1 %t.1
431 define i1 @test_cond_from_preheader_or(i8 %x, i8 %y, i1 %c) {
432 ; CHECK-LABEL: @test_cond_from_preheader_or(
433 ; CHECK-NEXT:  entry:
434 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
435 ; CHECK:       exit:
436 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[Y:%.*]], 10
437 ; CHECK-NEXT:    ret i1 [[C_5]]
438 ; CHECK:       pre:
439 ; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10
440 ; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99
441 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_1]], [[Y_1]]
442 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT_1:%.*]], label [[LOOP:%.*]]
443 ; CHECK:       loop:
444 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 true, false
445 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X]], 11
446 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_1]]
447 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[X]], 11
448 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], [[C_2]]
449 ; CHECK-NEXT:    [[R_4:%.*]] = xor i1 [[R_3]], true
450 ; CHECK-NEXT:    [[R_5:%.*]] = xor i1 [[R_4]], false
451 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i8 [[Y]], 98
452 ; CHECK-NEXT:    [[R_6:%.*]] = xor i1 [[R_5]], [[C_3]]
453 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ule i8 [[Y]], 98
454 ; CHECK-NEXT:    [[R_7:%.*]] = xor i1 [[R_6]], [[C_4]]
455 ; CHECK-NEXT:    call void @use(i1 [[R_7]])
456 ; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
457 ; CHECK:       exit.1:
458 ; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i8 [[Y]], 100
459 ; CHECK-NEXT:    ret i1 [[C_6]]
461 entry:
462   br i1 %c, label %pre, label %exit
464 exit:
465   %c.5 = icmp ugt i8 %y, 10
466   ret i1 %c.5
468 pre:
469   %x.1 = icmp ule i8 %x, 10
470   %y.1 = icmp ugt i8 %y, 99
471   %or = or i1 %x.1, %y.1
472   br i1 %or, label %exit.1, label %loop
474 loop:
475   %t.1 = icmp ugt i8 %x, 10
476   %f.1 = icmp ule i8 %x, 10
477   %r.1 = xor i1 %t.1, %f.1
478   %c.1 = icmp ugt i8 %x, 11
479   %r.2 = xor i1 %r.1, %c.1
480   %c.2 = icmp ule i8 %x, 11
481   %r.3 = xor i1 %r.2, %c.2
483   %t.2 = icmp ule i8 %y, 99
484   %r.4 = xor i1 %r.3, %t.2
485   %f.2 = icmp ugt i8 %y, 99
486   %r.5 = xor i1 %r.4, %f.2
488   %c.3 = icmp ule i8 %y, 98
489   %r.6 = xor i1 %r.5, %c.3
490   %c.4 = icmp ule i8 %y, 98
491   %r.7 = xor i1 %r.6, %c.4
492   call void @use(i1 %r.7)
494   br i1 true, label %exit, label %loop
496 exit.1:
497   %c.6 = icmp ule i8 %y, 100
498   ret i1 %c.6
501 define i1 @test_cond_from_preheader_or_successor_flipped(i8 %x, i8 %y, i1 %c) {
502 ; CHECK-LABEL: @test_cond_from_preheader_or_successor_flipped(
503 ; CHECK-NEXT:  entry:
504 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
505 ; CHECK:       exit:
506 ; CHECK-NEXT:    [[C_9:%.*]] = icmp ugt i8 [[Y:%.*]], 10
507 ; CHECK-NEXT:    ret i1 [[C_9]]
508 ; CHECK:       pre:
509 ; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10
510 ; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99
511 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_1]], [[Y_1]]
512 ; CHECK-NEXT:    br i1 [[OR]], label [[LOOP:%.*]], label [[EXIT_1:%.*]]
513 ; CHECK:       loop:
514 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X]], 10
515 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 10
516 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 [[C_1]], [[C_2]]
517 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i8 [[X]], 9
518 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]]
519 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i8 [[X]], 9
520 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], [[C_4]]
521 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[Y]], 99
522 ; CHECK-NEXT:    [[R_4:%.*]] = xor i1 [[R_3]], [[C_5]]
523 ; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i8 [[Y]], 99
524 ; CHECK-NEXT:    [[R_5:%.*]] = xor i1 [[R_4]], [[C_6]]
525 ; CHECK-NEXT:    [[C_7:%.*]] = icmp ugt i8 [[Y]], 100
526 ; CHECK-NEXT:    [[R_6:%.*]] = xor i1 [[R_5]], [[C_7]]
527 ; CHECK-NEXT:    [[C_8:%.*]] = icmp ugt i8 [[Y]], 100
528 ; CHECK-NEXT:    [[R_7:%.*]] = xor i1 [[R_6]], [[C_8]]
529 ; CHECK-NEXT:    call void @use(i1 [[R_7]])
530 ; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
531 ; CHECK:       exit.1:
532 ; CHECK-NEXT:    ret i1 true
534 entry:
535   br i1 %c, label %pre, label %exit
537 exit:
538   %c.9 = icmp ugt i8 %y, 10
539   ret i1 %c.9
541 pre:
542   %x.1 = icmp ule i8 %x, 10
543   %y.1 = icmp ugt i8 %y, 99
544   %or = or i1 %x.1, %y.1
545   br i1 %or, label %loop, label %exit.1
547 loop:
548   %c.1 = icmp ule i8 %x, 10
549   %c.2 = icmp ugt i8 %x, 10
550   %r.1 = xor i1 %c.1, %c.2
551   %c.3 = icmp ule i8 %x, 9
552   %r.2 = xor i1 %r.1, %c.3
553   %c.4 = icmp ugt i8 %x, 9
554   %r.3 = xor i1 %r.2, %c.4
556   %c.5 = icmp ugt i8 %y, 99
557   %r.4 = xor i1 %r.3, %c.5
558   %c.6 = icmp ule i8 %y, 99
559   %r.5 = xor i1 %r.4, %c.6
561   %c.7 = icmp ugt i8 %y, 100
562   %r.6 = xor i1 %r.5, %c.7
563   %c.8 = icmp ugt i8 %y, 100
564   %r.7 = xor i1 %r.6, %c.8
565   call void @use(i1 %r.7)
567   br i1 true, label %exit, label %loop
569 exit.1:
570   %t.1 = icmp ule i8 %y, 100
571   ret i1 %t.1
574 ; Test case from PR49819.
575 define i1 @both_branch_to_same_block(i4 %x) {
576 ; CHECK-LABEL: @both_branch_to_same_block(
577 ; CHECK-NEXT:  entry:
578 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i4 [[X:%.*]], 0
579 ; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT:%.*]], label [[EXIT]]
580 ; CHECK:       exit:
581 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i4 [[X]], 0
582 ; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i4 [[X]], 0
583 ; CHECK-NEXT:    [[RES:%.*]] = xor i1 [[C_2]], [[C_3]]
584 ; CHECK-NEXT:    ret i1 [[RES]]
586 entry:
587   %c.1 = icmp ne i4 %x, 0
588   br i1 %c.1, label %exit, label %exit
590 exit:
591   %c.2 = icmp ne i4 %x, 0
592   %c.3 = icmp eq i4 %x, 0
593   %res = xor i1 %c.2, %c.3
594   ret i1 %res
597 define i1 @both_branch_to_same_block_and(i4 %x, i4 %y) {
598 ; CHECK-LABEL: @both_branch_to_same_block_and(
599 ; CHECK-NEXT:  entry:
600 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i4 [[X:%.*]], 0
601 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i4 [[Y:%.*]], -6
602 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
603 ; CHECK-NEXT:    br i1 [[AND]], label [[EXIT:%.*]], label [[EXIT]]
604 ; CHECK:       exit:
605 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ne i4 [[X]], 0
606 ; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i4 [[X]], 0
607 ; CHECK-NEXT:    [[RES:%.*]] = xor i1 [[C_3]], [[C_4]]
608 ; CHECK-NEXT:    ret i1 [[RES]]
610 entry:
611   %c.1 = icmp ne i4 %x, 0
612   %c.2 = icmp ne i4 %y, 10
613   %and = and i1 %c.1, %c.2
614   br i1 %and, label %exit, label %exit
616 exit:
617   %c.3 = icmp ne i4 %x, 0
618   %c.4 = icmp eq i4 %x, 0
619   %res = xor i1 %c.3, %c.4
620   ret i1 %res
624 define i1 @both_branch_to_same_block_or(i4 %x, i4 %y) {
625 ; CHECK-LABEL: @both_branch_to_same_block_or(
626 ; CHECK-NEXT:  entry:
627 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i4 [[X:%.*]], 0
628 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i4 [[Y:%.*]], -6
629 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_1]], [[C_2]]
630 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[EXIT]]
631 ; CHECK:       exit:
632 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ne i4 [[X]], 0
633 ; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i4 [[X]], 0
634 ; CHECK-NEXT:    [[RES:%.*]] = xor i1 [[C_3]], [[C_4]]
635 ; CHECK-NEXT:    ret i1 [[RES]]
637 entry:
638   %c.1 = icmp ne i4 %x, 0
639   %c.2 = icmp ne i4 %y, 10
640   %or = or i1 %c.1, %c.2
641   br i1 %or, label %exit, label %exit
643 exit:
644   %c.3 = icmp ne i4 %x, 0
645   %c.4 = icmp eq i4 %x, 0
646   %res = xor i1 %c.3, %c.4
647   ret i1 %res