[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / select-safe-bool-transforms.ll
blobfef4081c0bb6e9d0bafe0d7935e95dd4dc0e6773
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; TODO: All of these should be optimized to less than or equal to a single
5 ; instruction of select/and/or.
7 ; --- (A op B) op' A   /   (B op A) op' A ---
9 ; (A land B) land A
10 define i1 @land_land_left1(i1 %A, i1 %B) {
11 ; CHECK-LABEL: @land_land_left1(
12 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
13 ; CHECK-NEXT:    ret i1 [[C]]
15   %c = select i1 %A, i1 %B, i1 false
16   %res = select i1 %c, i1 %A, i1 false
17   ret i1 %res
19 define i1 @land_land_left2(i1 %A, i1 %B) {
20 ; CHECK-LABEL: @land_land_left2(
21 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
22 ; CHECK-NEXT:    ret i1 [[RES]]
24   %c = select i1 %B, i1 %A, i1 false
25   %res = select i1 %c, i1 %A, i1 false
26   ret i1 %res
29 ; (A land B) band A
30 define i1 @land_band_left1(i1 %A, i1 %B) {
31 ; CHECK-LABEL: @land_band_left1(
32 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
33 ; CHECK-NEXT:    ret i1 [[C]]
35   %c = select i1 %A, i1 %B, i1 false
36   %res = and i1 %c, %A
37   ret i1 %res
39 define i1 @land_band_left2(i1 %A, i1 %B) {
40 ; CHECK-LABEL: @land_band_left2(
41 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
42 ; CHECK-NEXT:    ret i1 [[C]]
44   %c = select i1 %B, i1 %A, i1 false
45   %res = and i1 %c, %A
46   ret i1 %res
49 ; (A land B) lor A
50 define i1 @land_lor_left1(i1 %A, i1 %B) {
51 ; CHECK-LABEL: @land_lor_left1(
52 ; CHECK-NEXT:    ret i1 [[A:%.*]]
54   %c = select i1 %A, i1 %B, i1 false
55   %res = select i1 %c, i1 true, i1 %A
56   ret i1 %res
58 define i1 @land_lor_left2(i1 %A, i1 %B) {
59 ; CHECK-LABEL: @land_lor_left2(
60 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
61 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C]], i1 true, i1 [[A]]
62 ; CHECK-NEXT:    ret i1 [[RES]]
64   %c = select i1 %B, i1 %A, i1 false
65   %res = select i1 %c, i1 true, i1 %A
66   ret i1 %res
69 ; (A land B) bor A
70 define i1 @land_bor_left1(i1 %A, i1 %B) {
71 ; CHECK-LABEL: @land_bor_left1(
72 ; CHECK-NEXT:    ret i1 [[A:%.*]]
74   %c = select i1 %A, i1 %B, i1 false
75   %res = or i1 %c, %A
76   ret i1 %res
78 define i1 @land_bor_left2(i1 %A, i1 %B) {
79 ; CHECK-LABEL: @land_bor_left2(
80 ; CHECK-NEXT:    ret i1 [[A:%.*]]
82   %c = select i1 %B, i1 %A, i1 false
83   %res = or i1 %c, %A
84   ret i1 %res
87 ; (A band B) land A
88 define i1 @band_land_left1(i1 %A, i1 %B) {
89 ; CHECK-LABEL: @band_land_left1(
90 ; CHECK-NEXT:    [[C:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
91 ; CHECK-NEXT:    ret i1 [[C]]
93   %c = and i1 %A, %B
94   %res = select i1 %c, i1 %A, i1 false
95   ret i1 %res
97 define i1 @band_land_left2(i1 %A, i1 %B) {
98 ; CHECK-LABEL: @band_land_left2(
99 ; CHECK-NEXT:    [[C:%.*]] = and i1 [[B:%.*]], [[A:%.*]]
100 ; CHECK-NEXT:    ret i1 [[C]]
102   %c = and i1 %B, %A
103   %res = select i1 %c, i1 %A, i1 false
104   ret i1 %res
107 ; (A band B) lor A
108 define i1 @band_lor_left1(i1 %A, i1 %B) {
109 ; CHECK-LABEL: @band_lor_left1(
110 ; CHECK-NEXT:    ret i1 [[A:%.*]]
112   %c = and i1 %A, %B
113   %res = select i1 %c, i1 true, i1 %A
114   ret i1 %res
116 define i1 @band_lor_left2(i1 %A, i1 %B) {
117 ; CHECK-LABEL: @band_lor_left2(
118 ; CHECK-NEXT:    ret i1 [[A:%.*]]
120   %c = and i1 %B, %A
121   %res = select i1 %c, i1 true, i1 %A
122   ret i1 %res
125 ; (A lor B) land A
126 define i1 @lor_land_left1(i1 %A, i1 %B) {
127 ; CHECK-LABEL: @lor_land_left1(
128 ; CHECK-NEXT:    ret i1 [[A:%.*]]
130   %c = select i1 %A, i1 true, i1 %B
131   %res = select i1 %c, i1 %A, i1 false
132   ret i1 %res
134 define i1 @lor_land_left2(i1 %A, i1 %B) {
135 ; CHECK-LABEL: @lor_land_left2(
136 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
137 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C]], i1 [[A]], i1 false
138 ; CHECK-NEXT:    ret i1 [[RES]]
140   %c = select i1 %B, i1 true, i1 %A
141   %res = select i1 %c, i1 %A, i1 false
142   ret i1 %res
145 ; (A lor B) band A
146 define i1 @lor_band_left1(i1 %A, i1 %B) {
147 ; CHECK-LABEL: @lor_band_left1(
148 ; CHECK-NEXT:    ret i1 [[A:%.*]]
150   %c = select i1 %A, i1 true, i1 %B
151   %res = and i1 %c, %A
152   ret i1 %res
154 define i1 @lor_band_left2(i1 %A, i1 %B) {
155 ; CHECK-LABEL: @lor_band_left2(
156 ; CHECK-NEXT:    ret i1 [[A:%.*]]
158   %c = select i1 %B, i1 true, i1 %A
159   %res = and i1 %c, %A
160   ret i1 %res
163 ; (A lor B) lor A
164 define i1 @lor_lor_left1(i1 %A, i1 %B) {
165 ; CHECK-LABEL: @lor_lor_left1(
166 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
167 ; CHECK-NEXT:    ret i1 [[C]]
169   %c = select i1 %A, i1 true, i1 %B
170   %res = select i1 %c, i1 true, i1 %A
171   ret i1 %res
173 define i1 @lor_lor_left2(i1 %A, i1 %B) {
174 ; CHECK-LABEL: @lor_lor_left2(
175 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
176 ; CHECK-NEXT:    ret i1 [[RES]]
178   %c = select i1 %B, i1 true, i1 %A
179   %res = select i1 %c, i1 true, i1 %A
180   ret i1 %res
183 ; (A lor B) bor A
184 define i1 @lor_bor_left1(i1 %A, i1 %B) {
185 ; CHECK-LABEL: @lor_bor_left1(
186 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
187 ; CHECK-NEXT:    ret i1 [[C]]
189   %c = select i1 %A, i1 true, i1 %B
190   %res = or i1 %c, %A
191   ret i1 %res
193 define i1 @lor_bor_left2(i1 %A, i1 %B) {
194 ; CHECK-LABEL: @lor_bor_left2(
195 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
196 ; CHECK-NEXT:    ret i1 [[C]]
198   %c = select i1 %B, i1 true, i1 %A
199   %res = or i1 %c, %A
200   ret i1 %res
203 ; (A bor B) land A
204 define i1 @bor_land_left1(i1 %A, i1 %B) {
205 ; CHECK-LABEL: @bor_land_left1(
206 ; CHECK-NEXT:    ret i1 [[A:%.*]]
208   %c = or i1 %A, %B
209   %res = select i1 %c, i1 %A, i1 false
210   ret i1 %res
212 define i1 @bor_land_left2(i1 %A, i1 %B) {
213 ; CHECK-LABEL: @bor_land_left2(
214 ; CHECK-NEXT:    ret i1 [[A:%.*]]
216   %c = or i1 %B, %A
217   %res = select i1 %c, i1 %A, i1 false
218   ret i1 %res
221 ; (A bor B) lor A
222 define i1 @bor_lor_left1(i1 %A, i1 %B) {
223 ; CHECK-LABEL: @bor_lor_left1(
224 ; CHECK-NEXT:    [[C:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
225 ; CHECK-NEXT:    ret i1 [[C]]
227   %c = or i1 %A, %B
228   %res = select i1 %c, i1 true, i1 %A
229   ret i1 %res
231 define i1 @bor_lor_left2(i1 %A, i1 %B) {
232 ; CHECK-LABEL: @bor_lor_left2(
233 ; CHECK-NEXT:    [[C:%.*]] = or i1 [[B:%.*]], [[A:%.*]]
234 ; CHECK-NEXT:    ret i1 [[C]]
236   %c = or i1 %B, %A
237   %res = select i1 %c, i1 true, i1 %A
238   ret i1 %res
241 ; --- A op (A op' B)   /   A op (B op' A) ---
243 ; A land (A land B)
244 define i1 @land_land_right1(i1 %A, i1 %B) {
245 ; CHECK-LABEL: @land_land_right1(
246 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
247 ; CHECK-NEXT:    ret i1 [[RES]]
249   %c = select i1 %A, i1 %B, i1 false
250   %res = select i1 %A, i1 %c, i1 false
251   ret i1 %res
253 define i1 @land_land_right2(i1 %A, i1 %B) {
254 ; CHECK-LABEL: @land_land_right2(
255 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
256 ; CHECK-NEXT:    ret i1 [[RES]]
258   %c = select i1 %B, i1 %A, i1 false
259   %res = select i1 %A, i1 %c, i1 false
260   ret i1 %res
263 ; A band (A land B)
264 define i1 @land_band_right1(i1 %A, i1 %B) {
265 ; CHECK-LABEL: @land_band_right1(
266 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
267 ; CHECK-NEXT:    ret i1 [[C]]
269   %c = select i1 %A, i1 %B, i1 false
270   %res = and i1 %A, %c
271   ret i1 %res
273 define i1 @land_band_right2(i1 %A, i1 %B) {
274 ; CHECK-LABEL: @land_band_right2(
275 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
276 ; CHECK-NEXT:    ret i1 [[C]]
278   %c = select i1 %B, i1 %A, i1 false
279   %res = and i1 %A, %c
280   ret i1 %res
283 ; A lor (A land B)
284 define i1 @land_lor_right1(i1 %A, i1 %B) {
285 ; CHECK-LABEL: @land_lor_right1(
286 ; CHECK-NEXT:    ret i1 [[A:%.*]]
288   %c = select i1 %A, i1 %B, i1 false
289   %res = select i1 %A, i1 true, i1 %c
290   ret i1 %res
292 define i1 @land_lor_right2(i1 %A, i1 %B) {
293 ; CHECK-LABEL: @land_lor_right2(
294 ; CHECK-NEXT:    ret i1 [[A:%.*]]
296   %c = select i1 %B, i1 %A, i1 false
297   %res = select i1 %A, i1 true, i1 %c
298   ret i1 %res
301 ; A bor (A land B)
302 define i1 @land_bor_right1(i1 %A, i1 %B) {
303 ; CHECK-LABEL: @land_bor_right1(
304 ; CHECK-NEXT:    ret i1 [[A:%.*]]
306   %c = select i1 %A, i1 %B, i1 false
307   %res = or i1 %A, %c
308   ret i1 %res
310 define i1 @land_bor_right2(i1 %A, i1 %B) {
311 ; CHECK-LABEL: @land_bor_right2(
312 ; CHECK-NEXT:    ret i1 [[A:%.*]]
314   %c = select i1 %B, i1 %A, i1 false
315   %res = or i1 %A, %c
316   ret i1 %res
319 ; A land (A band B)
320 define i1 @band_land_right1(i1 %A, i1 %B) {
321 ; CHECK-LABEL: @band_land_right1(
322 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
323 ; CHECK-NEXT:    ret i1 [[RES]]
325   %c = and i1 %A, %B
326   %res = select i1 %A, i1 %c, i1 false
327   ret i1 %res
329 define i1 @band_land_right2(i1 %A, i1 %B) {
330 ; CHECK-LABEL: @band_land_right2(
331 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
332 ; CHECK-NEXT:    ret i1 [[RES]]
334   %c = and i1 %B, %A
335   %res = select i1 %A, i1 %c, i1 false
336   ret i1 %res
339 ; A lor (A band B)
340 define i1 @band_lor_right1(i1 %A, i1 %B) {
341 ; CHECK-LABEL: @band_lor_right1(
342 ; CHECK-NEXT:    ret i1 [[A:%.*]]
344   %c = and i1 %A, %B
345   %res = select i1 %A, i1 true, i1 %c
346   ret i1 %res
348 define i1 @band_lor_right2(i1 %A, i1 %B) {
349 ; CHECK-LABEL: @band_lor_right2(
350 ; CHECK-NEXT:    ret i1 [[A:%.*]]
352   %c = and i1 %B, %A
353   %res = select i1 %A, i1 true, i1 %c
354   ret i1 %res
357 ; A land (A lor B)
358 define i1 @lor_land_right1(i1 %A, i1 %B) {
359 ; CHECK-LABEL: @lor_land_right1(
360 ; CHECK-NEXT:    ret i1 [[A:%.*]]
362   %c = select i1 %A, i1 true, i1 %B
363   %res = select i1 %A, i1 %c, i1 false
364   ret i1 %res
366 define i1 @lor_land_right2(i1 %A, i1 %B) {
367 ; CHECK-LABEL: @lor_land_right2(
368 ; CHECK-NEXT:    ret i1 [[A:%.*]]
370   %c = select i1 %B, i1 true, i1 %A
371   %res = select i1 %A, i1 %c, i1 false
372   ret i1 %res
375 ; A band (A lor B)
376 define i1 @lor_band_right1(i1 %A, i1 %B) {
377 ; CHECK-LABEL: @lor_band_right1(
378 ; CHECK-NEXT:    ret i1 [[A:%.*]]
380   %c = select i1 %A, i1 true, i1 %B
381   %res = and i1 %A, %c
382   ret i1 %res
384 define i1 @lor_band_right2(i1 %A, i1 %B) {
385 ; CHECK-LABEL: @lor_band_right2(
386 ; CHECK-NEXT:    ret i1 [[A:%.*]]
388   %c = select i1 %B, i1 true, i1 %A
389   %res = and i1 %A, %c
390   ret i1 %res
393 ; A lor (A lor B)
394 define i1 @lor_lor_right1(i1 %A, i1 %B) {
395 ; CHECK-LABEL: @lor_lor_right1(
396 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
397 ; CHECK-NEXT:    ret i1 [[RES]]
399   %c = select i1 %A, i1 true, i1 %B
400   %res = select i1 %A, i1 true, i1 %c
401   ret i1 %res
403 define i1 @lor_lor_right2(i1 %A, i1 %B) {
404 ; CHECK-LABEL: @lor_lor_right2(
405 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
406 ; CHECK-NEXT:    ret i1 [[RES]]
408   %c = select i1 %B, i1 true, i1 %A
409   %res = select i1 %A, i1 true, i1 %c
410   ret i1 %res
413 ; A bor (A lor B)
414 define i1 @lor_bor_right1(i1 %A, i1 %B) {
415 ; CHECK-LABEL: @lor_bor_right1(
416 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
417 ; CHECK-NEXT:    ret i1 [[C]]
419   %c = select i1 %A, i1 true, i1 %B
420   %res = or i1 %A, %c
421   ret i1 %res
423 define i1 @lor_bor_right2(i1 %A, i1 %B) {
424 ; CHECK-LABEL: @lor_bor_right2(
425 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
426 ; CHECK-NEXT:    ret i1 [[C]]
428   %c = select i1 %B, i1 true, i1 %A
429   %res = or i1 %A, %c
430   ret i1 %res
433 ; A land (A bor B)
434 define i1 @bor_land_right1(i1 %A, i1 %B) {
435 ; CHECK-LABEL: @bor_land_right1(
436 ; CHECK-NEXT:    ret i1 [[A:%.*]]
438   %c = or i1 %A, %B
439   %res = select i1 %A, i1 %c, i1 false
440   ret i1 %res
442 define i1 @bor_land_right2(i1 %A, i1 %B) {
443 ; CHECK-LABEL: @bor_land_right2(
444 ; CHECK-NEXT:    ret i1 [[A:%.*]]
446   %c = or i1 %B, %A
447   %res = select i1 %A, i1 %c, i1 false
448   ret i1 %res
451 ; A lor (A bor B)
452 define i1 @bor_lor_right1(i1 %A, i1 %B) {
453 ; CHECK-LABEL: @bor_lor_right1(
454 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
455 ; CHECK-NEXT:    ret i1 [[RES]]
457   %c = or i1 %A, %B
458   %res = select i1 %A, i1 true, i1 %c
459   ret i1 %res
461 define i1 @bor_lor_right2(i1 %A, i1 %B) {
462 ; CHECK-LABEL: @bor_lor_right2(
463 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
464 ; CHECK-NEXT:    ret i1 [[RES]]
466   %c = or i1 %B, %A
467   %res = select i1 %A, i1 true, i1 %c
468   ret i1 %res
471 ; Value equivalence substitution does not account for vector
472 ; transforms, so it needs a scalar condition operand.
473 ; For example, this would miscompile if %a = {1, 0}.
475 define <2 x i1> @PR50500_trueval(<2 x i1> %a, <2 x i1> %b) {
476 ; CHECK-LABEL: @PR50500_trueval(
477 ; CHECK-NEXT:    [[S:%.*]] = shufflevector <2 x i1> [[A:%.*]], <2 x i1> poison, <2 x i32> <i32 1, i32 0>
478 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[S]], <2 x i1> [[B:%.*]]
479 ; CHECK-NEXT:    ret <2 x i1> [[R]]
481   %s = shufflevector <2 x i1> %a, <2 x i1> poison, <2 x i32> <i32 1, i32 0>
482   %r = select <2 x i1> %a, <2 x i1> %s, <2 x i1> %b
483   ret <2 x i1> %r
486 define <2 x i1> @PR50500_falseval(<2 x i1> %a, <2 x i1> %b) {
487 ; CHECK-LABEL: @PR50500_falseval(
488 ; CHECK-NEXT:    [[S:%.*]] = shufflevector <2 x i1> [[A:%.*]], <2 x i1> poison, <2 x i32> <i32 1, i32 0>
489 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[B:%.*]], <2 x i1> [[S]]
490 ; CHECK-NEXT:    ret <2 x i1> [[R]]
492   %s = shufflevector <2 x i1> %a, <2 x i1> poison, <2 x i32> <i32 1, i32 0>
493   %r = select <2 x i1> %a, <2 x i1> %b, <2 x i1> %s
494   ret <2 x i1> %r