Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / branch.ll
blob1110d5f90b1790cb465587ccf90e112827aba143
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