[RISCV] Reduce redundancy in vnsrl tests
[llvm-project.git] / llvm / test / Transforms / InstCombine / branch.ll
blob1d5ff72eef9ce613bd0f34522b3f7b3b72c39b8f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
4 declare void @use(i1)
6 ; Check that we fold the condition of branches of the
7 ; form: br <condition> dest1, dest2, where dest1 == dest2.
8 define i32 @test(i32 %x) {
9 ; CHECK-LABEL: @test(
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    br i1 false, label [[MERGE:%.*]], label [[MERGE]]
12 ; CHECK:       merge:
13 ; CHECK-NEXT:    ret i32 [[X:%.*]]
15 entry:
16   %cmp = icmp ult i32 %x, 7
17   br i1 %cmp, label %merge, label %merge
18 merge:
19   ret i32 %x
22 @global = global i8 0
24 define i32 @pat(i32 %x) {
25 ; CHECK-LABEL: @pat(
26 ; CHECK-NEXT:    br i1 false, label [[PATATINO:%.*]], label [[PATATINO]]
27 ; CHECK:       patatino:
28 ; CHECK-NEXT:    ret i32 [[X:%.*]]
30   %y = icmp eq i32 27, ptrtoint(ptr @global to i32)
31   br i1 %y, label %patatino, label %patatino
32 patatino:
33   ret i32 %x
36 define i1 @test01(i1 %cond) {
37 ; CHECK-LABEL: @test01(
38 ; CHECK-NEXT:  entry:
39 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]]
40 ; CHECK:       if.true.1:
41 ; CHECK-NEXT:    br label [[MERGE_1:%.*]]
42 ; CHECK:       if.false.1:
43 ; CHECK-NEXT:    br label [[MERGE_1]]
44 ; CHECK:       merge.1:
45 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]]
46 ; CHECK:       if.true.2:
47 ; CHECK-NEXT:    br label [[MERGE_2:%.*]]
48 ; CHECK:       if.false.2:
49 ; CHECK-NEXT:    br label [[MERGE_2]]
50 ; CHECK:       merge.2:
51 ; CHECK-NEXT:    ret i1 [[COND]]
53 entry:
54   br i1 %cond, label %if.true.1, label %if.false.1
56 if.true.1:
57   br label %merge.1
59 if.false.1:
60   br label  %merge.1
62 merge.1:
63   %merge.cond.1 = phi i1 [true, %if.true.1], [false, %if.false.1]
64   br i1 %merge.cond.1, label %if.true.2, label %if.false.2
66 if.true.2:
67   br label %merge.2
69 if.false.2:
70   br label  %merge.2
72 merge.2:
73   %merge.cond.2 = phi i1 [true, %if.true.2], [false, %if.false.2]
74   ret i1 %merge.cond.2
77 define i1 @test02(i1 %cond) {
78 ; CHECK-LABEL: @test02(
79 ; CHECK-NEXT:  entry:
80 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]]
81 ; CHECK:       if.true.1:
82 ; CHECK-NEXT:    br label [[MERGE_1:%.*]]
83 ; CHECK:       if.false.1:
84 ; CHECK-NEXT:    br label [[MERGE_1]]
85 ; CHECK:       merge.1:
86 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_FALSE_2:%.*]], label [[IF_TRUE_2:%.*]]
87 ; CHECK:       if.true.2:
88 ; CHECK-NEXT:    br label [[MERGE_2:%.*]]
89 ; CHECK:       if.false.2:
90 ; CHECK-NEXT:    br label [[MERGE_2]]
91 ; CHECK:       merge.2:
92 ; CHECK-NEXT:    ret i1 [[COND]]
94 entry:
95   br i1 %cond, label %if.true.1, label %if.false.1
97 if.true.1:
98   br label %merge.1
100 if.false.1:
101   br label  %merge.1
103 merge.1:
104   %merge.cond.1 = phi i1 [false, %if.true.1], [true, %if.false.1]
105   br i1 %merge.cond.1, label %if.true.2, label %if.false.2
107 if.true.2:
108   br label %merge.2
110 if.false.2:
111   br label  %merge.2
113 merge.2:
114   %merge.cond.2 = phi i1 [false, %if.true.2], [true, %if.false.2]
115   ret i1 %merge.cond.2
118 ; if (x && !y) ret 42; ret 3 --> if (!x || y) ret 3; ret 42
120 define i32 @logical_and_not(i1 %x, i1 %y) {
121 ; CHECK-LABEL: @logical_and_not(
122 ; CHECK-NEXT:  entry:
123 ; CHECK-NEXT:    [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
124 ; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[Y:%.*]]
125 ; CHECK-NEXT:    br i1 [[TMP0]], label [[F:%.*]], label [[T:%.*]]
126 ; CHECK:       t:
127 ; CHECK-NEXT:    ret i32 42
128 ; CHECK:       f:
129 ; CHECK-NEXT:    ret i32 3
131 entry:
132   %noty = xor i1 %y, true
133   %and = select i1 %x, i1 %noty, i1 false
134   br i1 %and, label %t, label %f
137   ret i32 42
140   ret i32 3
143 ; if (x && y || !x) ret 3; ret 42 --> if (!x || y) ret 3; ret 42
145 define i32 @logical_and_or(i1 %x, i1 %y) {
146 ; CHECK-LABEL: @logical_and_or(
147 ; CHECK-NEXT:  entry:
148 ; CHECK-NEXT:    [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
149 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[Y:%.*]]
150 ; CHECK-NEXT:    br i1 [[AND]], label [[F:%.*]], label [[T:%.*]]
151 ; CHECK:       t:
152 ; CHECK-NEXT:    ret i32 42
153 ; CHECK:       f:
154 ; CHECK-NEXT:    ret i32 3
156 entry:
157   %and = select i1 %x, i1 %y, i1 true
158   br i1 %and, label %f, label %t
161   ret i32 42
164   ret i32 3
167 ; if (!x || y) ret 3; ret 42
169 define i32 @logical_or_not(i1 %x, i1 %y) {
170 ; CHECK-LABEL: @logical_or_not(
171 ; CHECK-NEXT:  entry:
172 ; CHECK-NEXT:    [[NOTX:%.*]] = xor i1 [[X:%.*]], true
173 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[NOTX]], i1 true, i1 [[Y:%.*]]
174 ; CHECK-NEXT:    br i1 [[AND]], label [[F:%.*]], label [[T:%.*]]
175 ; CHECK:       t:
176 ; CHECK-NEXT:    ret i32 42
177 ; CHECK:       f:
178 ; CHECK-NEXT:    ret i32 3
180 entry:
181   %notx = xor i1 %x, true
182   %and = select i1 %notx, i1 true, i1 %y
183   br i1 %and, label %f, label %t
186   ret i32 42
189   ret i32 3
192 ; negative test
194 define i32 @logical_and_not_use1(i1 %x, i1 %y) {
195 ; CHECK-LABEL: @logical_and_not_use1(
196 ; CHECK-NEXT:  entry:
197 ; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
198 ; CHECK-NEXT:    call void @use(i1 [[NOTY]])
199 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false
200 ; CHECK-NEXT:    br i1 [[AND]], label [[T:%.*]], label [[F:%.*]]
201 ; CHECK:       t:
202 ; CHECK-NEXT:    ret i32 42
203 ; CHECK:       f:
204 ; CHECK-NEXT:    ret i32 3
206 entry:
207   %noty = xor i1 %y, true
208   call void @use(i1 %noty)
209   %and = select i1 %x, i1 %noty, i1 false
210   br i1 %and, label %t, label %f
213   ret i32 42
216   ret i32 3
219 ; negative test
221 define i32 @logical_and_not_use2(i1 %x, i1 %y) {
222 ; CHECK-LABEL: @logical_and_not_use2(
223 ; CHECK-NEXT:  entry:
224 ; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
225 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false
226 ; CHECK-NEXT:    call void @use(i1 [[AND]])
227 ; CHECK-NEXT:    br i1 [[AND]], label [[T:%.*]], label [[F:%.*]]
228 ; CHECK:       t:
229 ; CHECK-NEXT:    ret i32 42
230 ; CHECK:       f:
231 ; CHECK-NEXT:    ret i32 3
233 entry:
234   %noty = xor i1 %y, true
235   %and = select i1 %x, i1 %noty, i1 false
236   call void @use(i1 %and)
237   br i1 %and, label %t, label %f
240   ret i32 42
243   ret i32 3
246 define i32 @dom_true(i1 %cmp) {
247 ; CHECK-LABEL: @dom_true(
248 ; CHECK-NEXT:    br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
249 ; CHECK:       if.then:
250 ; CHECK-NEXT:    ret i32 1
251 ; CHECK:       if.else:
252 ; CHECK-NEXT:    ret i32 0
254   br i1 %cmp, label %if.then, label %if.else
256 if.then:
257   %zext = zext i1 %cmp to i32
258   ret i32 %zext
260 if.else:
261   ret i32 0
264 define i32 @dom_false(i1 %cmp) {
265 ; CHECK-LABEL: @dom_false(
266 ; CHECK-NEXT:    br i1 [[CMP:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
267 ; CHECK:       if.then:
268 ; CHECK-NEXT:    ret i32 0
269 ; CHECK:       if.else:
270 ; CHECK-NEXT:    ret i32 0
272   br i1 %cmp, label %if.else, label %if.then
274 if.then:
275   %zext = zext i1 %cmp to i32
276   ret i32 %zext
278 if.else:
279   ret i32 0
282 define i32 @dom_true_phi(i1 %cmp) {
283 ; CHECK-LABEL: @dom_true_phi(
284 ; CHECK-NEXT:    br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
285 ; CHECK:       if.then:
286 ; CHECK-NEXT:    br label [[IF_END:%.*]]
287 ; CHECK:       if.else:
288 ; CHECK-NEXT:    br label [[IF_END]]
289 ; CHECK:       if.end:
290 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
291 ; CHECK-NEXT:    ret i32 [[ZEXT]]
293   br i1 %cmp, label %if.then, label %if.else
295 if.then:
296   br label %if.end
298 if.else:
299   br label %if.end
301 if.end:
302   %phi = phi i1 [ true, %if.then ], [ %cmp, %if.else ]
303   %zext = zext i1 %phi to i32
304   ret i32 %zext
307 ; Negative tests
309 define i32 @same_dest(i1 %cmp) {
310 ; CHECK-LABEL: @same_dest(
311 ; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_THEN]]
312 ; CHECK:       if.then:
313 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP:%.*]] to i32
314 ; CHECK-NEXT:    ret i32 [[ZEXT]]
316   br i1 %cmp, label %if.then, label %if.then
318 if.then:
319   %zext = zext i1 %cmp to i32
320   ret i32 %zext
323 define i32 @not_dom(i1 %cmp) {
324 ; CHECK-LABEL: @not_dom(
325 ; CHECK-NEXT:    br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
326 ; CHECK:       if.then:
327 ; CHECK-NEXT:    br label [[IF_ELSE]]
328 ; CHECK:       if.else:
329 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
330 ; CHECK-NEXT:    ret i32 [[ZEXT]]
332   br i1 %cmp, label %if.then, label %if.else
334 if.then:
335   br label %if.else
337 if.else:
338   %zext = zext i1 %cmp to i32
339   ret i32 %zext