1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instsimplify -S | FileCheck %s
3
4define <2 x i8> @vsel_tvec(<2 x i8> %x, <2 x i8> %y) {
5; CHECK-LABEL: @vsel_tvec(
6; CHECK-NEXT:    ret <2 x i8> %x
7;
8  %s = select <2 x i1><i1 true, i1 true>, <2 x i8> %x, <2 x i8> %y
9  ret <2 x i8> %s
10}
11
12define <2 x i8> @vsel_fvec(<2 x i8> %x, <2 x i8> %y) {
13; CHECK-LABEL: @vsel_fvec(
14; CHECK-NEXT:    ret <2 x i8> %y
15;
16  %s = select <2 x i1><i1 false, i1 false>, <2 x i8> %x, <2 x i8> %y
17  ret <2 x i8> %s
18}
19
20define i32 @test1(i32 %x) {
21; CHECK-LABEL: @test1(
22; CHECK-NEXT:    ret i32 %x
23;
24  %and = and i32 %x, 1
25  %cmp = icmp eq i32 %and, 0
26  %and1 = and i32 %x, -2
27  %and1.x = select i1 %cmp, i32 %and1, i32 %x
28  ret i32 %and1.x
29}
30
31define i32 @test2(i32 %x) {
32; CHECK-LABEL: @test2(
33; CHECK-NEXT:    ret i32 %x
34;
35  %and = and i32 %x, 1
36  %cmp = icmp ne i32 %and, 0
37  %and1 = and i32 %x, -2
38  %and1.x = select i1 %cmp, i32 %x, i32 %and1
39  ret i32 %and1.x
40}
41
42define i32 @test3(i32 %x) {
43; CHECK-LABEL: @test3(
44; CHECK-NEXT:    [[AND1:%.*]] = and i32 %x, -2
45; CHECK-NEXT:    ret i32 [[AND1]]
46;
47  %and = and i32 %x, 1
48  %cmp = icmp ne i32 %and, 0
49  %and1 = and i32 %x, -2
50  %and1.x = select i1 %cmp, i32 %and1, i32 %x
51  ret i32 %and1.x
52}
53
54define i32 @test4(i32 %X) {
55; CHECK-LABEL: @test4(
56; CHECK-NEXT:    [[OR:%.*]] = or i32 %X, -2147483648
57; CHECK-NEXT:    ret i32 [[OR]]
58;
59  %cmp = icmp slt i32 %X, 0
60  %or = or i32 %X, -2147483648
61  %cond = select i1 %cmp, i32 %X, i32 %or
62  ret i32 %cond
63}
64
65; Same as above, but the compare isn't canonical
66define i32 @test4noncanon(i32 %X) {
67; CHECK-LABEL: @test4noncanon(
68; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
69; CHECK-NEXT:    ret i32 [[OR]]
70;
71  %cmp = icmp sle i32 %X, -1
72  %or = or i32 %X, -2147483648
73  %cond = select i1 %cmp, i32 %X, i32 %or
74  ret i32 %cond
75}
76
77define i32 @test5(i32 %X) {
78; CHECK-LABEL: @test5(
79; CHECK-NEXT:    ret i32 %X
80;
81  %cmp = icmp slt i32 %X, 0
82  %or = or i32 %X, -2147483648
83  %cond = select i1 %cmp, i32 %or, i32 %X
84  ret i32 %cond
85}
86
87define i32 @test6(i32 %X) {
88; CHECK-LABEL: @test6(
89; CHECK-NEXT:    [[AND:%.*]] = and i32 %X, 2147483647
90; CHECK-NEXT:    ret i32 [[AND]]
91;
92  %cmp = icmp slt i32 %X, 0
93  %and = and i32 %X, 2147483647
94  %cond = select i1 %cmp, i32 %and, i32 %X
95  ret i32 %cond
96}
97
98define i32 @test7(i32 %X) {
99; CHECK-LABEL: @test7(
100; CHECK-NEXT:    ret i32 %X
101;
102  %cmp = icmp slt i32 %X, 0
103  %and = and i32 %X, 2147483647
104  %cond = select i1 %cmp, i32 %X, i32 %and
105  ret i32 %cond
106}
107
108define i32 @test8(i32 %X) {
109; CHECK-LABEL: @test8(
110; CHECK-NEXT:    ret i32 %X
111;
112  %cmp = icmp sgt i32 %X, -1
113  %or = or i32 %X, -2147483648
114  %cond = select i1 %cmp, i32 %X, i32 %or
115  ret i32 %cond
116}
117
118define i32 @test9(i32 %X) {
119; CHECK-LABEL: @test9(
120; CHECK-NEXT:    [[OR:%.*]] = or i32 %X, -2147483648
121; CHECK-NEXT:    ret i32 [[OR]]
122;
123  %cmp = icmp sgt i32 %X, -1
124  %or = or i32 %X, -2147483648
125  %cond = select i1 %cmp, i32 %or, i32 %X
126  ret i32 %cond
127}
128
129; Same as above, but the compare isn't canonical
130define i32 @test9noncanon(i32 %X) {
131; CHECK-LABEL: @test9noncanon(
132; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
133; CHECK-NEXT:    ret i32 [[OR]]
134;
135  %cmp = icmp sge i32 %X, 0
136  %or = or i32 %X, -2147483648
137  %cond = select i1 %cmp, i32 %or, i32 %X
138  ret i32 %cond
139}
140
141define i32 @test10(i32 %X) {
142; CHECK-LABEL: @test10(
143; CHECK-NEXT:    ret i32 %X
144;
145  %cmp = icmp sgt i32 %X, -1
146  %and = and i32 %X, 2147483647
147  %cond = select i1 %cmp, i32 %and, i32 %X
148  ret i32 %cond
149}
150
151define i32 @test11(i32 %X) {
152; CHECK-LABEL: @test11(
153; CHECK-NEXT:    [[AND:%.*]] = and i32 %X, 2147483647
154; CHECK-NEXT:    ret i32 [[AND]]
155;
156  %cmp = icmp sgt i32 %X, -1
157  %and = and i32 %X, 2147483647
158  %cond = select i1 %cmp, i32 %X, i32 %and
159  ret i32 %cond
160}
161
162define <2 x i8> @test11vec(<2 x i8> %X) {
163; CHECK-LABEL: @test11vec(
164; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> %X, <i8 127, i8 127>
165; CHECK-NEXT:    ret <2 x i8> [[AND]]
166;
167  %cmp = icmp sgt <2 x i8> %X, <i8 -1, i8 -1>
168  %and = and <2 x i8> %X, <i8 127, i8 127>
169  %sel = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %and
170  ret <2 x i8> %sel
171}
172
173define i32 @test12(i32 %X) {
174; CHECK-LABEL: @test12(
175; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
176; CHECK-NEXT:    ret i32 [[AND]]
177;
178  %cmp = icmp ult i32 %X, 4
179  %and = and i32 %X, 3
180  %cond = select i1 %cmp, i32 %X, i32 %and
181  ret i32 %cond
182}
183
184; Same as above, but the compare isn't canonical
185define i32 @test12noncanon(i32 %X) {
186; CHECK-LABEL: @test12noncanon(
187; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
188; CHECK-NEXT:    ret i32 [[AND]]
189;
190  %cmp = icmp ule i32 %X, 3
191  %and = and i32 %X, 3
192  %cond = select i1 %cmp, i32 %X, i32 %and
193  ret i32 %cond
194}
195
196define i32 @test13(i32 %X) {
197; CHECK-LABEL: @test13(
198; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
199; CHECK-NEXT:    ret i32 [[AND]]
200;
201  %cmp = icmp ugt i32 %X, 3
202  %and = and i32 %X, 3
203  %cond = select i1 %cmp, i32 %and, i32 %X
204  ret i32 %cond
205}
206
207; Same as above, but the compare isn't canonical
208define i32 @test13noncanon(i32 %X) {
209; CHECK-LABEL: @test13noncanon(
210; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
211; CHECK-NEXT:    ret i32 [[AND]]
212;
213  %cmp = icmp uge i32 %X, 4
214  %and = and i32 %X, 3
215  %cond = select i1 %cmp, i32 %and, i32 %X
216  ret i32 %cond
217}
218
219define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) {
220; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8(
221; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, 8
222; CHECK-NEXT:    ret i32 [[OR]]
223;
224  %and = and i32 %x, 8
225  %cmp = icmp eq i32 %and, 0
226  %or = or i32 %x, 8
227  %sel = select i1 %cmp, i32 %or, i32 %x
228  ret i32 %sel
229}
230
231define i32 @select_icmp_and_8_eq_0_or_8_alt(i32 %x) {
232; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8_alt(
233; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, 8
234; CHECK-NEXT:    ret i32 [[OR]]
235;
236  %and = and i32 %x, 8
237  %cmp = icmp ne i32 %and, 0
238  %or = or i32 %x, 8
239  %sel = select i1 %cmp, i32 %x, i32 %or
240  ret i32 %sel
241}
242
243define i32 @select_icmp_and_8_ne_0_or_8(i32 %x) {
244; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8(
245; CHECK-NEXT:    ret i32 %x
246;
247  %and = and i32 %x, 8
248  %cmp = icmp ne i32 %and, 0
249  %or = or i32 %x, 8
250  %sel = select i1 %cmp, i32 %or, i32 %x
251  ret i32 %sel
252}
253
254define i32 @select_icmp_and_8_ne_0_or_8_alt(i32 %x) {
255; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8_alt(
256; CHECK-NEXT:    ret i32 %x
257;
258  %and = and i32 %x, 8
259  %cmp = icmp eq i32 %and, 0
260  %or = or i32 %x, 8
261  %sel = select i1 %cmp, i32 %x, i32 %or
262  ret i32 %sel
263}
264
265define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) {
266; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8(
267; CHECK-NEXT:    [[AND1:%.*]] = and i32 %x, -9
268; CHECK-NEXT:    ret i32 [[AND1]]
269;
270  %and = and i32 %x, 8
271  %cmp = icmp eq i32 %and, 0
272  %and1 = and i32 %x, -9
273  %sel = select i1 %cmp, i32 %x, i32 %and1
274  ret i32 %sel
275}
276
277define i32 @select_icmp_and_8_eq_0_and_not_8_alt(i32 %x) {
278; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8_alt(
279; CHECK-NEXT:    [[AND1:%.*]] = and i32 %x, -9
280; CHECK-NEXT:    ret i32 [[AND1]]
281;
282  %and = and i32 %x, 8
283  %cmp = icmp ne i32 %and, 0
284  %and1 = and i32 %x, -9
285  %sel = select i1 %cmp, i32 %and1, i32 %x
286  ret i32 %sel
287}
288
289define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) {
290; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8(
291; CHECK-NEXT:    ret i32 %x
292;
293  %and = and i32 %x, 8
294  %cmp = icmp ne i32 %and, 0
295  %and1 = and i32 %x, -9
296  %sel = select i1 %cmp, i32 %x, i32 %and1
297  ret i32 %sel
298}
299
300define i32 @select_icmp_and_8_ne_0_and_not_8_alt(i32 %x) {
301; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_alt(
302; CHECK-NEXT:    ret i32 %x
303;
304  %and = and i32 %x, 8
305  %cmp = icmp eq i32 %and, 0
306  %and1 = and i32 %x, -9
307  %sel = select i1 %cmp, i32 %and1, i32 %x
308  ret i32 %sel
309}
310
311; PR28466: https://llvm.org/bugs/show_bug.cgi?id=28466
312; Each of the previous 8 patterns has a variant that replaces the
313; 'and' with a 'trunc' and the icmp eq/ne with icmp slt/sgt.
314
315define i32 @select_icmp_trunc_8_ne_0_or_128(i32 %x) {
316; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128(
317; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, 128
318; CHECK-NEXT:    ret i32 [[OR]]
319;
320  %trunc = trunc i32 %x to i8
321  %cmp = icmp sgt i8 %trunc, -1
322  %or = or i32 %x, 128
323  %sel = select i1 %cmp, i32 %or, i32 %x
324  ret i32 %sel
325}
326
327define i32 @select_icmp_trunc_8_ne_0_or_128_alt(i32 %x) {
328; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128_alt(
329; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, 128
330; CHECK-NEXT:    ret i32 [[OR]]
331;
332  %trunc = trunc i32 %x to i8
333  %cmp = icmp slt i8 %trunc, 0
334  %or = or i32 %x, 128
335  %sel = select i1 %cmp, i32 %x, i32 %or
336  ret i32 %sel
337}
338
339define i32 @select_icmp_trunc_8_eq_0_or_128(i32 %x) {
340; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128(
341; CHECK-NEXT:    ret i32 %x
342;
343  %trunc = trunc i32 %x to i8
344  %cmp = icmp slt i8 %trunc, 0
345  %or = or i32 %x, 128
346  %sel = select i1 %cmp, i32 %or, i32 %x
347  ret i32 %sel
348}
349
350define i32 @select_icmp_trunc_8_eq_0_or_128_alt(i32 %x) {
351; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128_alt(
352; CHECK-NEXT:    ret i32 %x
353;
354  %trunc = trunc i32 %x to i8
355  %cmp = icmp sgt i8 %trunc, -1
356  %or = or i32 %x, 128
357  %sel = select i1 %cmp, i32 %x, i32 %or
358  ret i32 %sel
359}
360
361define i32 @select_icmp_trunc_8_eq_0_and_not_8(i32 %x) {
362; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8(
363; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, -9
364; CHECK-NEXT:    ret i32 [[AND]]
365;
366  %trunc = trunc i32 %x to i4
367  %cmp = icmp sgt i4 %trunc, -1
368  %and = and i32 %x, -9
369  %sel = select i1 %cmp, i32 %x, i32 %and
370  ret i32 %sel
371}
372
373define i32 @select_icmp_trunc_8_eq_0_and_not_8_alt(i32 %x) {
374; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8_alt(
375; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, -9
376; CHECK-NEXT:    ret i32 [[AND]]
377;
378  %trunc = trunc i32 %x to i4
379  %cmp = icmp slt i4 %trunc, 0
380  %and = and i32 %x, -9
381  %sel = select i1 %cmp, i32 %and, i32 %x
382  ret i32 %sel
383}
384
385define i32 @select_icmp_trunc_8_ne_0_and_not_8(i32 %x) {
386; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8(
387; CHECK-NEXT:    ret i32 %x
388;
389  %trunc = trunc i32 %x to i4
390  %cmp = icmp slt i4 %trunc, 0
391  %and = and i32 %x, -9
392  %sel = select i1 %cmp, i32 %x, i32 %and
393  ret i32 %sel
394}
395
396define i32 @select_icmp_trunc_8_ne_0_and_not_8_alt(i32 %x) {
397; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt(
398; CHECK-NEXT:    ret i32 %x
399;
400  %trunc = trunc i32 %x to i4
401  %cmp = icmp sgt i4 %trunc, -1
402  %and = and i32 %x, -9
403  %sel = select i1 %cmp, i32 %and, i32 %x
404  ret i32 %sel
405}
406
407; Make sure that at least a few of the same patterns are repeated with vector types.
408
409define <2 x i32> @select_icmp_and_8_ne_0_and_not_8_vec(<2 x i32> %x) {
410; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_vec(
411; CHECK-NEXT:    ret <2 x i32> %x
412;
413  %and = and <2 x i32> %x, <i32 8, i32 8>
414  %cmp = icmp ne <2 x i32> %and, zeroinitializer
415  %and1 = and <2 x i32> %x, <i32 -9, i32 -9>
416  %sel = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %and1
417  ret <2 x i32> %sel
418}
419
420define <2 x i32> @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(<2 x i32> %x) {
421; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(
422; CHECK-NEXT:    ret <2 x i32> %x
423;
424  %trunc = trunc <2 x i32> %x to <2 x i4>
425  %cmp = icmp sgt <2 x i4> %trunc, <i4 -1, i4 -1>
426  %and = and <2 x i32> %x, <i32 -9, i32 -9>
427  %sel = select <2 x i1> %cmp, <2 x i32> %and, <2 x i32> %x
428  ret <2 x i32> %sel
429}
430
431; Insert a bit from x into y? This should be possible in InstCombine, but not InstSimplify?
432
433define i32 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i32 %y) {
434; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8(
435; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 8
436; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
437; CHECK-NEXT:    [[AND1:%.*]] = and i32 %y, -9
438; CHECK-NEXT:    [[Y_AND1:%.*]] = select i1 [[CMP]], i32 %y, i32 [[AND1]]
439; CHECK-NEXT:    ret i32 [[Y_AND1]]
440;
441  %and = and i32 %x, 8
442  %cmp = icmp eq i32 %and, 0
443  %and1 = and i32 %y, -9
444  %y.and1 = select i1 %cmp, i32 %y, i32 %and1
445  ret i32 %y.and1
446}
447
448define i64 @select_icmp_x_and_8_eq_0_y64_and_not_8(i32 %x, i64 %y) {
449; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y64_and_not_8(
450; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 8
451; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
452; CHECK-NEXT:    [[AND1:%.*]] = and i64 %y, -9
453; CHECK-NEXT:    [[Y_AND1:%.*]] = select i1 [[CMP]], i64 %y, i64 [[AND1]]
454; CHECK-NEXT:    ret i64 [[Y_AND1]]
455;
456  %and = and i32 %x, 8
457  %cmp = icmp eq i32 %and, 0
458  %and1 = and i64 %y, -9
459  %y.and1 = select i1 %cmp, i64 %y, i64 %and1
460  ret i64 %y.and1
461}
462
463define i64 @select_icmp_x_and_8_ne_0_y64_and_not_8(i32 %x, i64 %y) {
464; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y64_and_not_8(
465; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 8
466; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
467; CHECK-NEXT:    [[AND1:%.*]] = and i64 %y, -9
468; CHECK-NEXT:    [[AND1_Y:%.*]] = select i1 [[CMP]], i64 [[AND1]], i64 %y
469; CHECK-NEXT:    ret i64 [[AND1_Y]]
470;
471  %and = and i32 %x, 8
472  %cmp = icmp eq i32 %and, 0
473  %and1 = and i64 %y, -9
474  %and1.y = select i1 %cmp, i64 %and1, i64 %y
475  ret i64 %and1.y
476}
477
478; Don't crash on a pointer or aggregate type.
479
480define i32* @select_icmp_pointers(i32* %x, i32* %y) {
481; CHECK-LABEL: @select_icmp_pointers(
482; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32* %x, null
483; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32* %x, i32* %y
484; CHECK-NEXT:    ret i32* [[SEL]]
485;
486  %cmp = icmp slt i32* %x, null
487  %sel = select i1 %cmp, i32* %x, i32* %y
488  ret i32* %sel
489}
490
491; If the condition is known, we don't need to select, but we're not
492; doing this fold here to avoid compile-time cost.
493
494declare void @llvm.assume(i1)
495
496define i8 @assume_sel_cond(i1 %cond, i8 %x, i8 %y) {
497; CHECK-LABEL: @assume_sel_cond(
498; CHECK-NEXT:    call void @llvm.assume(i1 %cond)
499; CHECK-NEXT:    [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y
500; CHECK-NEXT:    ret i8 [[SEL]]
501;
502  call void @llvm.assume(i1 %cond)
503  %sel = select i1 %cond, i8 %x, i8 %y
504  ret i8 %sel
505}
506
507define i8 @do_not_assume_sel_cond(i1 %cond, i8 %x, i8 %y) {
508; CHECK-LABEL: @do_not_assume_sel_cond(
509; CHECK-NEXT:    [[NOTCOND:%.*]] = icmp eq i1 %cond, false
510; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTCOND]])
511; CHECK-NEXT:    [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y
512; CHECK-NEXT:    ret i8 [[SEL]]
513;
514  %notcond = icmp eq i1 %cond, false
515  call void @llvm.assume(i1 %notcond)
516  %sel = select i1 %cond, i8 %x, i8 %y
517  ret i8 %sel
518}
519
520