xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/dom.ll (revision 13ffde316a8541d77116bd18f73efada236617f3)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4; Test cases where both the true and false successors reach the same block,
5; dominated by one of them.
6
7declare void @use(i1)
8
9define 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]]
20;
21entry:
22  %c.1 = icmp ule i8 %x, 10
23  br i1 %c.1, label %bb1, label %bb2
24
25bb1:
26  %c.2 = icmp ule i8 %x, 10
27  call void @use(i1 %c.2)
28  br label %bb2
29
30bb2:
31  %c.3 = icmp ugt i8 %x, 10
32  ret i1 %c.3
33}
34
35define 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]]
48;
49entry:
50  %c.1 = icmp ule i8 %x, 10
51  br i1 %c.1, label %then, label %else
52
53then:
54  %c.2 = icmp ule i8 %x, 10
55  call void @use(i1 %c.2)
56  br label %exit
57
58else:
59  br label %exit
60
61exit:
62  %c.3 = icmp ugt i8 %x, 10
63  ret i1 %c.3
64}
65
66define 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]]
79;
80entry:
81  %c.1 = icmp ule i8 %x, 10
82  br i1 %c.1, label %then, label %else
83
84then:
85  br label %exit
86
87else:
88  %c.2 = icmp ule i8 %x, 10
89  call void @use(i1 %c.2)
90  br label %exit
91
92exit:
93  %c.3 = icmp ugt i8 %x, 10
94  ret i1 %c.3
95}
96
97define 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]]
108;
109entry:
110  %c.1 = icmp ule i8 %x, 10
111  br i1 %c.1, label %bb2, label %bb1
112
113bb1:
114  %c.2 = icmp ugt i8 %x, 10
115  ret i1 %c.2
116
117bb2:
118  %c.3 = icmp ule i8 %x, 10
119  call void @use(i1 %c.3)
120  br label %bb1
121}
122
123; Test cases where the true/false successors are not domianted by the conditional branching block.
124define 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
136;
137entry:
138  br i1 %c, label %bb.cond, label %bb1
139
140bb.cond:
141  %c.1 = icmp ule i8 %x, 10
142  br i1 %c.1, label %bb1, label %bb2
143
144bb1:
145  %c.2 = icmp ule i8 %x, 10
146  ret i1 %c.2
147
148bb2:
149  %c.3 = icmp ugt i8 %x, 10
150  ret i1 %c.3
151}
152
153define 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]]
165;
166entry:
167  br i1 %c, label %bb.cond, label %bb2
168
169bb.cond:
170  %c.1 = icmp ule i8 %x, 10
171  br i1 %c.1, label %bb1, label %bb2
172
173bb1:
174  %c.2 = icmp ule i8 %x, 10
175  ret i1 %c.2
176
177bb2:
178  %c.3 = icmp ugt i8 %x, 10
179  ret i1 %c.3
180}
181
182
183define 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]]
203;
204entry:
205  br i1 %c, label %pre, label %bb2
206
207pre:
208  %c.1 = icmp ule i8 %x, 10
209  br i1 %c.1, label %loop, label %bb2
210
211loop:
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)
216
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)
221
222  br i1 true, label %exit, label %loop
223
224exit:
225  %c.4 = icmp ule i8 %x, 10
226  ret i1 %c.4
227
228bb2:
229  %c.5 = icmp ugt i8 %x, 10
230  ret i1 %c.5
231}
232
233define 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]]
253;
254entry:
255  br i1 %c, label %pre, label %bb2
256
257pre:
258  %c.1 = icmp ule i8 %x, 10
259  br i1 %c.1, label %bb2, label %loop
260
261loop:
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)
266
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)
271
272  br i1 true, label %exit, label %loop
273
274exit:
275  %f.2 = icmp ule i8 %x, 10
276  ret i1 %f.2
277
278bb2:
279  %c.5 = icmp ugt i8 %x, 10
280  ret i1 %c.5
281}
282
283define 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]]
312;
313entry:
314  br i1 %c, label %pre, label %exit
315
316exit:
317  %c.5 = icmp ugt i8 %y, 10
318  ret i1 %c.5
319
320pre:
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
325
326loop:
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
330
331  %c.1 = icmp ule i8 %x, 9
332  %r.2 = xor i1 %r.1, %c.1
333
334  %c.2 = icmp ugt i8 %x, 9
335  %r.3 = xor i1 %r.2, %c.2
336
337  %t.2 = icmp ugt i8 %y, 99
338  %r.4 = xor i1 %r.3, %t.2
339
340  %f.2 = icmp ule i8 %y, 99
341  %r.5 = xor i1 %r.4, %f.2
342
343  %c.3 = icmp ugt i8 %y, 100
344  %r.6 = xor i1 %r.5, %c.3
345
346  %c.4 = icmp ugt i8 %y, 100
347  %r.7 = xor i1 %r.6, %c.4
348  call void @use(i1 %r.7)
349
350  br i1 true, label %exit, label %loop
351
352exit.1:
353  %c.6 = icmp ugt i8 %y, 10
354  ret i1 %c.6
355}
356
357
358define 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
390;
391entry:
392  br i1 %c, label %pre, label %exit
393
394exit:
395  %c.9 = icmp ugt i8 %y, 10
396  ret i1 %c.9
397
398pre:
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
403
404loop:
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
412
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
417
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)
423
424  br i1 true, label %exit, label %loop
425
426exit.1:
427  %t.1 = icmp ugt i8 %y, 10
428  ret i1 %t.1
429}
430
431define 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]]
460;
461entry:
462  br i1 %c, label %pre, label %exit
463
464exit:
465  %c.5 = icmp ugt i8 %y, 10
466  ret i1 %c.5
467
468pre:
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
473
474loop:
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
482
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
487
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)
493
494  br i1 true, label %exit, label %loop
495
496exit.1:
497  %c.6 = icmp ule i8 %y, 100
498  ret i1 %c.6
499}
500
501define 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
533;
534entry:
535  br i1 %c, label %pre, label %exit
536
537exit:
538  %c.9 = icmp ugt i8 %y, 10
539  ret i1 %c.9
540
541pre:
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
546
547loop:
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
555
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
560
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)
566
567  br i1 true, label %exit, label %loop
568
569exit.1:
570  %t.1 = icmp ule i8 %y, 100
571  ret i1 %t.1
572}
573
574; Test case from PR49819.
575define 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]]
585;
586entry:
587  %c.1 = icmp ne i4 %x, 0
588  br i1 %c.1, label %exit, label %exit
589
590exit:
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
595}
596
597define 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]]
609;
610entry:
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
615
616exit:
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
621}
622
623
624define 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]]
636;
637entry:
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
642
643exit:
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
648}
649