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