blob: c4df76d4535904dc767b136a9ba6e536fc6914ce [file] [log] [blame]
Sanjay Patel8a2bf302016-07-18 20:06:51 +00001; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
David Majnemerc6a5e1d2014-11-27 06:32:46 +00002; RUN: opt < %s -instsimplify -S | FileCheck %s
3
Sanjay Patel6f7ac7e2017-08-30 14:04:57 +00004define <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
Haicheng Wu25f6c192017-10-02 23:43:52 +000020define <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
Sanjay Patel841ca952018-02-17 01:18:53 +000028; FIXME: Allow for undef elements in a constant vector condition.
29
30define <3 x i8> @vsel_undef_true_op(<3 x i8> %x, <3 x i8> %y) {
31; CHECK-LABEL: @vsel_undef_true_op(
32; CHECK-NEXT: [[S:%.*]] = select <3 x i1> <i1 true, i1 undef, i1 true>, <3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]]
33; CHECK-NEXT: ret <3 x i8> [[S]]
34;
35 %s = select <3 x i1><i1 1, i1 undef, i1 1>, <3 x i8> %x, <3 x i8> %y
36 ret <3 x i8> %s
37}
38
39define <3 x i4> @vsel_undef_false_op(<3 x i4> %x, <3 x i4> %y) {
40; CHECK-LABEL: @vsel_undef_false_op(
41; CHECK-NEXT: [[S:%.*]] = select <3 x i1> <i1 false, i1 undef, i1 undef>, <3 x i4> [[X:%.*]], <3 x i4> [[Y:%.*]]
42; CHECK-NEXT: ret <3 x i4> [[S]]
43;
44 %s = select <3 x i1><i1 0, i1 undef, i1 undef>, <3 x i4> %x, <3 x i4> %y
45 ret <3 x i4> %s
46}
47
David Majnemerc6a5e1d2014-11-27 06:32:46 +000048define i32 @test1(i32 %x) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +000049; CHECK-LABEL: @test1(
50; CHECK-NEXT: ret i32 %x
51;
David Majnemerc6a5e1d2014-11-27 06:32:46 +000052 %and = and i32 %x, 1
53 %cmp = icmp eq i32 %and, 0
54 %and1 = and i32 %x, -2
55 %and1.x = select i1 %cmp, i32 %and1, i32 %x
56 ret i32 %and1.x
David Majnemerc6a5e1d2014-11-27 06:32:46 +000057}
58
59define i32 @test2(i32 %x) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +000060; CHECK-LABEL: @test2(
61; CHECK-NEXT: ret i32 %x
62;
David Majnemerc6a5e1d2014-11-27 06:32:46 +000063 %and = and i32 %x, 1
64 %cmp = icmp ne i32 %and, 0
65 %and1 = and i32 %x, -2
66 %and1.x = select i1 %cmp, i32 %x, i32 %and1
67 ret i32 %and1.x
David Majnemerc6a5e1d2014-11-27 06:32:46 +000068}
69
70define i32 @test3(i32 %x) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +000071; CHECK-LABEL: @test3(
72; CHECK-NEXT: [[AND1:%.*]] = and i32 %x, -2
73; CHECK-NEXT: ret i32 [[AND1]]
74;
David Majnemerc6a5e1d2014-11-27 06:32:46 +000075 %and = and i32 %x, 1
76 %cmp = icmp ne i32 %and, 0
77 %and1 = and i32 %x, -2
78 %and1.x = select i1 %cmp, i32 %and1, i32 %x
79 ret i32 %and1.x
David Majnemerc6a5e1d2014-11-27 06:32:46 +000080}
81
David Majnemer0b6a0b02014-12-20 03:04:38 +000082define i32 @test4(i32 %X) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +000083; CHECK-LABEL: @test4(
84; CHECK-NEXT: [[OR:%.*]] = or i32 %X, -2147483648
85; CHECK-NEXT: ret i32 [[OR]]
86;
David Majnemer0b6a0b02014-12-20 03:04:38 +000087 %cmp = icmp slt i32 %X, 0
88 %or = or i32 %X, -2147483648
89 %cond = select i1 %cmp, i32 %X, i32 %or
90 ret i32 %cond
David Majnemer0b6a0b02014-12-20 03:04:38 +000091}
92
Craig Topperba691872017-08-10 01:02:02 +000093; Same as above, but the compare isn't canonical
Craig Topperba691872017-08-10 01:02:02 +000094define i32 @test4noncanon(i32 %X) {
95; CHECK-LABEL: @test4noncanon(
Craig Topperb1e4b1a2017-08-14 22:11:43 +000096; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
97; CHECK-NEXT: ret i32 [[OR]]
Craig Topperba691872017-08-10 01:02:02 +000098;
99 %cmp = icmp sle i32 %X, -1
100 %or = or i32 %X, -2147483648
101 %cond = select i1 %cmp, i32 %X, i32 %or
102 ret i32 %cond
103}
104
David Majnemer0b6a0b02014-12-20 03:04:38 +0000105define i32 @test5(i32 %X) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000106; CHECK-LABEL: @test5(
107; CHECK-NEXT: ret i32 %X
108;
David Majnemer0b6a0b02014-12-20 03:04:38 +0000109 %cmp = icmp slt i32 %X, 0
110 %or = or i32 %X, -2147483648
111 %cond = select i1 %cmp, i32 %or, i32 %X
112 ret i32 %cond
David Majnemer0b6a0b02014-12-20 03:04:38 +0000113}
114
115define i32 @test6(i32 %X) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000116; CHECK-LABEL: @test6(
117; CHECK-NEXT: [[AND:%.*]] = and i32 %X, 2147483647
118; CHECK-NEXT: ret i32 [[AND]]
119;
David Majnemer0b6a0b02014-12-20 03:04:38 +0000120 %cmp = icmp slt i32 %X, 0
121 %and = and i32 %X, 2147483647
122 %cond = select i1 %cmp, i32 %and, i32 %X
123 ret i32 %cond
David Majnemer0b6a0b02014-12-20 03:04:38 +0000124}
125
126define i32 @test7(i32 %X) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000127; CHECK-LABEL: @test7(
128; CHECK-NEXT: ret i32 %X
129;
David Majnemer0b6a0b02014-12-20 03:04:38 +0000130 %cmp = icmp slt i32 %X, 0
131 %and = and i32 %X, 2147483647
132 %cond = select i1 %cmp, i32 %X, i32 %and
133 ret i32 %cond
David Majnemer0b6a0b02014-12-20 03:04:38 +0000134}
135
136define i32 @test8(i32 %X) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000137; CHECK-LABEL: @test8(
138; CHECK-NEXT: ret i32 %X
139;
David Majnemer0b6a0b02014-12-20 03:04:38 +0000140 %cmp = icmp sgt i32 %X, -1
141 %or = or i32 %X, -2147483648
142 %cond = select i1 %cmp, i32 %X, i32 %or
143 ret i32 %cond
David Majnemer0b6a0b02014-12-20 03:04:38 +0000144}
145
146define i32 @test9(i32 %X) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000147; CHECK-LABEL: @test9(
148; CHECK-NEXT: [[OR:%.*]] = or i32 %X, -2147483648
149; CHECK-NEXT: ret i32 [[OR]]
150;
David Majnemer0b6a0b02014-12-20 03:04:38 +0000151 %cmp = icmp sgt i32 %X, -1
152 %or = or i32 %X, -2147483648
153 %cond = select i1 %cmp, i32 %or, i32 %X
154 ret i32 %cond
David Majnemer0b6a0b02014-12-20 03:04:38 +0000155}
156
Craig Topperba691872017-08-10 01:02:02 +0000157; Same as above, but the compare isn't canonical
Craig Topperba691872017-08-10 01:02:02 +0000158define i32 @test9noncanon(i32 %X) {
159; CHECK-LABEL: @test9noncanon(
Craig Topperb1e4b1a2017-08-14 22:11:43 +0000160; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
161; CHECK-NEXT: ret i32 [[OR]]
Craig Topperba691872017-08-10 01:02:02 +0000162;
163 %cmp = icmp sge i32 %X, 0
164 %or = or i32 %X, -2147483648
165 %cond = select i1 %cmp, i32 %or, i32 %X
166 ret i32 %cond
167}
168
David Majnemer0b6a0b02014-12-20 03:04:38 +0000169define i32 @test10(i32 %X) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000170; CHECK-LABEL: @test10(
171; CHECK-NEXT: ret i32 %X
172;
David Majnemer0b6a0b02014-12-20 03:04:38 +0000173 %cmp = icmp sgt i32 %X, -1
174 %and = and i32 %X, 2147483647
175 %cond = select i1 %cmp, i32 %and, i32 %X
176 ret i32 %cond
David Majnemer0b6a0b02014-12-20 03:04:38 +0000177}
178
179define i32 @test11(i32 %X) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000180; CHECK-LABEL: @test11(
181; CHECK-NEXT: [[AND:%.*]] = and i32 %X, 2147483647
182; CHECK-NEXT: ret i32 [[AND]]
183;
David Majnemer0b6a0b02014-12-20 03:04:38 +0000184 %cmp = icmp sgt i32 %X, -1
185 %and = and i32 %X, 2147483647
186 %cond = select i1 %cmp, i32 %X, i32 %and
187 ret i32 %cond
David Majnemer0b6a0b02014-12-20 03:04:38 +0000188}
189
Sanjay Patel5f3c7032016-07-20 23:40:01 +0000190define <2 x i8> @test11vec(<2 x i8> %X) {
191; CHECK-LABEL: @test11vec(
192; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> %X, <i8 127, i8 127>
193; CHECK-NEXT: ret <2 x i8> [[AND]]
194;
195 %cmp = icmp sgt <2 x i8> %X, <i8 -1, i8 -1>
196 %and = and <2 x i8> %X, <i8 127, i8 127>
197 %sel = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %and
198 ret <2 x i8> %sel
199}
200
Craig Topper58def1e2017-08-14 18:49:39 +0000201define i32 @test12(i32 %X) {
202; CHECK-LABEL: @test12(
Craig Topper0aa3a192017-08-14 21:39:51 +0000203; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3
204; CHECK-NEXT: ret i32 [[AND]]
Craig Topper58def1e2017-08-14 18:49:39 +0000205;
206 %cmp = icmp ult i32 %X, 4
207 %and = and i32 %X, 3
208 %cond = select i1 %cmp, i32 %X, i32 %and
209 ret i32 %cond
210}
211
212; Same as above, but the compare isn't canonical
Craig Topper58def1e2017-08-14 18:49:39 +0000213define i32 @test12noncanon(i32 %X) {
214; CHECK-LABEL: @test12noncanon(
Craig Topperb1e4b1a2017-08-14 22:11:43 +0000215; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3
216; CHECK-NEXT: ret i32 [[AND]]
Craig Topper58def1e2017-08-14 18:49:39 +0000217;
218 %cmp = icmp ule i32 %X, 3
219 %and = and i32 %X, 3
220 %cond = select i1 %cmp, i32 %X, i32 %and
221 ret i32 %cond
222}
223
Craig Topper58def1e2017-08-14 18:49:39 +0000224define i32 @test13(i32 %X) {
225; CHECK-LABEL: @test13(
Craig Topper0aa3a192017-08-14 21:39:51 +0000226; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3
227; CHECK-NEXT: ret i32 [[AND]]
Craig Topper58def1e2017-08-14 18:49:39 +0000228;
229 %cmp = icmp ugt i32 %X, 3
230 %and = and i32 %X, 3
231 %cond = select i1 %cmp, i32 %and, i32 %X
232 ret i32 %cond
233}
234
235; Same as above, but the compare isn't canonical
Craig Topper58def1e2017-08-14 18:49:39 +0000236define i32 @test13noncanon(i32 %X) {
237; CHECK-LABEL: @test13noncanon(
Craig Topperb1e4b1a2017-08-14 22:11:43 +0000238; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3
239; CHECK-NEXT: ret i32 [[AND]]
Craig Topper58def1e2017-08-14 18:49:39 +0000240;
241 %cmp = icmp uge i32 %X, 4
242 %and = and i32 %X, 3
243 %cond = select i1 %cmp, i32 %and, i32 %X
244 ret i32 %cond
245}
246
David Majnemerc6a5e1d2014-11-27 06:32:46 +0000247define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000248; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8(
249; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 8
250; CHECK-NEXT: ret i32 [[OR]]
251;
David Majnemerc6a5e1d2014-11-27 06:32:46 +0000252 %and = and i32 %x, 8
253 %cmp = icmp eq i32 %and, 0
254 %or = or i32 %x, 8
Sanjay Patel47c04f92016-07-19 20:47:00 +0000255 %sel = select i1 %cmp, i32 %or, i32 %x
256 ret i32 %sel
257}
258
259define i32 @select_icmp_and_8_eq_0_or_8_alt(i32 %x) {
260; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8_alt(
261; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 8
262; CHECK-NEXT: ret i32 [[OR]]
263;
264 %and = and i32 %x, 8
265 %cmp = icmp ne i32 %and, 0
266 %or = or i32 %x, 8
267 %sel = select i1 %cmp, i32 %x, i32 %or
268 ret i32 %sel
269}
270
271define i32 @select_icmp_and_8_ne_0_or_8(i32 %x) {
272; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8(
273; CHECK-NEXT: ret i32 %x
274;
275 %and = and i32 %x, 8
276 %cmp = icmp ne i32 %and, 0
277 %or = or i32 %x, 8
278 %sel = select i1 %cmp, i32 %or, i32 %x
279 ret i32 %sel
280}
281
282define i32 @select_icmp_and_8_ne_0_or_8_alt(i32 %x) {
283; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8_alt(
284; CHECK-NEXT: ret i32 %x
285;
286 %and = and i32 %x, 8
287 %cmp = icmp eq i32 %and, 0
288 %or = or i32 %x, 8
289 %sel = select i1 %cmp, i32 %x, i32 %or
290 ret i32 %sel
291}
292
293define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) {
294; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8(
295; CHECK-NEXT: [[AND1:%.*]] = and i32 %x, -9
296; CHECK-NEXT: ret i32 [[AND1]]
297;
298 %and = and i32 %x, 8
299 %cmp = icmp eq i32 %and, 0
300 %and1 = and i32 %x, -9
301 %sel = select i1 %cmp, i32 %x, i32 %and1
302 ret i32 %sel
303}
304
305define i32 @select_icmp_and_8_eq_0_and_not_8_alt(i32 %x) {
306; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8_alt(
307; CHECK-NEXT: [[AND1:%.*]] = and i32 %x, -9
308; CHECK-NEXT: ret i32 [[AND1]]
309;
310 %and = and i32 %x, 8
311 %cmp = icmp ne i32 %and, 0
312 %and1 = and i32 %x, -9
313 %sel = select i1 %cmp, i32 %and1, i32 %x
314 ret i32 %sel
315}
316
317define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) {
318; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8(
319; CHECK-NEXT: ret i32 %x
320;
321 %and = and i32 %x, 8
322 %cmp = icmp ne i32 %and, 0
323 %and1 = and i32 %x, -9
324 %sel = select i1 %cmp, i32 %x, i32 %and1
325 ret i32 %sel
326}
327
328define i32 @select_icmp_and_8_ne_0_and_not_8_alt(i32 %x) {
329; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_alt(
330; CHECK-NEXT: ret i32 %x
331;
332 %and = and i32 %x, 8
333 %cmp = icmp eq i32 %and, 0
334 %and1 = and i32 %x, -9
335 %sel = select i1 %cmp, i32 %and1, i32 %x
336 ret i32 %sel
David Majnemerc6a5e1d2014-11-27 06:32:46 +0000337}
338
Sanjay Pateld2ff6d72016-07-19 16:49:55 +0000339; PR28466: https://llvm.org/bugs/show_bug.cgi?id=28466
Sanjay Patel47c04f92016-07-19 20:47:00 +0000340; Each of the previous 8 patterns has a variant that replaces the
341; 'and' with a 'trunc' and the icmp eq/ne with icmp slt/sgt.
Sanjay Patel8b76ebe2016-07-19 17:07:35 +0000342
Sanjay Patel47c04f92016-07-19 20:47:00 +0000343define i32 @select_icmp_trunc_8_ne_0_or_128(i32 %x) {
344; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128(
Sanjay Patel8b76ebe2016-07-19 17:07:35 +0000345; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 128
Sanjay Patela3bfb4e2016-07-21 21:26:45 +0000346; CHECK-NEXT: ret i32 [[OR]]
Sanjay Patel8b76ebe2016-07-19 17:07:35 +0000347;
348 %trunc = trunc i32 %x to i8
Sanjay Patel47c04f92016-07-19 20:47:00 +0000349 %cmp = icmp sgt i8 %trunc, -1
Sanjay Patel8b76ebe2016-07-19 17:07:35 +0000350 %or = or i32 %x, 128
351 %sel = select i1 %cmp, i32 %or, i32 %x
352 ret i32 %sel
353}
Sanjay Pateld2ff6d72016-07-19 16:49:55 +0000354
Sanjay Patel47c04f92016-07-19 20:47:00 +0000355define i32 @select_icmp_trunc_8_ne_0_or_128_alt(i32 %x) {
356; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128_alt(
Sanjay Patel8b76ebe2016-07-19 17:07:35 +0000357; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 128
Sanjay Patela3bfb4e2016-07-21 21:26:45 +0000358; CHECK-NEXT: ret i32 [[OR]]
Sanjay Patel8b76ebe2016-07-19 17:07:35 +0000359;
360 %trunc = trunc i32 %x to i8
361 %cmp = icmp slt i8 %trunc, 0
362 %or = or i32 %x, 128
363 %sel = select i1 %cmp, i32 %x, i32 %or
364 ret i32 %sel
365}
366
Sanjay Patel47c04f92016-07-19 20:47:00 +0000367define i32 @select_icmp_trunc_8_eq_0_or_128(i32 %x) {
368; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128(
Sanjay Patela3bfb4e2016-07-21 21:26:45 +0000369; CHECK-NEXT: ret i32 %x
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000370;
Sanjay Patel47c04f92016-07-19 20:47:00 +0000371 %trunc = trunc i32 %x to i8
372 %cmp = icmp slt i8 %trunc, 0
373 %or = or i32 %x, 128
374 %sel = select i1 %cmp, i32 %or, i32 %x
375 ret i32 %sel
376}
377
378define i32 @select_icmp_trunc_8_eq_0_or_128_alt(i32 %x) {
379; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128_alt(
Sanjay Patela3bfb4e2016-07-21 21:26:45 +0000380; CHECK-NEXT: ret i32 %x
Sanjay Patel47c04f92016-07-19 20:47:00 +0000381;
382 %trunc = trunc i32 %x to i8
383 %cmp = icmp sgt i8 %trunc, -1
384 %or = or i32 %x, 128
385 %sel = select i1 %cmp, i32 %x, i32 %or
386 ret i32 %sel
387}
388
389define i32 @select_icmp_trunc_8_eq_0_and_not_8(i32 %x) {
390; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8(
Sanjay Patel47c04f92016-07-19 20:47:00 +0000391; CHECK-NEXT: [[AND:%.*]] = and i32 %x, -9
Sanjay Patela3bfb4e2016-07-21 21:26:45 +0000392; CHECK-NEXT: ret i32 [[AND]]
Sanjay Patel47c04f92016-07-19 20:47:00 +0000393;
394 %trunc = trunc i32 %x to i4
395 %cmp = icmp sgt i4 %trunc, -1
396 %and = and i32 %x, -9
397 %sel = select i1 %cmp, i32 %x, i32 %and
398 ret i32 %sel
399}
400
401define i32 @select_icmp_trunc_8_eq_0_and_not_8_alt(i32 %x) {
402; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8_alt(
Sanjay Patel47c04f92016-07-19 20:47:00 +0000403; CHECK-NEXT: [[AND:%.*]] = and i32 %x, -9
Sanjay Patela3bfb4e2016-07-21 21:26:45 +0000404; CHECK-NEXT: ret i32 [[AND]]
Sanjay Patel47c04f92016-07-19 20:47:00 +0000405;
406 %trunc = trunc i32 %x to i4
407 %cmp = icmp slt i4 %trunc, 0
408 %and = and i32 %x, -9
409 %sel = select i1 %cmp, i32 %and, i32 %x
410 ret i32 %sel
David Majnemerc6a5e1d2014-11-27 06:32:46 +0000411}
412
Sanjay Patel8b76ebe2016-07-19 17:07:35 +0000413define i32 @select_icmp_trunc_8_ne_0_and_not_8(i32 %x) {
414; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8(
Sanjay Patela3bfb4e2016-07-21 21:26:45 +0000415; CHECK-NEXT: ret i32 %x
Sanjay Patel8b76ebe2016-07-19 17:07:35 +0000416;
417 %trunc = trunc i32 %x to i4
418 %cmp = icmp slt i4 %trunc, 0
419 %and = and i32 %x, -9
420 %sel = select i1 %cmp, i32 %x, i32 %and
421 ret i32 %sel
422}
423
Sanjay Patel47c04f92016-07-19 20:47:00 +0000424define i32 @select_icmp_trunc_8_ne_0_and_not_8_alt(i32 %x) {
425; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt(
Sanjay Patela3bfb4e2016-07-21 21:26:45 +0000426; CHECK-NEXT: ret i32 %x
Sanjay Patel8b76ebe2016-07-19 17:07:35 +0000427;
428 %trunc = trunc i32 %x to i4
Sanjay Patel47c04f92016-07-19 20:47:00 +0000429 %cmp = icmp sgt i4 %trunc, -1
Sanjay Patel8b76ebe2016-07-19 17:07:35 +0000430 %and = and i32 %x, -9
431 %sel = select i1 %cmp, i32 %and, i32 %x
432 ret i32 %sel
433}
434
Sanjay Patel9eec5502016-07-21 20:11:08 +0000435; Make sure that at least a few of the same patterns are repeated with vector types.
436
437define <2 x i32> @select_icmp_and_8_ne_0_and_not_8_vec(<2 x i32> %x) {
438; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_vec(
439; CHECK-NEXT: ret <2 x i32> %x
440;
441 %and = and <2 x i32> %x, <i32 8, i32 8>
442 %cmp = icmp ne <2 x i32> %and, zeroinitializer
443 %and1 = and <2 x i32> %x, <i32 -9, i32 -9>
444 %sel = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %and1
445 ret <2 x i32> %sel
446}
447
448define <2 x i32> @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(<2 x i32> %x) {
449; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(
Sanjay Patela3bfb4e2016-07-21 21:26:45 +0000450; CHECK-NEXT: ret <2 x i32> %x
Sanjay Patel9eec5502016-07-21 20:11:08 +0000451;
452 %trunc = trunc <2 x i32> %x to <2 x i4>
453 %cmp = icmp sgt <2 x i4> %trunc, <i4 -1, i4 -1>
454 %and = and <2 x i32> %x, <i32 -9, i32 -9>
455 %sel = select <2 x i1> %cmp, <2 x i32> %and, <2 x i32> %x
456 ret <2 x i32> %sel
457}
458
459; Insert a bit from x into y? This should be possible in InstCombine, but not InstSimplify?
460
461define i32 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i32 %y) {
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000462; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8(
463; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 8
464; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
Sanjay Patel9eec5502016-07-21 20:11:08 +0000465; CHECK-NEXT: [[AND1:%.*]] = and i32 %y, -9
466; CHECK-NEXT: [[Y_AND1:%.*]] = select i1 [[CMP]], i32 %y, i32 [[AND1]]
467; CHECK-NEXT: ret i32 [[Y_AND1]]
468;
469 %and = and i32 %x, 8
470 %cmp = icmp eq i32 %and, 0
471 %and1 = and i32 %y, -9
472 %y.and1 = select i1 %cmp, i32 %y, i32 %and1
473 ret i32 %y.and1
474}
475
476define i64 @select_icmp_x_and_8_eq_0_y64_and_not_8(i32 %x, i64 %y) {
477; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y64_and_not_8(
478; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 8
479; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000480; CHECK-NEXT: [[AND1:%.*]] = and i64 %y, -9
481; CHECK-NEXT: [[Y_AND1:%.*]] = select i1 [[CMP]], i64 %y, i64 [[AND1]]
482; CHECK-NEXT: ret i64 [[Y_AND1]]
483;
David Majnemerc6a5e1d2014-11-27 06:32:46 +0000484 %and = and i32 %x, 8
485 %cmp = icmp eq i32 %and, 0
486 %and1 = and i64 %y, -9
487 %y.and1 = select i1 %cmp, i64 %y, i64 %and1
488 ret i64 %y.and1
489}
490
Sanjay Patel9eec5502016-07-21 20:11:08 +0000491define i64 @select_icmp_x_and_8_ne_0_y64_and_not_8(i32 %x, i64 %y) {
492; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y64_and_not_8(
Sanjay Patel8a2bf302016-07-18 20:06:51 +0000493; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 8
494; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
495; CHECK-NEXT: [[AND1:%.*]] = and i64 %y, -9
496; CHECK-NEXT: [[AND1_Y:%.*]] = select i1 [[CMP]], i64 [[AND1]], i64 %y
497; CHECK-NEXT: ret i64 [[AND1_Y]]
498;
David Majnemerc6a5e1d2014-11-27 06:32:46 +0000499 %and = and i32 %x, 8
500 %cmp = icmp eq i32 %and, 0
501 %and1 = and i64 %y, -9
502 %and1.y = select i1 %cmp, i64 %and1, i64 %y
503 ret i64 %and1.y
504}
505
Sanjay Patele9fc79b2016-07-21 21:56:00 +0000506; Don't crash on a pointer or aggregate type.
507
508define i32* @select_icmp_pointers(i32* %x, i32* %y) {
509; CHECK-LABEL: @select_icmp_pointers(
510; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32* %x, null
511; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32* %x, i32* %y
512; CHECK-NEXT: ret i32* [[SEL]]
513;
514 %cmp = icmp slt i32* %x, null
515 %sel = select i1 %cmp, i32* %x, i32* %y
516 ret i32* %sel
517}
518
Sanjay Patel51783632017-01-13 17:02:42 +0000519; If the condition is known, we don't need to select, but we're not
520; doing this fold here to avoid compile-time cost.
Sanjay Patel95faecb2017-01-05 00:40:52 +0000521
522declare void @llvm.assume(i1)
523
524define i8 @assume_sel_cond(i1 %cond, i8 %x, i8 %y) {
525; CHECK-LABEL: @assume_sel_cond(
526; CHECK-NEXT: call void @llvm.assume(i1 %cond)
527; CHECK-NEXT: [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y
528; CHECK-NEXT: ret i8 [[SEL]]
529;
530 call void @llvm.assume(i1 %cond)
531 %sel = select i1 %cond, i8 %x, i8 %y
532 ret i8 %sel
533}
534
535define i8 @do_not_assume_sel_cond(i1 %cond, i8 %x, i8 %y) {
536; CHECK-LABEL: @do_not_assume_sel_cond(
537; CHECK-NEXT: [[NOTCOND:%.*]] = icmp eq i1 %cond, false
538; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]])
539; CHECK-NEXT: [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y
540; CHECK-NEXT: ret i8 [[SEL]]
541;
542 %notcond = icmp eq i1 %cond, false
543 call void @llvm.assume(i1 %notcond)
544 %sel = select i1 %cond, i8 %x, i8 %y
545 ret i8 %sel
546}
547