xref: /llvm-project/llvm/test/Transforms/InstCombine/select-icmp-and.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4;; ((X & 27) ? 27 : 0)
5
6define i41 @test5(i41 %X) {
7; CHECK-LABEL: @test5(
8; CHECK-NEXT:    [[Y:%.*]] = and i41 [[X:%.*]], 32
9; CHECK-NEXT:    ret i41 [[Y]]
10;
11  %Y = and i41 %X, 32
12  %t = icmp ne i41 %Y, 0
13  %V = select i1 %t, i41 32, i41 0
14  ret i41 %V
15}
16
17;; ((X & 27) ? 27 : 0)
18
19define i1023 @test6(i1023 %X) {
20; CHECK-LABEL: @test6(
21; CHECK-NEXT:    [[Y:%.*]] = and i1023 [[X:%.*]], 64
22; CHECK-NEXT:    ret i1023 [[Y]]
23;
24  %Y = and i1023 %X, 64
25  %t = icmp ne i1023 %Y, 0
26  %V = select i1 %t, i1023 64, i1023 0
27  ret i1023 %V
28}
29
30define i32 @test35(i32 %x) {
31; CHECK-LABEL: @test35(
32; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
33; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 60, i32 100
34; CHECK-NEXT:    ret i32 [[COND]]
35;
36  %cmp = icmp sge i32 %x, 0
37  %cond = select i1 %cmp, i32 60, i32 100
38  ret i32 %cond
39}
40
41define <2 x i32> @test35vec(<2 x i32> %x) {
42; CHECK-LABEL: @test35vec(
43; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 -1)
44; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> splat (i32 60), <2 x i32> splat (i32 100)
45; CHECK-NEXT:    ret <2 x i32> [[COND]]
46;
47  %cmp = icmp sge <2 x i32> %x, <i32 0, i32 0>
48  %cond = select <2 x i1> %cmp, <2 x i32> <i32 60, i32 60>, <2 x i32> <i32 100, i32 100>
49  ret <2 x i32> %cond
50}
51
52; Make sure we can still perform this optimization with a truncate present
53define i32 @test35_with_trunc(i64 %x) {
54; CHECK-LABEL: @test35_with_trunc(
55; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[X:%.*]], 2147483648
56; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[TMP1]], 0
57; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 60, i32 100
58; CHECK-NEXT:    ret i32 [[COND]]
59;
60  %x1 = trunc i64 %x to i32
61  %cmp = icmp sge i32 %x1, 0
62  %cond = select i1 %cmp, i32 60, i32 100
63  ret i32 %cond
64}
65
66define i32 @test36(i32 %x) {
67; CHECK-LABEL: @test36(
68; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
69; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 60, i32 100
70; CHECK-NEXT:    ret i32 [[COND]]
71;
72  %cmp = icmp slt i32 %x, 0
73  %cond = select i1 %cmp, i32 60, i32 100
74  ret i32 %cond
75}
76
77define <2 x i32> @test36vec(<2 x i32> %x) {
78; CHECK-LABEL: @test36vec(
79; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
80; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> splat (i32 60), <2 x i32> splat (i32 100)
81; CHECK-NEXT:    ret <2 x i32> [[COND]]
82;
83  %cmp = icmp slt <2 x i32> %x, <i32 0, i32 0>
84  %cond = select <2 x i1> %cmp, <2 x i32> <i32 60, i32 60>, <2 x i32> <i32 100, i32 100>
85  ret <2 x i32> %cond
86}
87
88define i32 @test37(i32 %x) {
89; CHECK-LABEL: @test37(
90; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
91; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 1, i32 -1
92; CHECK-NEXT:    ret i32 [[COND]]
93;
94  %cmp = icmp sgt i32 %x, -1
95  %cond = select i1 %cmp, i32 1, i32 -1
96  ret i32 %cond
97}
98
99define <2 x i32> @test37vec(<2 x i32> %x) {
100; CHECK-LABEL: @test37vec(
101; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 -1)
102; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> splat (i32 1), <2 x i32> splat (i32 -1)
103; CHECK-NEXT:    ret <2 x i32> [[COND]]
104;
105  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
106  %cond = select <2 x i1> %cmp, <2 x i32> <i32 1, i32 1>, <2 x i32> <i32 -1, i32 -1>
107  ret <2 x i32> %cond
108}
109
110define i32 @test65(i64 %x) {
111; CHECK-LABEL: @test65(
112; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[X:%.*]], 16
113; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i64 [[TMP1]], 0
114; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[DOTNOT]], i32 42, i32 40
115; CHECK-NEXT:    ret i32 [[TMP2]]
116;
117  %1 = and i64 %x, 16
118  %2 = icmp ne i64 %1, 0
119  %3 = select i1 %2, i32 40, i32 42
120  ret i32 %3
121}
122
123define <2 x i32> @test65vec(<2 x i64> %x) {
124; CHECK-LABEL: @test65vec(
125; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i64> [[X:%.*]], splat (i64 16)
126; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer
127; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[DOTNOT]], <2 x i32> splat (i32 42), <2 x i32> splat (i32 40)
128; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
129;
130  %1 = and <2 x i64> %x, <i64 16, i64 16>
131  %2 = icmp ne <2 x i64> %1, zeroinitializer
132  %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>
133  ret <2 x i32> %3
134}
135
136define i32 @test66(i64 %x) {
137; CHECK-LABEL: @test66(
138; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[X:%.*]], 4294967296
139; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i64 [[TMP1]], 0
140; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[DOTNOT]], i32 42, i32 40
141; CHECK-NEXT:    ret i32 [[TMP2]]
142;
143  %1 = and i64 %x, 4294967296
144  %2 = icmp ne i64 %1, 0
145  %3 = select i1 %2, i32 40, i32 42
146  ret i32 %3
147}
148
149define <2 x i32> @test66vec(<2 x i64> %x) {
150; CHECK-LABEL: @test66vec(
151; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i64> [[X:%.*]], splat (i64 4294967296)
152; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer
153; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[DOTNOT]], <2 x i32> splat (i32 42), <2 x i32> splat (i32 40)
154; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
155;
156  %1 = and <2 x i64> %x, <i64 4294967296, i64 4294967296>
157  %2 = icmp ne <2 x i64> %1, zeroinitializer
158  %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>
159  ret <2 x i32> %3
160}
161
162; Make sure we don't try to optimize a scalar 'and' with a vector select.
163define <2 x i32> @test66vec_scalar_and(i64 %x) {
164; CHECK-LABEL: @test66vec_scalar_and(
165; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[X:%.*]], 4294967296
166; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i64 [[TMP1]], 0
167; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[DOTNOT]], <2 x i32> splat (i32 42), <2 x i32> splat (i32 40)
168; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
169;
170  %1 = and i64 %x, 4294967296
171  %2 = icmp ne i64 %1, 0
172  %3 = select i1 %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>
173  ret <2 x i32> %3
174}
175
176define i32 @test67(i16 %x) {
177; CHECK-LABEL: @test67(
178; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[X:%.*]], 4
179; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i16 [[TMP1]], 0
180; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[DOTNOT]], i32 42, i32 40
181; CHECK-NEXT:    ret i32 [[TMP2]]
182;
183  %1 = and i16 %x, 4
184  %2 = icmp ne i16 %1, 0
185  %3 = select i1 %2, i32 40, i32 42
186  ret i32 %3
187}
188
189define <2 x i32> @test67vec(<2 x i16> %x) {
190; CHECK-LABEL: @test67vec(
191; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], splat (i16 4)
192; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq <2 x i16> [[TMP1]], zeroinitializer
193; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[DOTNOT]], <2 x i32> splat (i32 42), <2 x i32> splat (i32 40)
194; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
195;
196  %1 = and <2 x i16> %x, <i16 4, i16 4>
197  %2 = icmp ne <2 x i16> %1, zeroinitializer
198  %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>
199  ret <2 x i32> %3
200}
201
202define i32 @test71(i32 %x) {
203; CHECK-LABEL: @test71(
204; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 128
205; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
206; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[DOTNOT]], i32 42, i32 40
207; CHECK-NEXT:    ret i32 [[TMP2]]
208;
209  %1 = and i32 %x, 128
210  %2 = icmp ne i32 %1, 0
211  %3 = select i1 %2, i32 40, i32 42
212  ret i32 %3
213}
214
215define <2 x i32> @test71vec(<2 x i32> %x) {
216; CHECK-LABEL: @test71vec(
217; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 128)
218; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
219; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[DOTNOT]], <2 x i32> splat (i32 42), <2 x i32> splat (i32 40)
220; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
221;
222  %1 = and <2 x i32> %x, <i32 128, i32 128>
223  %2 = icmp ne <2 x i32> %1, <i32 0, i32 0>
224  %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>
225  ret <2 x i32> %3
226}
227
228define i32 @test72(i32 %x) {
229; CHECK-LABEL: @test72(
230; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 128
231; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
232; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP2]], i32 40, i32 42
233; CHECK-NEXT:    ret i32 [[TMP3]]
234;
235  %1 = and i32 %x, 128
236  %2 = icmp eq i32 %1, 0
237  %3 = select i1 %2, i32 40, i32 42
238  ret i32 %3
239}
240
241define <2 x i32> @test72vec(<2 x i32> %x) {
242; CHECK-LABEL: @test72vec(
243; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 128)
244; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
245; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> splat (i32 40), <2 x i32> splat (i32 42)
246; CHECK-NEXT:    ret <2 x i32> [[TMP3]]
247;
248  %1 = and <2 x i32> %x, <i32 128, i32 128>
249  %2 = icmp eq <2 x i32> %1, <i32 0, i32 0>
250  %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>
251  ret <2 x i32> %3
252}
253
254define i32 @test73(i32 %x) {
255; CHECK-LABEL: @test73(
256; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 128
257; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
258; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP2]], i32 40, i32 42
259; CHECK-NEXT:    ret i32 [[TMP3]]
260;
261  %1 = trunc i32 %x to i8
262  %2 = icmp sgt i8 %1, -1
263  %3 = select i1 %2, i32 40, i32 42
264  ret i32 %3
265}
266
267define <2 x i32> @test73vec(<2 x i32> %x) {
268; CHECK-LABEL: @test73vec(
269; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 128)
270; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
271; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> splat (i32 40), <2 x i32> splat (i32 42)
272; CHECK-NEXT:    ret <2 x i32> [[TMP3]]
273;
274  %1 = trunc <2 x i32> %x to <2 x i8>
275  %2 = icmp sgt <2 x i8> %1, <i8 -1, i8 -1>
276  %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>
277  ret <2 x i32> %3
278}
279
280define i32 @test74(i32 %x) {
281; CHECK-LABEL: @test74(
282; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -1
283; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 40, i32 42
284; CHECK-NEXT:    ret i32 [[TMP2]]
285;
286  %1 = icmp sgt i32 %x, -1
287  %2 = select i1 %1, i32 40, i32 42
288  ret i32 %2
289}
290
291define <2 x i32> @test74vec(<2 x i32> %x) {
292; CHECK-LABEL: @test74vec(
293; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 -1)
294; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> splat (i32 40), <2 x i32> splat (i32 42)
295; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
296;
297  %1 = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
298  %2 = select <2 x i1> %1, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>
299  ret <2 x i32> %2
300}
301
302define i64 @test75(i32 %X) {
303; CHECK-LABEL: @test75(
304; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
305; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i64 0, i64 8
306; CHECK-NEXT:    ret i64 [[TMP2]]
307;
308  %1 = icmp slt i32 %X, 0
309  %2 = select i1 %1, i64 0, i64 8
310  ret i64 %2
311}
312
313;; Code sequence for (X & 16) ? 16 : 0
314define i32 @test15a(i32 %X) {
315; CHECK-LABEL: @test15a(
316; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 16
317; CHECK-NEXT:    ret i32 [[T1]]
318;
319  %t1 = and i32 %X, 16
320  %t2 = icmp eq i32 %t1, 0
321  %t3 = select i1 %t2, i32 0, i32 16
322  ret i32 %t3
323}
324
325;; Code sequence for (X & 32) ? 0 : 24
326define i32 @test15b(i32 %X) {
327; CHECK-LABEL: @test15b(
328; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 32
329; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[T1]], 32
330; CHECK-NEXT:    ret i32 [[T3]]
331;
332  %t1 = and i32 %X, 32
333  %t2 = icmp eq i32 %t1, 0
334  %t3 = select i1 %t2, i32 32, i32 0
335  ret i32 %t3
336}
337
338;; Alternate code sequence for (X & 16) ? 16 : 0
339define i32 @test15c(i32 %X) {
340; CHECK-LABEL: @test15c(
341; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 16
342; CHECK-NEXT:    ret i32 [[T1]]
343;
344  %t1 = and i32 %X, 16
345  %t2 = icmp eq i32 %t1, 16
346  %t3 = select i1 %t2, i32 16, i32 0
347  ret i32 %t3
348}
349
350;; Alternate code sequence for (X & 16) ? 16 : 0
351define i32 @test15d(i32 %X) {
352; CHECK-LABEL: @test15d(
353; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 16
354; CHECK-NEXT:    ret i32 [[T1]]
355;
356  %t1 = and i32 %X, 16
357  %t2 = icmp ne i32 %t1, 0
358  %t3 = select i1 %t2, i32 16, i32 0
359  ret i32 %t3
360}
361
362;; (a & 128) ? 256 : 0
363define i32 @test15e(i32 %X) {
364; CHECK-LABEL: @test15e(
365; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[X:%.*]], 1
366; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T1]], 256
367; CHECK-NEXT:    ret i32 [[T3]]
368;
369  %t1 = and i32 %X, 128
370  %t2 = icmp ne i32 %t1, 0
371  %t3 = select i1 %t2, i32 256, i32 0
372  ret i32 %t3
373}
374
375;; (a & 128) ? 0 : 256
376define i32 @test15f(i32 %X) {
377; CHECK-LABEL: @test15f(
378; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[X:%.*]], 1
379; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[T1]], 256
380; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[TMP1]], 256
381; CHECK-NEXT:    ret i32 [[T3]]
382;
383  %t1 = and i32 %X, 128
384  %t2 = icmp ne i32 %t1, 0
385  %t3 = select i1 %t2, i32 0, i32 256
386  ret i32 %t3
387}
388
389;; (a & 8) ? -1 : -9
390define i32 @test15g(i32 %X) {
391; CHECK-LABEL: @test15g(
392; CHECK-NEXT:    [[T3:%.*]] = or i32 [[X:%.*]], -9
393; CHECK-NEXT:    ret i32 [[T3]]
394;
395  %t1 = and i32 %X, 8
396  %t2 = icmp ne i32 %t1, 0
397  %t3 = select i1 %t2, i32 -1, i32 -9
398  ret i32 %t3
399}
400
401;; (a & 8) ? -9 : -1
402define i32 @test15h(i32 %X) {
403; CHECK-LABEL: @test15h(
404; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 8
405; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[T1]], -1
406; CHECK-NEXT:    ret i32 [[T3]]
407;
408  %t1 = and i32 %X, 8
409  %t2 = icmp ne i32 %t1, 0
410  %t3 = select i1 %t2, i32 -9, i32 -1
411  ret i32 %t3
412}
413
414;; (a & 2) ? 577 : 1089
415define i32 @test15i(i32 %X) {
416; CHECK-LABEL: @test15i(
417; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 2
418; CHECK-NEXT:    [[T2_NOT:%.*]] = icmp eq i32 [[T1]], 0
419; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T2_NOT]], i32 1089, i32 577
420; CHECK-NEXT:    ret i32 [[T3]]
421;
422  %t1 = and i32 %X, 2
423  %t2 = icmp ne i32 %t1, 0
424  %t3 = select i1 %t2, i32 577, i32 1089
425  ret i32 %t3
426}
427
428;; (a & 2) ? 1089 : 577
429define i32 @test15j(i32 %X) {
430; CHECK-LABEL: @test15j(
431; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 2
432; CHECK-NEXT:    [[T2_NOT:%.*]] = icmp eq i32 [[T1]], 0
433; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T2_NOT]], i32 577, i32 1089
434; CHECK-NEXT:    ret i32 [[T3]]
435;
436  %t1 = and i32 %X, 2
437  %t2 = icmp ne i32 %t1, 0
438  %t3 = select i1 %t2, i32 1089, i32 577
439  ret i32 %t3
440}
441
442declare void @use1(i1)
443
444; (X & 8) == 0 ? -3 : -11 --> (X & 8) ^ -3
445; Extra cmp use ensures that cmp predicate canonicalization is thwarted.
446
447define i32 @clear_to_set(i32 %x) {
448; CHECK-LABEL: @clear_to_set(
449; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 8
450; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
451; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[T1]], -3
452; CHECK-NEXT:    call void @use1(i1 [[T2]])
453; CHECK-NEXT:    ret i32 [[T3]]
454;
455  %t1 = and i32 %x, 8
456  %t2 = icmp eq i32 %t1, 0
457  %t3 = select i1 %t2, i32 -3, i32 -11
458  call void @use1(i1 %t2)
459  ret i32 %t3
460}
461
462; (X & 8) == 0 ? -11 : -3 --> (X & 8) | -11
463; Extra cmp use ensures that cmp predicate canonicalization is thwarted.
464
465define i32 @clear_to_clear(i32 %x) {
466; CHECK-LABEL: @clear_to_clear(
467; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 8
468; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
469; CHECK-NEXT:    [[T3:%.*]] = or disjoint i32 [[T1]], -11
470; CHECK-NEXT:    call void @use1(i1 [[T2]])
471; CHECK-NEXT:    ret i32 [[T3]]
472;
473  %t1 = and i32 %x, 8
474  %t2 = icmp eq i32 %t1, 0
475  %t3 = select i1 %t2, i32 -11, i32 -3
476  call void @use1(i1 %t2)
477  ret i32 %t3
478}
479
480; (X & 8) != 0 ? -3 : -11 --> (X & 8) | -11
481; Extra cmp use ensures that cmp predicate canonicalization is thwarted.
482
483define i32 @set_to_set(i32 %x) {
484; CHECK-LABEL: @set_to_set(
485; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 8
486; CHECK-NEXT:    [[T2:%.*]] = icmp ne i32 [[T1]], 0
487; CHECK-NEXT:    [[T3:%.*]] = or disjoint i32 [[T1]], -11
488; CHECK-NEXT:    call void @use1(i1 [[T2]])
489; CHECK-NEXT:    ret i32 [[T3]]
490;
491  %t1 = and i32 %x, 8
492  %t2 = icmp ne i32 %t1, 0
493  %t3 = select i1 %t2, i32 -3, i32 -11
494  call void @use1(i1 %t2)
495  ret i32 %t3
496}
497
498; (X & 8) != 0 ? -3 : -11 --> (X & 8) ^ -3
499; Extra cmp use ensures that cmp predicate canonicalization is thwarted.
500
501define i32 @set_to_clear(i32 %x) {
502; CHECK-LABEL: @set_to_clear(
503; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 8
504; CHECK-NEXT:    [[T2:%.*]] = icmp ne i32 [[T1]], 0
505; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[T1]], -3
506; CHECK-NEXT:    call void @use1(i1 [[T2]])
507; CHECK-NEXT:    ret i32 [[T3]]
508;
509  %t1 = and i32 %x, 8
510  %t2 = icmp ne i32 %t1, 0
511  %t3 = select i1 %t2, i32 -11, i32 -3
512  call void @use1(i1 %t2)
513  ret i32 %t3
514}
515
516; (X & 128) == 0 ? 131 : 3 --> (X & 128) ^ 131
517
518define i8 @clear_to_set_decomposebittest(i8 %x) {
519; CHECK-LABEL: @clear_to_set_decomposebittest(
520; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -128
521; CHECK-NEXT:    [[T3:%.*]] = xor i8 [[TMP1]], -125
522; CHECK-NEXT:    ret i8 [[T3]]
523;
524  %t2 = icmp sgt i8 %x, -1
525  %t3 = select i1 %t2, i8 131, i8 3
526  ret i8 %t3
527}
528
529; (X & 128) == 0 ? 3 : 131 --> (X & 128) | 3
530
531define i8 @clear_to_clear_decomposebittest(i8 %x) {
532; CHECK-LABEL: @clear_to_clear_decomposebittest(
533; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -128
534; CHECK-NEXT:    [[T3:%.*]] = or disjoint i8 [[TMP1]], 3
535; CHECK-NEXT:    ret i8 [[T3]]
536;
537  %t2 = icmp sgt i8 %x, -1
538  %t3 = select i1 %t2, i8 3, i8 131
539  ret i8 %t3
540}
541
542; (X & 128) != 0 ? 131 : 3 --> (X & 128) | 3
543
544define i8 @set_to_set_decomposebittest(i8 %x) {
545; CHECK-LABEL: @set_to_set_decomposebittest(
546; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -128
547; CHECK-NEXT:    [[T3:%.*]] = or disjoint i8 [[TMP1]], 3
548; CHECK-NEXT:    ret i8 [[T3]]
549;
550  %t2 = icmp slt i8 %x, 0
551  %t3 = select i1 %t2, i8 131, i8 3
552  ret i8 %t3
553}
554
555; (X & 128) != 0 ? 3 : 131 --> (X & 128) ^ 131
556
557define i8 @set_to_clear_decomposebittest(i8 %x) {
558; CHECK-LABEL: @set_to_clear_decomposebittest(
559; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -128
560; CHECK-NEXT:    [[T3:%.*]] = xor i8 [[TMP1]], -125
561; CHECK-NEXT:    ret i8 [[T3]]
562;
563  %t2 = icmp slt i8 %x, 0
564  %t3 = select i1 %t2, i8 3, i8 131
565  ret i8 %t3
566}
567
568; (X & 128) == 0 ? 131 : 3 --> (X & 128) ^ 131
569; Extra cmp use to verify that we are not creating extra instructions.
570
571define i8 @clear_to_set_decomposebittest_extra_use(i8 %x) {
572; CHECK-LABEL: @clear_to_set_decomposebittest_extra_use(
573; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[X:%.*]], -1
574; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T2]], i8 -125, i8 3
575; CHECK-NEXT:    call void @use1(i1 [[T2]])
576; CHECK-NEXT:    ret i8 [[T3]]
577;
578  %t2 = icmp sgt i8 %x, -1
579  %t3 = select i1 %t2, i8 131, i8 3
580  call void @use1(i1 %t2)
581  ret i8 %t3
582}
583
584; (X & 128) == 0 ? 3 : 131 --> (X & 128) | 3
585; Extra cmp use to verify that we are not creating extra instructions.
586
587define i8 @clear_to_clear_decomposebittest_extra_use(i8 %x) {
588; CHECK-LABEL: @clear_to_clear_decomposebittest_extra_use(
589; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[X:%.*]], -1
590; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T2]], i8 3, i8 -125
591; CHECK-NEXT:    call void @use1(i1 [[T2]])
592; CHECK-NEXT:    ret i8 [[T3]]
593;
594  %t2 = icmp sgt i8 %x, -1
595  %t3 = select i1 %t2, i8 3, i8 131
596  call void @use1(i1 %t2)
597  ret i8 %t3
598}
599
600; (X & 128) != 0 ? 131 : 3 --> (X & 128) | 3
601; Extra cmp use to verify that we are not creating extra instructions.
602
603define i8 @set_to_set_decomposebittest_extra_use(i8 %x) {
604; CHECK-LABEL: @set_to_set_decomposebittest_extra_use(
605; CHECK-NEXT:    [[T2:%.*]] = icmp slt i8 [[X:%.*]], 0
606; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T2]], i8 -125, i8 3
607; CHECK-NEXT:    call void @use1(i1 [[T2]])
608; CHECK-NEXT:    ret i8 [[T3]]
609;
610  %t2 = icmp slt i8 %x, 0
611  %t3 = select i1 %t2, i8 131, i8 3
612  call void @use1(i1 %t2)
613  ret i8 %t3
614}
615
616; (X & 128) != 0 ? 3 : 131 --> (X & 128) ^ 131
617; Extra cmp use to verify that we are not creating extra instructions.
618
619define i8 @set_to_clear_decomposebittest_extra_use(i8 %x) {
620; CHECK-LABEL: @set_to_clear_decomposebittest_extra_use(
621; CHECK-NEXT:    [[T2:%.*]] = icmp slt i8 [[X:%.*]], 0
622; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T2]], i8 3, i8 -125
623; CHECK-NEXT:    call void @use1(i1 [[T2]])
624; CHECK-NEXT:    ret i8 [[T3]]
625;
626  %t2 = icmp slt i8 %x, 0
627  %t3 = select i1 %t2, i8 3, i8 131
628  call void @use1(i1 %t2)
629  ret i8 %t3
630}
631
632define i32 @select_bittest_to_add(i32 %x) {
633; CHECK-LABEL: @select_bittest_to_add(
634; CHECK-NEXT:  entry:
635; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1
636; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[AND]], 3
637; CHECK-NEXT:    ret i32 [[RET]]
638;
639entry:
640  %and = and i32 %x, 1
641  %cmp = icmp eq i32 %and, 0
642  %ret = select i1 %cmp, i32 3, i32 4
643  ret i32 %ret
644}
645
646define i32 @select_bittest_to_sub(i32 %x) {
647; CHECK-LABEL: @select_bittest_to_sub(
648; CHECK-NEXT:  entry:
649; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1
650; CHECK-NEXT:    [[RET:%.*]] = sub nuw nsw i32 4, [[AND]]
651; CHECK-NEXT:    ret i32 [[RET]]
652;
653entry:
654  %and = and i32 %x, 1
655  %cmp = icmp eq i32 %and, 0
656  %ret = select i1 %cmp, i32 4, i32 3
657  ret i32 %ret
658}
659
660define i32 @select_bittest_to_shl(i32 %x) {
661; CHECK-LABEL: @select_bittest_to_shl(
662; CHECK-NEXT:  entry:
663; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1
664; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
665; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 2, i32 4
666; CHECK-NEXT:    ret i32 [[RET]]
667;
668entry:
669  %and = and i32 %x, 1
670  %cmp = icmp eq i32 %and, 0
671  %ret = select i1 %cmp, i32 2, i32 4
672  ret i32 %ret
673}
674
675define i32 @select_bittest_to_lshr(i32 %x) {
676; CHECK-LABEL: @select_bittest_to_lshr(
677; CHECK-NEXT:  entry:
678; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1
679; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
680; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 4, i32 2
681; CHECK-NEXT:    ret i32 [[RET]]
682;
683entry:
684  %and = and i32 %x, 1
685  %cmp = icmp eq i32 %and, 0
686  %ret = select i1 %cmp, i32 4, i32 2
687  ret i32 %ret
688}
689
690define i32 @select_bittest_to_ashr(i32 %x) {
691; CHECK-LABEL: @select_bittest_to_ashr(
692; CHECK-NEXT:  entry:
693; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2
694; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
695; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 -4, i32 -1
696; CHECK-NEXT:    ret i32 [[RET]]
697;
698entry:
699  %and = and i32 %x, 2
700  %cmp = icmp eq i32 %and, 0
701  %ret = select i1 %cmp, i32 -4, i32 -1
702  ret i32 %ret
703}
704
705define i32 @select_bittest_to_shl_negative_test(i32 %x) {
706; CHECK-LABEL: @select_bittest_to_shl_negative_test(
707; CHECK-NEXT:    [[MASK:%.*]] = and i32 [[X:%.*]], 1
708; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[MASK]], 0
709; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i32 4, i32 6
710; CHECK-NEXT:    ret i32 [[RES]]
711;
712  %mask = and i32 %x, 1
713  %cond = icmp eq i32 %mask, 0
714  %y = select i1 %cond, i32 2, i32 4
715  %res = add nuw nsw i32 %y, 2
716  ret i32 %res
717}
718