1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instsimplify -S | FileCheck %s
3
4define i1 @bool_true_or_false(i1 %cond) {
5; CHECK-LABEL: @bool_true_or_false(
6; CHECK-NEXT:    ret i1 [[COND:%.*]]
7;
8  %s = select i1 %cond, i1 true, i1 false
9  ret i1 %s
10}
11
12define <2 x i1> @bool_true_or_false_vec(<2 x i1> %cond) {
13; CHECK-LABEL: @bool_true_or_false_vec(
14; CHECK-NEXT:    ret <2 x i1> [[COND:%.*]]
15;
16  %s = select <2 x i1> %cond, <2 x i1> <i1 true, i1 true>, <2 x i1> zeroinitializer
17  ret <2 x i1> %s
18}
19
20define <2 x i1> @bool_true_or_false_vec_undef(<2 x i1> %cond) {
21; CHECK-LABEL: @bool_true_or_false_vec_undef(
22; CHECK-NEXT:    ret <2 x i1> [[COND:%.*]]
23;
24  %s = select <2 x i1> %cond, <2 x i1> <i1 undef, i1 true>, <2 x i1> <i1 false, i1 undef>
25  ret <2 x i1> %s
26}
27
28define i32 @cond_is_false(i32 %A, i32 %B) {
29; CHECK-LABEL: @cond_is_false(
30; CHECK-NEXT:    ret i32 [[B:%.*]]
31;
32  %C = select i1 false, i32 %A, i32 %B
33  ret i32 %C
34}
35
36define i32 @cond_is_true(i32 %A, i32 %B) {
37; CHECK-LABEL: @cond_is_true(
38; CHECK-NEXT:    ret i32 [[A:%.*]]
39;
40  %C = select i1 true, i32 %A, i32 %B
41  ret i32 %C
42}
43
44define i32 @equal_arms(i1 %cond, i32 %x) {
45; CHECK-LABEL: @equal_arms(
46; CHECK-NEXT:    ret i32 [[X:%.*]]
47;
48  %V = select i1 %cond, i32 %x, i32 %x
49  ret i32 %V
50}
51
52define <2 x i32> @equal_arms_vec(<2 x i1> %cond, <2 x i32> %x) {
53; CHECK-LABEL: @equal_arms_vec(
54; CHECK-NEXT:    ret <2 x i32> [[X:%.*]]
55;
56  %V = select <2 x i1> %cond, <2 x i32> %x, <2 x i32> %x
57  ret <2 x i32> %V
58}
59
60define <2 x i32> @equal_arms_vec_undef(<2 x i1> %cond) {
61; CHECK-LABEL: @equal_arms_vec_undef(
62; CHECK-NEXT:    ret <2 x i32> <i32 42, i32 42>
63;
64  %V = select <2 x i1> %cond, <2 x i32> <i32 42, i32 undef>, <2 x i32> <i32 undef, i32 42>
65  ret <2 x i32> %V
66}
67
68define <3 x float> @equal_arms_vec_less_undef(<3 x i1> %cond) {
69; CHECK-LABEL: @equal_arms_vec_less_undef(
70; CHECK-NEXT:    ret <3 x float> <float 4.200000e+01, float 4.200000e+01, float 4.300000e+01>
71;
72  %V = select <3 x i1> %cond, <3 x float> <float 42.0, float undef, float 43.0>, <3 x float> <float 42.0, float 42.0, float 43.0>
73  ret <3 x float> %V
74}
75
76define <3 x float> @equal_arms_vec_more_undef(<3 x i1> %cond) {
77; CHECK-LABEL: @equal_arms_vec_more_undef(
78; CHECK-NEXT:    ret <3 x float> <float 4.200000e+01, float undef, float 4.300000e+01>
79;
80  %V = select <3 x i1> %cond, <3 x float> <float 42.0, float undef, float undef>, <3 x float> <float undef, float undef, float 43.0>
81  ret <3 x float> %V
82}
83
84define <2 x i8> @vsel_tvec(<2 x i8> %x, <2 x i8> %y) {
85; CHECK-LABEL: @vsel_tvec(
86; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
87;
88  %s = select <2 x i1><i1 true, i1 true>, <2 x i8> %x, <2 x i8> %y
89  ret <2 x i8> %s
90}
91
92define <2 x i8> @vsel_fvec(<2 x i8> %x, <2 x i8> %y) {
93; CHECK-LABEL: @vsel_fvec(
94; CHECK-NEXT:    ret <2 x i8> [[Y:%.*]]
95;
96  %s = select <2 x i1><i1 false, i1 false>, <2 x i8> %x, <2 x i8> %y
97  ret <2 x i8> %s
98}
99
100define <2 x i8> @vsel_mixedvec() {
101; CHECK-LABEL: @vsel_mixedvec(
102; CHECK-NEXT:    ret <2 x i8> <i8 0, i8 3>
103;
104  %s = select <2 x i1><i1 true, i1 false>, <2 x i8> <i8 0, i8 1>, <2 x i8> <i8 2, i8 3>
105  ret <2 x i8> %s
106}
107
108; FIXME: Allow for undef elements in a constant vector condition.
109
110define <3 x i8> @vsel_undef_true_op(<3 x i8> %x, <3 x i8> %y) {
111; CHECK-LABEL: @vsel_undef_true_op(
112; CHECK-NEXT:    [[S:%.*]] = select <3 x i1> <i1 true, i1 undef, i1 true>, <3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]]
113; CHECK-NEXT:    ret <3 x i8> [[S]]
114;
115  %s = select <3 x i1><i1 1, i1 undef, i1 1>, <3 x i8> %x, <3 x i8> %y
116  ret <3 x i8> %s
117}
118
119define <3 x i4> @vsel_undef_false_op(<3 x i4> %x, <3 x i4> %y) {
120; CHECK-LABEL: @vsel_undef_false_op(
121; CHECK-NEXT:    [[S:%.*]] = select <3 x i1> <i1 false, i1 undef, i1 undef>, <3 x i4> [[X:%.*]], <3 x i4> [[Y:%.*]]
122; CHECK-NEXT:    ret <3 x i4> [[S]]
123;
124  %s = select <3 x i1><i1 0, i1 undef, i1 undef>, <3 x i4> %x, <3 x i4> %y
125  ret <3 x i4> %s
126}
127
128define i32 @test1(i32 %x) {
129; CHECK-LABEL: @test1(
130; CHECK-NEXT:    ret i32 [[X:%.*]]
131;
132  %and = and i32 %x, 1
133  %cmp = icmp eq i32 %and, 0
134  %and1 = and i32 %x, -2
135  %and1.x = select i1 %cmp, i32 %and1, i32 %x
136  ret i32 %and1.x
137}
138
139define i32 @test2(i32 %x) {
140; CHECK-LABEL: @test2(
141; CHECK-NEXT:    ret i32 [[X:%.*]]
142;
143  %and = and i32 %x, 1
144  %cmp = icmp ne i32 %and, 0
145  %and1 = and i32 %x, -2
146  %and1.x = select i1 %cmp, i32 %x, i32 %and1
147  ret i32 %and1.x
148}
149
150define i32 @test3(i32 %x) {
151; CHECK-LABEL: @test3(
152; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[X:%.*]], -2
153; CHECK-NEXT:    ret i32 [[AND1]]
154;
155  %and = and i32 %x, 1
156  %cmp = icmp ne i32 %and, 0
157  %and1 = and i32 %x, -2
158  %and1.x = select i1 %cmp, i32 %and1, i32 %x
159  ret i32 %and1.x
160}
161
162define i32 @test4(i32 %X) {
163; CHECK-LABEL: @test4(
164; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
165; CHECK-NEXT:    ret i32 [[OR]]
166;
167  %cmp = icmp slt i32 %X, 0
168  %or = or i32 %X, -2147483648
169  %cond = select i1 %cmp, i32 %X, i32 %or
170  ret i32 %cond
171}
172
173; Same as above, but the compare isn't canonical
174define i32 @test4noncanon(i32 %X) {
175; CHECK-LABEL: @test4noncanon(
176; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
177; CHECK-NEXT:    ret i32 [[OR]]
178;
179  %cmp = icmp sle i32 %X, -1
180  %or = or i32 %X, -2147483648
181  %cond = select i1 %cmp, i32 %X, i32 %or
182  ret i32 %cond
183}
184
185define i32 @test5(i32 %X) {
186; CHECK-LABEL: @test5(
187; CHECK-NEXT:    ret i32 [[X:%.*]]
188;
189  %cmp = icmp slt i32 %X, 0
190  %or = or i32 %X, -2147483648
191  %cond = select i1 %cmp, i32 %or, i32 %X
192  ret i32 %cond
193}
194
195define i32 @test6(i32 %X) {
196; CHECK-LABEL: @test6(
197; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
198; CHECK-NEXT:    ret i32 [[AND]]
199;
200  %cmp = icmp slt i32 %X, 0
201  %and = and i32 %X, 2147483647
202  %cond = select i1 %cmp, i32 %and, i32 %X
203  ret i32 %cond
204}
205
206define i32 @test7(i32 %X) {
207; CHECK-LABEL: @test7(
208; CHECK-NEXT:    ret i32 [[X:%.*]]
209;
210  %cmp = icmp slt i32 %X, 0
211  %and = and i32 %X, 2147483647
212  %cond = select i1 %cmp, i32 %X, i32 %and
213  ret i32 %cond
214}
215
216define i32 @test8(i32 %X) {
217; CHECK-LABEL: @test8(
218; CHECK-NEXT:    ret i32 [[X:%.*]]
219;
220  %cmp = icmp sgt i32 %X, -1
221  %or = or i32 %X, -2147483648
222  %cond = select i1 %cmp, i32 %X, i32 %or
223  ret i32 %cond
224}
225
226define i32 @test9(i32 %X) {
227; CHECK-LABEL: @test9(
228; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
229; CHECK-NEXT:    ret i32 [[OR]]
230;
231  %cmp = icmp sgt i32 %X, -1
232  %or = or i32 %X, -2147483648
233  %cond = select i1 %cmp, i32 %or, i32 %X
234  ret i32 %cond
235}
236
237; Same as above, but the compare isn't canonical
238define i32 @test9noncanon(i32 %X) {
239; CHECK-LABEL: @test9noncanon(
240; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
241; CHECK-NEXT:    ret i32 [[OR]]
242;
243  %cmp = icmp sge i32 %X, 0
244  %or = or i32 %X, -2147483648
245  %cond = select i1 %cmp, i32 %or, i32 %X
246  ret i32 %cond
247}
248
249define i32 @test10(i32 %X) {
250; CHECK-LABEL: @test10(
251; CHECK-NEXT:    ret i32 [[X:%.*]]
252;
253  %cmp = icmp sgt i32 %X, -1
254  %and = and i32 %X, 2147483647
255  %cond = select i1 %cmp, i32 %and, i32 %X
256  ret i32 %cond
257}
258
259define i32 @test11(i32 %X) {
260; CHECK-LABEL: @test11(
261; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
262; CHECK-NEXT:    ret i32 [[AND]]
263;
264  %cmp = icmp sgt i32 %X, -1
265  %and = and i32 %X, 2147483647
266  %cond = select i1 %cmp, i32 %X, i32 %and
267  ret i32 %cond
268}
269
270define <2 x i8> @test11vec(<2 x i8> %X) {
271; CHECK-LABEL: @test11vec(
272; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[X:%.*]], <i8 127, i8 127>
273; CHECK-NEXT:    ret <2 x i8> [[AND]]
274;
275  %cmp = icmp sgt <2 x i8> %X, <i8 -1, i8 -1>
276  %and = and <2 x i8> %X, <i8 127, i8 127>
277  %sel = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %and
278  ret <2 x i8> %sel
279}
280
281define i32 @test12(i32 %X) {
282; CHECK-LABEL: @test12(
283; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
284; CHECK-NEXT:    ret i32 [[AND]]
285;
286  %cmp = icmp ult i32 %X, 4
287  %and = and i32 %X, 3
288  %cond = select i1 %cmp, i32 %X, i32 %and
289  ret i32 %cond
290}
291
292; Same as above, but the compare isn't canonical
293define i32 @test12noncanon(i32 %X) {
294; CHECK-LABEL: @test12noncanon(
295; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
296; CHECK-NEXT:    ret i32 [[AND]]
297;
298  %cmp = icmp ule i32 %X, 3
299  %and = and i32 %X, 3
300  %cond = select i1 %cmp, i32 %X, i32 %and
301  ret i32 %cond
302}
303
304define i32 @test13(i32 %X) {
305; CHECK-LABEL: @test13(
306; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
307; CHECK-NEXT:    ret i32 [[AND]]
308;
309  %cmp = icmp ugt i32 %X, 3
310  %and = and i32 %X, 3
311  %cond = select i1 %cmp, i32 %and, i32 %X
312  ret i32 %cond
313}
314
315; Same as above, but the compare isn't canonical
316define i32 @test13noncanon(i32 %X) {
317; CHECK-LABEL: @test13noncanon(
318; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 3
319; CHECK-NEXT:    ret i32 [[AND]]
320;
321  %cmp = icmp uge i32 %X, 4
322  %and = and i32 %X, 3
323  %cond = select i1 %cmp, i32 %and, i32 %X
324  ret i32 %cond
325}
326
327define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) {
328; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8(
329; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], 8
330; CHECK-NEXT:    ret i32 [[OR]]
331;
332  %and = and i32 %x, 8
333  %cmp = icmp eq i32 %and, 0
334  %or = or i32 %x, 8
335  %sel = select i1 %cmp, i32 %or, i32 %x
336  ret i32 %sel
337}
338
339define i32 @select_icmp_and_8_eq_0_or_8_alt(i32 %x) {
340; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8_alt(
341; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], 8
342; CHECK-NEXT:    ret i32 [[OR]]
343;
344  %and = and i32 %x, 8
345  %cmp = icmp ne i32 %and, 0
346  %or = or i32 %x, 8
347  %sel = select i1 %cmp, i32 %x, i32 %or
348  ret i32 %sel
349}
350
351define i32 @select_icmp_and_8_ne_0_or_8(i32 %x) {
352; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8(
353; CHECK-NEXT:    ret i32 [[X:%.*]]
354;
355  %and = and i32 %x, 8
356  %cmp = icmp ne i32 %and, 0
357  %or = or i32 %x, 8
358  %sel = select i1 %cmp, i32 %or, i32 %x
359  ret i32 %sel
360}
361
362define i32 @select_icmp_and_8_ne_0_or_8_alt(i32 %x) {
363; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8_alt(
364; CHECK-NEXT:    ret i32 [[X:%.*]]
365;
366  %and = and i32 %x, 8
367  %cmp = icmp eq i32 %and, 0
368  %or = or i32 %x, 8
369  %sel = select i1 %cmp, i32 %x, i32 %or
370  ret i32 %sel
371}
372
373define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) {
374; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8(
375; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[X:%.*]], -9
376; CHECK-NEXT:    ret i32 [[AND1]]
377;
378  %and = and i32 %x, 8
379  %cmp = icmp eq i32 %and, 0
380  %and1 = and i32 %x, -9
381  %sel = select i1 %cmp, i32 %x, i32 %and1
382  ret i32 %sel
383}
384
385define i32 @select_icmp_and_8_eq_0_and_not_8_alt(i32 %x) {
386; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8_alt(
387; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[X:%.*]], -9
388; CHECK-NEXT:    ret i32 [[AND1]]
389;
390  %and = and i32 %x, 8
391  %cmp = icmp ne i32 %and, 0
392  %and1 = and i32 %x, -9
393  %sel = select i1 %cmp, i32 %and1, i32 %x
394  ret i32 %sel
395}
396
397define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) {
398; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8(
399; CHECK-NEXT:    ret i32 [[X:%.*]]
400;
401  %and = and i32 %x, 8
402  %cmp = icmp ne i32 %and, 0
403  %and1 = and i32 %x, -9
404  %sel = select i1 %cmp, i32 %x, i32 %and1
405  ret i32 %sel
406}
407
408define i32 @select_icmp_and_8_ne_0_and_not_8_alt(i32 %x) {
409; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_alt(
410; CHECK-NEXT:    ret i32 [[X:%.*]]
411;
412  %and = and i32 %x, 8
413  %cmp = icmp eq i32 %and, 0
414  %and1 = and i32 %x, -9
415  %sel = select i1 %cmp, i32 %and1, i32 %x
416  ret i32 %sel
417}
418
419; PR28466: https://llvm.org/bugs/show_bug.cgi?id=28466
420; Each of the previous 8 patterns has a variant that replaces the
421; 'and' with a 'trunc' and the icmp eq/ne with icmp slt/sgt.
422
423define i32 @select_icmp_trunc_8_ne_0_or_128(i32 %x) {
424; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128(
425; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], 128
426; CHECK-NEXT:    ret i32 [[OR]]
427;
428  %trunc = trunc i32 %x to i8
429  %cmp = icmp sgt i8 %trunc, -1
430  %or = or i32 %x, 128
431  %sel = select i1 %cmp, i32 %or, i32 %x
432  ret i32 %sel
433}
434
435define i32 @select_icmp_trunc_8_ne_0_or_128_alt(i32 %x) {
436; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128_alt(
437; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], 128
438; CHECK-NEXT:    ret i32 [[OR]]
439;
440  %trunc = trunc i32 %x to i8
441  %cmp = icmp slt i8 %trunc, 0
442  %or = or i32 %x, 128
443  %sel = select i1 %cmp, i32 %x, i32 %or
444  ret i32 %sel
445}
446
447define i32 @select_icmp_trunc_8_eq_0_or_128(i32 %x) {
448; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128(
449; CHECK-NEXT:    ret i32 [[X:%.*]]
450;
451  %trunc = trunc i32 %x to i8
452  %cmp = icmp slt i8 %trunc, 0
453  %or = or i32 %x, 128
454  %sel = select i1 %cmp, i32 %or, i32 %x
455  ret i32 %sel
456}
457
458define i32 @select_icmp_trunc_8_eq_0_or_128_alt(i32 %x) {
459; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128_alt(
460; CHECK-NEXT:    ret i32 [[X:%.*]]
461;
462  %trunc = trunc i32 %x to i8
463  %cmp = icmp sgt i8 %trunc, -1
464  %or = or i32 %x, 128
465  %sel = select i1 %cmp, i32 %x, i32 %or
466  ret i32 %sel
467}
468
469define i32 @select_icmp_trunc_8_eq_0_and_not_8(i32 %x) {
470; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8(
471; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], -9
472; CHECK-NEXT:    ret i32 [[AND]]
473;
474  %trunc = trunc i32 %x to i4
475  %cmp = icmp sgt i4 %trunc, -1
476  %and = and i32 %x, -9
477  %sel = select i1 %cmp, i32 %x, i32 %and
478  ret i32 %sel
479}
480
481define i32 @select_icmp_trunc_8_eq_0_and_not_8_alt(i32 %x) {
482; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8_alt(
483; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], -9
484; CHECK-NEXT:    ret i32 [[AND]]
485;
486  %trunc = trunc i32 %x to i4
487  %cmp = icmp slt i4 %trunc, 0
488  %and = and i32 %x, -9
489  %sel = select i1 %cmp, i32 %and, i32 %x
490  ret i32 %sel
491}
492
493define i32 @select_icmp_trunc_8_ne_0_and_not_8(i32 %x) {
494; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8(
495; CHECK-NEXT:    ret i32 [[X:%.*]]
496;
497  %trunc = trunc i32 %x to i4
498  %cmp = icmp slt i4 %trunc, 0
499  %and = and i32 %x, -9
500  %sel = select i1 %cmp, i32 %x, i32 %and
501  ret i32 %sel
502}
503
504define i32 @select_icmp_trunc_8_ne_0_and_not_8_alt(i32 %x) {
505; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt(
506; CHECK-NEXT:    ret i32 [[X:%.*]]
507;
508  %trunc = trunc i32 %x to i4
509  %cmp = icmp sgt i4 %trunc, -1
510  %and = and i32 %x, -9
511  %sel = select i1 %cmp, i32 %and, i32 %x
512  ret i32 %sel
513}
514
515; Make sure that at least a few of the same patterns are repeated with vector types.
516
517define <2 x i32> @select_icmp_and_8_ne_0_and_not_8_vec(<2 x i32> %x) {
518; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_vec(
519; CHECK-NEXT:    ret <2 x i32> [[X:%.*]]
520;
521  %and = and <2 x i32> %x, <i32 8, i32 8>
522  %cmp = icmp ne <2 x i32> %and, zeroinitializer
523  %and1 = and <2 x i32> %x, <i32 -9, i32 -9>
524  %sel = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %and1
525  ret <2 x i32> %sel
526}
527
528define <2 x i32> @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(<2 x i32> %x) {
529; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(
530; CHECK-NEXT:    ret <2 x i32> [[X:%.*]]
531;
532  %trunc = trunc <2 x i32> %x to <2 x i4>
533  %cmp = icmp sgt <2 x i4> %trunc, <i4 -1, i4 -1>
534  %and = and <2 x i32> %x, <i32 -9, i32 -9>
535  %sel = select <2 x i1> %cmp, <2 x i32> %and, <2 x i32> %x
536  ret <2 x i32> %sel
537}
538
539; Insert a bit from x into y? This should be possible in InstCombine, but not InstSimplify?
540
541define i32 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i32 %y) {
542; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8(
543; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 8
544; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
545; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], -9
546; CHECK-NEXT:    [[Y_AND1:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND1]]
547; CHECK-NEXT:    ret i32 [[Y_AND1]]
548;
549  %and = and i32 %x, 8
550  %cmp = icmp eq i32 %and, 0
551  %and1 = and i32 %y, -9
552  %y.and1 = select i1 %cmp, i32 %y, i32 %and1
553  ret i32 %y.and1
554}
555
556define i64 @select_icmp_x_and_8_eq_0_y64_and_not_8(i32 %x, i64 %y) {
557; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y64_and_not_8(
558; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 8
559; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
560; CHECK-NEXT:    [[AND1:%.*]] = and i64 [[Y:%.*]], -9
561; CHECK-NEXT:    [[Y_AND1:%.*]] = select i1 [[CMP]], i64 [[Y]], i64 [[AND1]]
562; CHECK-NEXT:    ret i64 [[Y_AND1]]
563;
564  %and = and i32 %x, 8
565  %cmp = icmp eq i32 %and, 0
566  %and1 = and i64 %y, -9
567  %y.and1 = select i1 %cmp, i64 %y, i64 %and1
568  ret i64 %y.and1
569}
570
571define i64 @select_icmp_x_and_8_ne_0_y64_and_not_8(i32 %x, i64 %y) {
572; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y64_and_not_8(
573; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 8
574; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
575; CHECK-NEXT:    [[AND1:%.*]] = and i64 [[Y:%.*]], -9
576; CHECK-NEXT:    [[AND1_Y:%.*]] = select i1 [[CMP]], i64 [[AND1]], i64 [[Y]]
577; CHECK-NEXT:    ret i64 [[AND1_Y]]
578;
579  %and = and i32 %x, 8
580  %cmp = icmp eq i32 %and, 0
581  %and1 = and i64 %y, -9
582  %and1.y = select i1 %cmp, i64 %and1, i64 %y
583  ret i64 %and1.y
584}
585
586; Don't crash on a pointer or aggregate type.
587
588define i32* @select_icmp_pointers(i32* %x, i32* %y) {
589; CHECK-LABEL: @select_icmp_pointers(
590; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32* [[X:%.*]], null
591; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32* [[X]], i32* [[Y:%.*]]
592; CHECK-NEXT:    ret i32* [[SEL]]
593;
594  %cmp = icmp slt i32* %x, null
595  %sel = select i1 %cmp, i32* %x, i32* %y
596  ret i32* %sel
597}
598
599; If the condition is known, we don't need to select, but we're not
600; doing this fold here to avoid compile-time cost.
601
602declare void @llvm.assume(i1)
603
604define i8 @assume_sel_cond(i1 %cond, i8 %x, i8 %y) {
605; CHECK-LABEL: @assume_sel_cond(
606; CHECK-NEXT:    call void @llvm.assume(i1 [[COND:%.*]])
607; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i8 [[X:%.*]], i8 [[Y:%.*]]
608; CHECK-NEXT:    ret i8 [[SEL]]
609;
610  call void @llvm.assume(i1 %cond)
611  %sel = select i1 %cond, i8 %x, i8 %y
612  ret i8 %sel
613}
614
615define i8 @do_not_assume_sel_cond(i1 %cond, i8 %x, i8 %y) {
616; CHECK-LABEL: @do_not_assume_sel_cond(
617; CHECK-NEXT:    [[NOTCOND:%.*]] = icmp eq i1 [[COND:%.*]], false
618; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTCOND]])
619; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i8 [[X:%.*]], i8 [[Y:%.*]]
620; CHECK-NEXT:    ret i8 [[SEL]]
621;
622  %notcond = icmp eq i1 %cond, false
623  call void @llvm.assume(i1 %notcond)
624  %sel = select i1 %cond, i8 %x, i8 %y
625  ret i8 %sel
626}
627
628define i32* @select_icmp_eq_0_gep_operand(i32* %base, i64 %n) {
629; CHECK-LABEL: @select_icmp_eq_0_gep_operand(
630; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[BASE:%.*]], i64 [[N:%.*]]
631; CHECK-NEXT:    ret i32* [[GEP]]
632;
633  %cond = icmp eq i64 %n, 0
634  %gep = getelementptr i32, i32* %base, i64 %n
635  %r = select i1 %cond, i32* %base, i32* %gep
636  ret i32* %r
637}
638
639define i32* @select_icmp_ne_0_gep_operand(i32* %base, i64 %n) {
640; CHECK-LABEL: @select_icmp_ne_0_gep_operand(
641; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[BASE:%.*]], i64 [[N:%.*]]
642; CHECK-NEXT:    ret i32* [[GEP]]
643;
644  %cond = icmp ne i64 %n, 0
645  %gep = getelementptr i32, i32* %base, i64 %n
646  %r = select i1 %cond, i32* %gep, i32* %base
647  ret i32* %r
648}
649
650define i1 @and_cmps(i32 %x) {
651; CHECK-LABEL: @and_cmps(
652; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 92
653; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], 11
654; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
655; CHECK-NEXT:    ret i1 [[R]]
656;
657  %cmp1 = icmp slt i32 %x, 92
658  %cmp2 = icmp slt i32 %x, 11
659  %r = select i1 %cmp1, i1 %cmp2, i1 false
660  ret i1 %r
661}
662
663define <2 x i1> @and_cmps_vector(<2 x i32> %x) {
664; CHECK-LABEL: @and_cmps_vector(
665; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 92, i32 92>
666; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt <2 x i32> [[X]], <i32 11, i32 11>
667; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[CMP1]], <2 x i1> [[CMP2]], <2 x i1> zeroinitializer
668; CHECK-NEXT:    ret <2 x i1> [[R]]
669;
670  %cmp1 = icmp slt <2 x i32> %x, <i32 92, i32 92>
671  %cmp2 = icmp slt <2 x i32> %x, <i32 11, i32 11>
672  %r = select <2 x i1> %cmp1, <2 x i1> %cmp2, <2 x i1> <i1 false, i1 false>
673  ret <2 x i1> %r
674}
675
676define i1 @or_cmps(float %x) {
677; CHECK-LABEL: @or_cmps(
678; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno float [[X:%.*]], 4.200000e+01
679; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uno float [[X]], 5.200000e+01
680; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]
681; CHECK-NEXT:    ret i1 [[R]]
682;
683  %cmp1 = fcmp uno float %x, 42.0
684  %cmp2 = fcmp uno float %x, 52.0
685  %r = select i1 %cmp1, i1 true, i1 %cmp2
686  ret i1 %r
687}
688
689define <2 x i1> @or_logic_vector(<2 x i1> %x, <2 x i1> %y) {
690; CHECK-LABEL: @or_logic_vector(
691; CHECK-NEXT:    [[A:%.*]] = and <2 x i1> [[X:%.*]], [[Y:%.*]]
692; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[X]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[A]]
693; CHECK-NEXT:    ret <2 x i1> [[R]]
694;
695  %a = and <2 x i1> %x, %y
696  %r = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %a
697  ret <2 x i1> %r
698}
699
700define i1 @and_not_cmps(i32 %x) {
701; CHECK-LABEL: @and_not_cmps(
702; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 92
703; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], 11
704; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
705; CHECK-NEXT:    ret i1 [[R]]
706;
707  %cmp1 = icmp slt i32 %x, 92
708  %cmp2 = icmp slt i32 %x, 11
709  %r = select i1 %cmp1, i1 false, i1 %cmp2
710  ret i1 %r
711}
712
713define i1 @or_not_cmps(i32 %x) {
714; CHECK-LABEL: @or_not_cmps(
715; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 92
716; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], 11
717; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
718; CHECK-NEXT:    ret i1 [[R]]
719;
720  %cmp1 = icmp slt i32 %x, 92
721  %cmp2 = icmp slt i32 %x, 11
722  %r = select i1 %cmp1, i1 %cmp2, i1 true
723  ret i1 %r
724}
725
726define i8 @and_cmps_wrong_type(i32 %x) {
727; CHECK-LABEL: @and_cmps_wrong_type(
728; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 92
729; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], 11
730; CHECK-NEXT:    [[S:%.*]] = sext i1 [[CMP2]] to i8
731; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], i8 [[S]], i8 0
732; CHECK-NEXT:    ret i8 [[R]]
733;
734  %cmp1 = icmp slt i32 %x, 92
735  %cmp2 = icmp slt i32 %x, 11
736  %s = sext i1 %cmp2 to i8
737  %r = select i1 %cmp1, i8 %s, i8 0
738  ret i8 %r
739}
740
741define i1 @y_might_be_poison(float %x, float %y) {
742; CHECK-LABEL: @y_might_be_poison(
743; CHECK-NEXT:    [[C1:%.*]] = fcmp ord float 0.000000e+00, [[X:%.*]]
744; CHECK-NEXT:    [[C2:%.*]] = fcmp ord float [[X]], [[Y:%.*]]
745; CHECK-NEXT:    [[C3:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
746; CHECK-NEXT:    ret i1 [[C3]]
747;
748  %c1 = fcmp ord float 0.0, %x
749  %c2 = fcmp ord float %x, %y
750  %c3 = select i1 %c1, i1 %c2, i1 false
751  ret i1 %c3
752}
753
754; Negative tests to ensure we don't remove selects with undef true/false values.
755; See https://bugs.llvm.org/show_bug.cgi?id=31633
756; https://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html
757; https://reviews.llvm.org/D83360
758define i32 @false_undef(i1 %cond, i32 %x) {
759; CHECK-LABEL: @false_undef(
760; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 undef
761; CHECK-NEXT:    ret i32 [[S]]
762;
763  %s = select i1 %cond, i32 %x, i32 undef
764  ret i32 %s
765}
766
767define i32 @true_undef(i1 %cond, i32 %x) {
768; CHECK-LABEL: @true_undef(
769; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], i32 undef, i32 [[X:%.*]]
770; CHECK-NEXT:    ret i32 [[S]]
771;
772  %s = select i1 %cond, i32 undef, i32 %x
773  ret i32 %s
774}
775
776define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) {
777; CHECK-LABEL: @false_undef_vec(
778; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> [[X:%.*]], <2 x i32> undef
779; CHECK-NEXT:    ret <2 x i32> [[S]]
780;
781  %s = select i1 %cond, <2 x i32> %x, <2 x i32> undef
782  ret <2 x i32> %s
783}
784
785define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) {
786; CHECK-LABEL: @true_undef_vec(
787; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> undef, <2 x i32> [[X:%.*]]
788; CHECK-NEXT:    ret <2 x i32> [[S]]
789;
790  %s = select i1 %cond, <2 x i32> undef, <2 x i32> %x
791  ret <2 x i32> %s
792}
793
794; These can be folded because the other value is guaranteed not to be poison.
795define i32 @false_undef_true_constant(i1 %cond) {
796; CHECK-LABEL: @false_undef_true_constant(
797; CHECK-NEXT:    ret i32 10
798;
799  %s = select i1 %cond, i32 10, i32 undef
800  ret i32 %s
801}
802
803define i32 @true_undef_false_constant(i1 %cond) {
804; CHECK-LABEL: @true_undef_false_constant(
805; CHECK-NEXT:    ret i32 20
806;
807  %s = select i1 %cond, i32 undef, i32 20
808  ret i32 %s
809}
810
811define <2 x i32> @false_undef_true_constant_vec(i1 %cond) {
812; CHECK-LABEL: @false_undef_true_constant_vec(
813; CHECK-NEXT:    ret <2 x i32> <i32 42, i32 -42>
814;
815  %s = select i1 %cond, <2 x i32> <i32 42, i32 -42>, <2 x i32> undef
816  ret <2 x i32> %s
817}
818
819define <2 x i32> @true_undef_false_constant_vec(i1 %cond) {
820; CHECK-LABEL: @true_undef_false_constant_vec(
821; CHECK-NEXT:    ret <2 x i32> <i32 -42, i32 42>
822;
823  %s = select i1 %cond, <2 x i32> undef, <2 x i32> <i32 -42, i32 42>
824  ret <2 x i32> %s
825}
826
827; If one input is undef and the other is freeze, we can fold it to the freeze.
828define i32 @false_undef_true_freeze(i1 %cond, i32 %x) {
829; CHECK-LABEL: @false_undef_true_freeze(
830; CHECK-NEXT:    [[XF:%.*]] = freeze i32 [[X:%.*]]
831; CHECK-NEXT:    ret i32 [[XF]]
832;
833  %xf = freeze i32 %x
834  %s = select i1 %cond, i32 %xf, i32 undef
835  ret i32 %s
836}
837
838define i32 @false_undef_false_freeze(i1 %cond, i32 %x) {
839; CHECK-LABEL: @false_undef_false_freeze(
840; CHECK-NEXT:    [[XF:%.*]] = freeze i32 [[X:%.*]]
841; CHECK-NEXT:    ret i32 [[XF]]
842;
843  %xf = freeze i32 %x
844  %s = select i1 %cond, i32 undef, i32 %xf
845  ret i32 %s
846}
847
848@g = external global i32, align 1
849
850define <2 x i32> @false_undef_true_constextpr_vec(i1 %cond) {
851; CHECK-LABEL: @false_undef_true_constextpr_vec(
852; CHECK-NEXT:    ret <2 x i32> <i32 ptrtoint (i32* @g to i32), i32 ptrtoint (i32* @g to i32)>
853;
854  %s = select i1 %cond, <2 x i32> <i32 undef, i32 ptrtoint (i32* @g to i32)>, <2 x i32> <i32 ptrtoint (i32* @g to i32), i32 undef>
855  ret <2 x i32> %s
856}
857
858define i32 @all_constant_true_undef() {
859; CHECK-LABEL: @all_constant_true_undef(
860; CHECK-NEXT:    ret i32 1
861;
862  %s = select i1 ptrtoint (i32 ()* @all_constant_true_undef to i1), i32 undef, i32 1
863  ret i32 %s
864}
865
866define float @all_constant_false_undef() {
867; CHECK-LABEL: @all_constant_false_undef(
868; CHECK-NEXT:    ret float 1.000000e+00
869;
870  %s = select i1 ptrtoint (float ()* @all_constant_false_undef to i1), float undef, float 1.0
871  ret float %s
872}
873
874define <2 x i32> @all_constant_true_undef_vec() {
875; CHECK-LABEL: @all_constant_true_undef_vec(
876; CHECK-NEXT:    ret <2 x i32> <i32 1, i32 -1>
877;
878  %s = select i1 ptrtoint (<2 x i32> ()* @all_constant_true_undef_vec to i1), <2 x i32> undef, <2 x i32> <i32 1, i32 -1>
879  ret <2 x i32> %s
880}
881
882define <2 x float> @all_constant_false_undef_vec() {
883; CHECK-LABEL: @all_constant_false_undef_vec(
884; CHECK-NEXT:    ret <2 x float> <float 1.000000e+00, float -1.000000e+00>
885;
886  %s = select i1 ptrtoint (<2 x float> ()* @all_constant_false_undef_vec to i1), <2 x float> undef, <2 x float> <float 1.0, float -1.0>
887  ret <2 x float> %s
888}
889
890; Negative tests. Don't fold if the non-undef operand is a constexpr.
891define i32 @all_constant_false_undef_true_constexpr() {
892; CHECK-LABEL: @all_constant_false_undef_true_constexpr(
893; CHECK-NEXT:    [[S:%.*]] = select i1 ptrtoint (i32 ()* @all_constant_false_undef_true_constexpr to i1), i32 ptrtoint (i32 ()* @all_constant_false_undef_true_constexpr to i32), i32 undef
894; CHECK-NEXT:    ret i32 [[S]]
895;
896  %s = select i1 ptrtoint (i32 ()* @all_constant_false_undef_true_constexpr to i1), i32 ptrtoint (i32 ()* @all_constant_false_undef_true_constexpr to i32), i32 undef
897  ret i32 %s
898}
899
900define i32 @all_constant_true_undef_false_constexpr() {
901; CHECK-LABEL: @all_constant_true_undef_false_constexpr(
902; CHECK-NEXT:    [[S:%.*]] = select i1 ptrtoint (i32 ()* @all_constant_true_undef_false_constexpr to i1), i32 undef, i32 ptrtoint (i32 ()* @all_constant_true_undef_false_constexpr to i32)
903; CHECK-NEXT:    ret i32 [[S]]
904;
905  %s = select i1 ptrtoint (i32 ()* @all_constant_true_undef_false_constexpr to i1), i32 undef, i32 ptrtoint (i32 ()* @all_constant_true_undef_false_constexpr to i32)
906  ret i32 %s
907}
908
909; Negative tests. Don't fold if the non-undef operand is a vector containing a constexpr.
910define <2 x i32> @all_constant_false_undef_true_constexpr_vec() {
911; CHECK-LABEL: @all_constant_false_undef_true_constexpr_vec(
912; CHECK-NEXT:    [[S:%.*]] = select i1 ptrtoint (<2 x i32> ()* @all_constant_false_undef_true_constexpr_vec to i1), <2 x i32> <i32 ptrtoint (<2 x i32> ()* @all_constant_false_undef_true_constexpr_vec to i32), i32 -1>, <2 x i32> undef
913; CHECK-NEXT:    ret <2 x i32> [[S]]
914;
915  %s = select i1 ptrtoint (<2 x i32> ()* @all_constant_false_undef_true_constexpr_vec to i1), <2 x i32> <i32 ptrtoint (<2 x i32> ()* @all_constant_false_undef_true_constexpr_vec to i32), i32 -1>, <2 x i32> undef
916  ret <2 x i32> %s
917}
918
919define <2 x i32> @all_constant_true_undef_false_constexpr_vec() {
920; CHECK-LABEL: @all_constant_true_undef_false_constexpr_vec(
921; CHECK-NEXT:    [[S:%.*]] = select i1 ptrtoint (<2 x i32> ()* @all_constant_true_undef_false_constexpr_vec to i1), <2 x i32> undef, <2 x i32> <i32 -1, i32 ptrtoint (<2 x i32> ()* @all_constant_true_undef_false_constexpr_vec to i32)>
922; CHECK-NEXT:    ret <2 x i32> [[S]]
923;
924  %s = select i1 ptrtoint (<2 x i32> ()* @all_constant_true_undef_false_constexpr_vec to i1), <2 x i32> undef, <2 x i32><i32 -1, i32 ptrtoint (<2 x i32> ()* @all_constant_true_undef_false_constexpr_vec to i32)>
925  ret <2 x i32> %s
926}
927
928define i1 @expand_binop_undef(i32 %x, i32 %y) {
929; CHECK-LABEL: @expand_binop_undef(
930; CHECK-NEXT:    [[CMP9_NOT_1:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
931; CHECK-NEXT:    [[CMP15:%.*]] = icmp slt i32 [[X]], [[Y]]
932; CHECK-NEXT:    [[SPEC_SELECT39:%.*]] = select i1 [[CMP9_NOT_1]], i1 undef, i1 [[CMP15]]
933; CHECK-NEXT:    [[SPEC_SELECT40:%.*]] = xor i1 [[CMP9_NOT_1]], true
934; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = and i1 [[SPEC_SELECT39]], [[SPEC_SELECT40]]
935; CHECK-NEXT:    ret i1 [[SPEC_SELECT]]
936;
937  %cmp9.not.1 = icmp eq i32 %x, %y
938  %cmp15 = icmp slt i32 %x, %y
939  %spec.select39 = select i1 %cmp9.not.1, i1 undef, i1 %cmp15
940  %spec.select40 = xor i1 %cmp9.not.1, 1
941  %spec.select  = and i1 %spec.select39, %spec.select40
942  ret i1 %spec.select
943}
944
945define i32 @pr47322_more_poisonous_replacement(i32 %arg) {
946; CHECK-LABEL: @pr47322_more_poisonous_replacement(
947; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ARG:%.*]], 0
948; CHECK-NEXT:    [[TRAILING:%.*]] = call i32 @llvm.cttz.i32(i32 [[ARG]], i1 immarg true)
949; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[ARG]], [[TRAILING]]
950; CHECK-NEXT:    [[R1_SROA_0_1:%.*]] = select i1 [[CMP]], i32 0, i32 [[SHIFTED]]
951; CHECK-NEXT:    ret i32 [[R1_SROA_0_1]]
952;
953  %cmp = icmp eq i32 %arg, 0
954  %trailing = call i32 @llvm.cttz.i32(i32 %arg, i1 immarg true)
955  %shifted = lshr i32 %arg, %trailing
956  %r1.sroa.0.1 = select i1 %cmp, i32 0, i32 %shifted
957  ret i32 %r1.sroa.0.1
958}
959declare i32 @llvm.cttz.i32(i32, i1 immarg)
960
961; Partial undef scalable vectors should be ignored.
962define <vscale x 2 x i1> @ignore_scalable_undef(<vscale x 2 x i1> %cond) {
963; CHECK-LABEL: @ignore_scalable_undef(
964; CHECK-NEXT:    [[S:%.*]] = select <vscale x 2 x i1> [[COND:%.*]], <vscale x 2 x i1> undef, <vscale x 2 x i1> insertelement (<vscale x 2 x i1> undef, i1 true, i32 0)
965; CHECK-NEXT:    ret <vscale x 2 x i1> [[S]]
966;
967  %vec = insertelement <vscale x 2 x i1> undef, i1 true, i32 0
968  %s = select <vscale x 2 x i1> %cond, <vscale x 2 x i1> undef, <vscale x 2 x i1> %vec
969  ret <vscale x 2 x i1> %s
970}
971
972; TODO: these can be optimized more
973
974define i32 @poison(i32 %x, i32 %y) {
975; CHECK-LABEL: @poison(
976; CHECK-NEXT:    ret i32 [[X:%.*]]
977;
978  %v = select i1 undef, i32 %x, i32 %y
979  ret i32 %v
980}
981
982define i32 @poison2(i1 %cond, i32 %x) {
983; CHECK-LABEL: @poison2(
984; CHECK-NEXT:    [[V:%.*]] = select i1 [[COND:%.*]], i32 poison, i32 [[X:%.*]]
985; CHECK-NEXT:    ret i32 [[V]]
986;
987  %v = select i1 %cond, i32 poison, i32 %x
988  ret i32 %v
989}
990
991define i32 @poison3(i1 %cond, i32 %x) {
992; CHECK-LABEL: @poison3(
993; CHECK-NEXT:    [[V:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 poison
994; CHECK-NEXT:    ret i32 [[V]]
995;
996  %v = select i1 %cond, i32 %x, i32 poison
997  ret i32 %v
998}
999
1000define <2 x i32> @poison4(<2 x i1> %cond, <2 x i32> %x) {
1001; CHECK-LABEL: @poison4(
1002; CHECK-NEXT:    [[V:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> [[X:%.*]], <2 x i32> poison
1003; CHECK-NEXT:    ret <2 x i32> [[V]]
1004;
1005  %v = select <2 x i1> %cond, <2 x i32> %x, <2 x i32> poison
1006  ret <2 x i32> %v
1007}
1008