[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-constant-phi.ll
blobd87ed5e6192a2f00524c6e36d422a232bfd979c8
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
3 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
5 define i1 @test_eq(i1 %cond) {
6 ; CHECK-LABEL: @test_eq(
7 ; CHECK-NEXT:  entry:
8 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
9 ; CHECK:       if.true:
10 ; CHECK-NEXT:    br label [[MERGE:%.*]]
11 ; CHECK:       if.false:
12 ; CHECK-NEXT:    br label [[MERGE]]
13 ; CHECK:       merge:
14 ; CHECK-NEXT:    br label [[EXIT:%.*]]
15 ; CHECK:       exit:
16 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[COND]], true
17 ; CHECK-NEXT:    ret i1 [[TMP0]]
19 entry:
20   br i1 %cond, label %if.true, label %if.false
22 if.true:
23   br label %merge
25 if.false:
26   br label %merge
28 merge:
29   %phi = phi i32 [123, %if.true], [456, %if.false]
30   br label %exit
32 exit:
33   %compare = icmp eq i32 %phi, 456
34   ret i1 %compare
37 define i1 @test_slt(i1 %cond) {
38 ; CHECK-LABEL: @test_slt(
39 ; CHECK-NEXT:  entry:
40 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
41 ; CHECK:       if.true:
42 ; CHECK-NEXT:    br label [[MERGE:%.*]]
43 ; CHECK:       if.false:
44 ; CHECK-NEXT:    br label [[MERGE]]
45 ; CHECK:       merge:
46 ; CHECK-NEXT:    br label [[EXIT:%.*]]
47 ; CHECK:       exit:
48 ; CHECK-NEXT:    ret i1 [[COND]]
50 entry:
51   br i1 %cond, label %if.true, label %if.false
53 if.true:
54   br label %merge
56 if.false:
57   br label %merge
59 merge:
60   %phi = phi i32 [123, %if.true], [456, %if.false]
61   br label %exit
63 exit:
64   %compare = icmp slt i32 %phi, 456
65   ret i1 %compare
68 define i1 @test_sle(i1 %cond) {
69 ; CHECK-LABEL: @test_sle(
70 ; CHECK-NEXT:  entry:
71 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
72 ; CHECK:       if.true:
73 ; CHECK-NEXT:    br label [[MERGE:%.*]]
74 ; CHECK:       if.false:
75 ; CHECK-NEXT:    br label [[MERGE]]
76 ; CHECK:       merge:
77 ; CHECK-NEXT:    br label [[EXIT:%.*]]
78 ; CHECK:       exit:
79 ; CHECK-NEXT:    ret i1 true
81 entry:
82   br i1 %cond, label %if.true, label %if.false
84 if.true:
85   br label %merge
87 if.false:
88   br label %merge
90 merge:
91   %phi = phi i32 [123, %if.true], [456, %if.false]
92   br label %exit
94 exit:
95   %compare = icmp sle i32 %phi, 456
96   ret i1 %compare
99 define i1 @test_ne(i1 %cond) {
100 ; CHECK-LABEL: @test_ne(
101 ; CHECK-NEXT:  entry:
102 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
103 ; CHECK:       if.true:
104 ; CHECK-NEXT:    br label [[MERGE:%.*]]
105 ; CHECK:       if.false:
106 ; CHECK-NEXT:    br label [[MERGE]]
107 ; CHECK:       merge:
108 ; CHECK-NEXT:    br label [[EXIT:%.*]]
109 ; CHECK:       exit:
110 ; CHECK-NEXT:    ret i1 [[COND]]
112 entry:
113   br i1 %cond, label %if.true, label %if.false
115 if.true:
116   br label %merge
118 if.false:
119   br label %merge
121 merge:
122   %phi = phi i32 [123, %if.true], [456, %if.false]
123   br label %exit
125 exit:
126   %compare = icmp ne i32 %phi, 456
127   ret i1 %compare
130 define i1 @test_ne_undef(i1 %cond) {
131 ; CHECK-LABEL: @test_ne_undef(
132 ; CHECK-NEXT:  entry:
133 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
134 ; CHECK:       if.true:
135 ; CHECK-NEXT:    br label [[MERGE:%.*]]
136 ; CHECK:       if.false:
137 ; CHECK-NEXT:    br label [[MERGE]]
138 ; CHECK:       merge:
139 ; CHECK-NEXT:    br label [[EXIT:%.*]]
140 ; CHECK:       exit:
141 ; CHECK-NEXT:    ret i1 false
143 entry:
144   br i1 %cond, label %if.true, label %if.false
146 if.true:
147   br label %merge
149 if.false:
150   br label %merge
152 merge:
153   %phi = phi i32 [undef, %if.true], [456, %if.false]
154   br label %exit
156 exit:
157   %compare = icmp ne i32 %phi, 456
158   ret i1 %compare
161 define <2 x i1> @test_ne_int_vector(i1 %cond) {
162 ; CHECK-LABEL: @test_ne_int_vector(
163 ; CHECK-NEXT:  entry:
164 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
165 ; CHECK:       if.true:
166 ; CHECK-NEXT:    br label [[MERGE:%.*]]
167 ; CHECK:       if.false:
168 ; CHECK-NEXT:    br label [[MERGE]]
169 ; CHECK:       merge:
170 ; CHECK-NEXT:    [[COMPARE:%.*]] = phi <2 x i1> [ <i1 true, i1 false>, [[IF_FALSE]] ], [ <i1 false, i1 true>, [[IF_TRUE]] ]
171 ; CHECK-NEXT:    br label [[EXIT:%.*]]
172 ; CHECK:       exit:
173 ; CHECK-NEXT:    ret <2 x i1> [[COMPARE]]
175 entry:
176   br i1 %cond, label %if.true, label %if.false
178 if.true:
179   br label %merge
181 if.false:
182   br label %merge
184 merge:
185   %phi = phi <2 x i32> [<i32 123, i32 123>, %if.true], [<i32 456, i32 456>, %if.false]
186   br label %exit
188 exit:
189   %compare = icmp ne <2 x i32> %phi, <i32 123, i32 456>
190   ret <2 x i1> %compare
193 ; TODO: We can also constant-fold this comparison for floats.
194 define i1 @test_ne_float(i1 %cond) {
195 ; CHECK-LABEL: @test_ne_float(
196 ; CHECK-NEXT:  entry:
197 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
198 ; CHECK:       if.true:
199 ; CHECK-NEXT:    br label [[MERGE:%.*]]
200 ; CHECK:       if.false:
201 ; CHECK-NEXT:    br label [[MERGE]]
202 ; CHECK:       merge:
203 ; CHECK-NEXT:    [[PHI:%.*]] = phi float [ 1.000000e+00, [[IF_TRUE]] ], [ 1.250000e+00, [[IF_FALSE]] ]
204 ; CHECK-NEXT:    br label [[EXIT:%.*]]
205 ; CHECK:       exit:
206 ; CHECK-NEXT:    [[COMPARE:%.*]] = fcmp one float [[PHI]], 1.250000e+00
207 ; CHECK-NEXT:    ret i1 [[COMPARE]]
209 entry:
210   br i1 %cond, label %if.true, label %if.false
212 if.true:
213   br label %merge
215 if.false:
216   br label %merge
218 merge:
219   %phi = phi float [1.0, %if.true], [1.25, %if.false]
220   br label %exit
222 exit:
223   %compare = fcmp one float %phi, 1.25
224   ret i1 %compare
227 define i1 @test_ne_float_undef(i1 %cond) {
228 ; CHECK-LABEL: @test_ne_float_undef(
229 ; CHECK-NEXT:  entry:
230 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
231 ; CHECK:       if.true:
232 ; CHECK-NEXT:    br label [[MERGE:%.*]]
233 ; CHECK:       if.false:
234 ; CHECK-NEXT:    br label [[MERGE]]
235 ; CHECK:       merge:
236 ; CHECK-NEXT:    br label [[EXIT:%.*]]
237 ; CHECK:       exit:
238 ; CHECK-NEXT:    ret i1 true
240 entry:
241   br i1 %cond, label %if.true, label %if.false
243 if.true:
244   br label %merge
246 if.false:
247   br label %merge
249 merge:
250   %phi = phi float [1.0, %if.true], [undef, %if.false]
251   br label %exit
253 exit:
254   %compare = fcmp one float %phi, 1.25
255   ret i1 %compare
258 define <2 x i1> @test_ne_float_vector(i1 %cond) {
259 ; CHECK-LABEL: @test_ne_float_vector(
260 ; CHECK-NEXT:  entry:
261 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
262 ; CHECK:       if.true:
263 ; CHECK-NEXT:    br label [[MERGE:%.*]]
264 ; CHECK:       if.false:
265 ; CHECK-NEXT:    br label [[MERGE]]
266 ; CHECK:       merge:
267 ; CHECK-NEXT:    [[PHI:%.*]] = phi <2 x float> [ <float 1.232500e+02, float 1.232500e+02>, [[IF_TRUE]] ], [ <float 4.562500e+02, float 4.562500e+02>, [[IF_FALSE]] ]
268 ; CHECK-NEXT:    br label [[EXIT:%.*]]
269 ; CHECK:       exit:
270 ; CHECK-NEXT:    [[COMPARE:%.*]] = fcmp one <2 x float> [[PHI]], <float 1.232500e+02, float 4.562500e+02>
271 ; CHECK-NEXT:    ret <2 x i1> [[COMPARE]]
273 entry:
274   br i1 %cond, label %if.true, label %if.false
276 if.true:
277   br label %merge
279 if.false:
280   br label %merge
282 merge:
283   %phi = phi <2 x float> [<float 123.25, float 123.25>, %if.true], [<float 456.25, float 456.25>, %if.false]
284   br label %exit
286 exit:
287   %compare = fcmp one <2 x float> %phi, <float 123.25, float 456.25>
288   ret <2 x i1> %compare