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