xref: /llvm-project/llvm/test/Transforms/InstCombine/select.ll (revision dcdf44aca7be8a3e8f36d308b7fd5e5979140574)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; PR1822
5
6target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64"
7
8define i1 @test5(i1 %C) {
9; CHECK-LABEL: @test5(
10; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
11; CHECK-NEXT:    ret i1 [[NOT_C]]
12;
13  %V = select i1 %C, i1 false, i1 true
14  ret i1 %V
15}
16
17define i32 @test6(i1 %C) {
18; CHECK-LABEL: @test6(
19; CHECK-NEXT:    [[V:%.*]] = zext i1 [[C:%.*]] to i32
20; CHECK-NEXT:    ret i32 [[V]]
21;
22  %V = select i1 %C, i32 1, i32 0
23  ret i32 %V
24}
25
26define i1 @trueval_is_true(i1 %C, i1 %X) {
27; CHECK-LABEL: @trueval_is_true(
28; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[X:%.*]]
29; CHECK-NEXT:    ret i1 [[R]]
30;
31  %R = select i1 %C, i1 true, i1 %X
32  ret i1 %R
33}
34
35define <2 x i1> @trueval_is_true_vec(<2 x i1> %C, <2 x i1> %X) {
36; CHECK-LABEL: @trueval_is_true_vec(
37; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[X:%.*]]
38; CHECK-NEXT:    ret <2 x i1> [[R]]
39;
40  %R = select <2 x i1> %C, <2 x i1> <i1 true, i1 true>, <2 x i1> %X
41  ret <2 x i1> %R
42}
43
44define <2 x i1> @trueval_is_true_vec_poison_elt(<2 x i1> %C, <2 x i1> %X) {
45; CHECK-LABEL: @trueval_is_true_vec_poison_elt(
46; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 poison, i1 true>, <2 x i1> [[X:%.*]]
47; CHECK-NEXT:    ret <2 x i1> [[R]]
48;
49  %R = select <2 x i1> %C, <2 x i1> <i1 poison, i1 true>, <2 x i1> %X
50  ret <2 x i1> %R
51}
52
53define i1 @test8(i1 %C, i1 %X) {
54; CHECK-LABEL: @test8(
55; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 false
56; CHECK-NEXT:    ret i1 [[R]]
57;
58  %R = select i1 %C, i1 %X, i1 false
59  ret i1 %R
60}
61
62define <2 x i1> @test8vec(<2 x i1> %C, <2 x i1> %X) {
63; CHECK-LABEL: @test8vec(
64; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]], <2 x i1> zeroinitializer
65; CHECK-NEXT:    ret <2 x i1> [[R]]
66;
67  %R = select <2 x i1> %C, <2 x i1> %X, <2 x i1> <i1 false, i1 false>
68  ret <2 x i1> %R
69}
70
71define <vscale x 2 x i1> @test8vvec(<vscale x 2 x i1> %C, <vscale x 2 x i1> %X) {
72; CHECK-LABEL: @test8vvec(
73; CHECK-NEXT:    [[R:%.*]] = select <vscale x 2 x i1> [[C:%.*]], <vscale x 2 x i1> [[X:%.*]], <vscale x 2 x i1> zeroinitializer
74; CHECK-NEXT:    ret <vscale x 2 x i1> [[R]]
75;
76  %R = select <vscale x 2 x i1> %C, <vscale x 2 x i1> %X, <vscale x 2 x i1> zeroinitializer
77  ret <vscale x 2 x i1> %R
78}
79
80define i1 @test9(i1 %C, i1 %X) {
81; CHECK-LABEL: @test9(
82; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
83; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOT_C]], i1 [[X:%.*]], i1 false
84; CHECK-NEXT:    ret i1 [[R]]
85;
86  %R = select i1 %C, i1 false, i1 %X
87  ret i1 %R
88}
89
90define <2 x i1> @test9vec(<2 x i1> %C, <2 x i1> %X) {
91; CHECK-LABEL: @test9vec(
92; CHECK-NEXT:    [[NOT_C:%.*]] = xor <2 x i1> [[C:%.*]], splat (i1 true)
93; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[NOT_C]], <2 x i1> [[X:%.*]], <2 x i1> zeroinitializer
94; CHECK-NEXT:    ret <2 x i1> [[R]]
95;
96  %R = select <2 x i1> %C, <2 x i1> <i1 false, i1 false>, <2 x i1> %X
97  ret <2 x i1> %R
98}
99
100define <vscale x 2 x i1> @test9vvec(<vscale x 2 x i1> %C, <vscale x 2 x i1> %X) {
101; CHECK-LABEL: @test9vvec(
102; CHECK-NEXT:    [[NOT_C:%.*]] = xor <vscale x 2 x i1> [[C:%.*]], splat (i1 true)
103; CHECK-NEXT:    [[R:%.*]] = select <vscale x 2 x i1> [[NOT_C]], <vscale x 2 x i1> [[X:%.*]], <vscale x 2 x i1> zeroinitializer
104; CHECK-NEXT:    ret <vscale x 2 x i1> [[R]]
105;
106  %R = select <vscale x 2 x i1> %C, <vscale x 2 x i1> zeroinitializer, <vscale x 2 x i1> %X
107  ret <vscale x 2 x i1> %R
108}
109
110define i1 @test10(i1 %C, i1 %X) {
111; CHECK-LABEL: @test10(
112; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
113; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[X:%.*]]
114; CHECK-NEXT:    ret i1 [[R]]
115;
116  %R = select i1 %C, i1 %X, i1 true
117  ret i1 %R
118}
119
120define <2 x i1> @test10vec(<2 x i1> %C, <2 x i1> %X) {
121; CHECK-LABEL: @test10vec(
122; CHECK-NEXT:    [[NOT_C:%.*]] = xor <2 x i1> [[C:%.*]], splat (i1 true)
123; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[NOT_C]], <2 x i1> splat (i1 true), <2 x i1> [[X:%.*]]
124; CHECK-NEXT:    ret <2 x i1> [[R]]
125;
126  %R = select <2 x i1> %C, <2 x i1> %X, <2 x i1> <i1 true, i1 true>
127  ret <2 x i1> %R
128}
129
130define i1 @test23(i1 %a, i1 %b) {
131; CHECK-LABEL: @test23(
132; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
133; CHECK-NEXT:    ret i1 [[C]]
134;
135  %c = select i1 %a, i1 %b, i1 %a
136  ret i1 %c
137}
138
139define <2 x i1> @test23vec(<2 x i1> %a, <2 x i1> %b) {
140; CHECK-LABEL: @test23vec(
141; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
142; CHECK-NEXT:    ret <2 x i1> [[C]]
143;
144  %c = select <2 x i1> %a, <2 x i1> %b, <2 x i1> %a
145  ret <2 x i1> %c
146}
147
148define i1 @test24(i1 %a, i1 %b) {
149; CHECK-LABEL: @test24(
150; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
151; CHECK-NEXT:    ret i1 [[C]]
152;
153  %c = select i1 %a, i1 %a, i1 %b
154  ret i1 %c
155}
156
157define <2 x i1> @test24vec(<2 x i1> %a, <2 x i1> %b) {
158; CHECK-LABEL: @test24vec(
159; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]]
160; CHECK-NEXT:    ret <2 x i1> [[C]]
161;
162  %c = select <2 x i1> %a, <2 x i1> %a, <2 x i1> %b
163  ret <2 x i1> %c
164}
165
166define i1 @test62(i1 %A, i1 %B) {
167; CHECK-LABEL: @test62(
168; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
169; CHECK-NEXT:    [[C:%.*]] = select i1 [[NOT_A]], i1 [[B:%.*]], i1 false
170; CHECK-NEXT:    ret i1 [[C]]
171;
172  %not = xor i1 %A, true
173  %C = select i1 %A, i1 %not, i1 %B
174  ret i1 %C
175}
176
177define <2 x i1> @test62vec(<2 x i1> %A, <2 x i1> %B) {
178; CHECK-LABEL: @test62vec(
179; CHECK-NEXT:    [[NOT_A:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true)
180; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[NOT_A]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
181; CHECK-NEXT:    ret <2 x i1> [[C]]
182;
183  %not = xor <2 x i1> %A, <i1 true, i1 true>
184  %C = select <2 x i1> %A, <2 x i1> %not, <2 x i1> %B
185  ret <2 x i1> %C
186}
187
188define i1 @test63(i1 %A, i1 %B) {
189; CHECK-LABEL: @test63(
190; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
191; CHECK-NEXT:    [[C:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[B:%.*]]
192; CHECK-NEXT:    ret i1 [[C]]
193;
194  %not = xor i1 %A, true
195  %C = select i1 %A, i1 %B, i1 %not
196  ret i1 %C
197}
198
199define <2 x i1> @test63vec(<2 x i1> %A, <2 x i1> %B) {
200; CHECK-LABEL: @test63vec(
201; CHECK-NEXT:    [[NOT_A:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true)
202; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[NOT_A]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]]
203; CHECK-NEXT:    ret <2 x i1> [[C]]
204;
205  %not = xor <2 x i1> %A, <i1 true, i1 true>
206  %C = select <2 x i1> %A, <2 x i1> %B, <2 x i1> %not
207  ret <2 x i1> %C
208}
209
210define i32 @test11(i32 %a) {
211; CHECK-LABEL: @test11(
212; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
213; CHECK-NEXT:    [[R:%.*]] = zext i1 [[C]] to i32
214; CHECK-NEXT:    ret i32 [[R]]
215;
216  %C = icmp eq i32 %a, 0
217  %R = select i1 %C, i32 0, i32 1
218  ret i32 %R
219}
220
221define i32 @test12(i1 %cond, i32 %a) {
222; CHECK-LABEL: @test12(
223; CHECK-NEXT:    [[B:%.*]] = zext i1 [[COND:%.*]] to i32
224; CHECK-NEXT:    [[C:%.*]] = or i32 [[A:%.*]], [[B]]
225; CHECK-NEXT:    ret i32 [[C]]
226;
227  %b = or i32 %a, 1
228  %c = select i1 %cond, i32 %b, i32 %a
229  ret i32 %c
230}
231
232define <2 x i32> @test12vec(<2 x i1> %cond, <2 x i32> %a) {
233; CHECK-LABEL: @test12vec(
234; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[COND:%.*]] to <2 x i32>
235; CHECK-NEXT:    [[C:%.*]] = or <2 x i32> [[A:%.*]], [[B]]
236; CHECK-NEXT:    ret <2 x i32> [[C]]
237;
238  %b = or <2 x i32> %a, <i32 1, i32 1>
239  %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %a
240  ret <2 x i32> %c
241}
242
243define i32 @test12a(i1 %cond, i32 %a) {
244; CHECK-LABEL: @test12a(
245; CHECK-NEXT:    [[B:%.*]] = zext i1 [[COND:%.*]] to i32
246; CHECK-NEXT:    [[C:%.*]] = ashr i32 [[A:%.*]], [[B]]
247; CHECK-NEXT:    ret i32 [[C]]
248;
249  %b = ashr i32 %a, 1
250  %c = select i1 %cond, i32 %b, i32 %a
251  ret i32 %c
252}
253
254define <2 x i32> @test12avec(<2 x i1> %cond, <2 x i32> %a) {
255; CHECK-LABEL: @test12avec(
256; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[COND:%.*]] to <2 x i32>
257; CHECK-NEXT:    [[C:%.*]] = ashr <2 x i32> [[A:%.*]], [[B]]
258; CHECK-NEXT:    ret <2 x i32> [[C]]
259;
260  %b = ashr <2 x i32> %a, <i32 1, i32 1>
261  %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %a
262  ret <2 x i32> %c
263}
264
265define i32 @test12b(i1 %cond, i32 %a) {
266; CHECK-LABEL: @test12b(
267; CHECK-NEXT:    [[NOT_COND:%.*]] = xor i1 [[COND:%.*]], true
268; CHECK-NEXT:    [[B:%.*]] = zext i1 [[NOT_COND]] to i32
269; CHECK-NEXT:    [[D:%.*]] = ashr i32 [[A:%.*]], [[B]]
270; CHECK-NEXT:    ret i32 [[D]]
271;
272  %b = ashr i32 %a, 1
273  %d = select i1 %cond, i32 %a, i32 %b
274  ret i32 %d
275}
276
277define <2 x i32> @test12bvec(<2 x i1> %cond, <2 x i32> %a) {
278; CHECK-LABEL: @test12bvec(
279; CHECK-NEXT:    [[NOT_COND:%.*]] = xor <2 x i1> [[COND:%.*]], splat (i1 true)
280; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[NOT_COND]] to <2 x i32>
281; CHECK-NEXT:    [[D:%.*]] = ashr <2 x i32> [[A:%.*]], [[B]]
282; CHECK-NEXT:    ret <2 x i32> [[D]]
283;
284  %b = ashr <2 x i32> %a, <i32 1, i32 1>
285  %d = select <2 x i1> %cond, <2 x i32> %a, <2 x i32> %b
286  ret <2 x i32> %d
287}
288
289define i32 @test13(i32 %a, i32 %b) {
290; CHECK-LABEL: @test13(
291; CHECK-NEXT:    ret i32 [[B:%.*]]
292;
293  %C = icmp eq i32 %a, %b
294  %V = select i1 %C, i32 %a, i32 %b
295  ret i32 %V
296}
297
298define i32 @test13a(i32 %a, i32 %b) {
299; CHECK-LABEL: @test13a(
300; CHECK-NEXT:    ret i32 [[A:%.*]]
301;
302  %C = icmp ne i32 %a, %b
303  %V = select i1 %C, i32 %a, i32 %b
304  ret i32 %V
305}
306
307define i32 @test13b(i32 %a, i32 %b) {
308; CHECK-LABEL: @test13b(
309; CHECK-NEXT:    ret i32 [[A:%.*]]
310;
311  %C = icmp eq i32 %a, %b
312  %V = select i1 %C, i32 %b, i32 %a
313  ret i32 %V
314}
315
316define i1 @test14a(i1 %C, i32 %X) {
317; CHECK-LABEL: @test14a(
318; CHECK-NEXT:    [[R1:%.*]] = icmp slt i32 [[X:%.*]], 1
319; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
320; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[R1]]
321; CHECK-NEXT:    ret i1 [[R]]
322;
323  %V = select i1 %C, i32 %X, i32 0
324  ; (X < 1) | !C
325  %R = icmp slt i32 %V, 1
326  ret i1 %R
327}
328
329define i1 @test14b(i1 %C, i32 %X) {
330; CHECK-LABEL: @test14b(
331; CHECK-NEXT:    [[R1:%.*]] = icmp slt i32 [[X:%.*]], 1
332; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[R1]]
333; CHECK-NEXT:    ret i1 [[R]]
334;
335  %V = select i1 %C, i32 0, i32 %X
336  ; (X < 1) | C
337  %R = icmp slt i32 %V, 1
338  ret i1 %R
339}
340
341define i32 @test16(i1 %C, ptr %P) {
342; CHECK-LABEL: @test16(
343; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
344; CHECK-NEXT:    ret i32 [[V]]
345;
346  %P2 = select i1 %C, ptr %P, ptr null
347  %V = load i32, ptr %P2
348  ret i32 %V
349}
350
351;; It may be legal to load from a null address in a non-zero address space
352define i32 @test16_neg(i1 %C, ptr addrspace(1) %P) {
353; CHECK-LABEL: @test16_neg(
354; CHECK-NEXT:    [[P2:%.*]] = select i1 [[C:%.*]], ptr addrspace(1) [[P:%.*]], ptr addrspace(1) null
355; CHECK-NEXT:    [[V:%.*]] = load i32, ptr addrspace(1) [[P2]], align 4
356; CHECK-NEXT:    ret i32 [[V]]
357;
358  %P2 = select i1 %C, ptr addrspace(1) %P, ptr addrspace(1) null
359  %V = load i32, ptr addrspace(1) %P2
360  ret i32 %V
361}
362
363define i32 @test16_neg2(i1 %C, ptr addrspace(1) %P) {
364; CHECK-LABEL: @test16_neg2(
365; CHECK-NEXT:    [[P2:%.*]] = select i1 [[C:%.*]], ptr addrspace(1) null, ptr addrspace(1) [[P:%.*]]
366; CHECK-NEXT:    [[V:%.*]] = load i32, ptr addrspace(1) [[P2]], align 4
367; CHECK-NEXT:    ret i32 [[V]]
368;
369  %P2 = select i1 %C, ptr addrspace(1) null, ptr addrspace(1) %P
370  %V = load i32, ptr addrspace(1) %P2
371  ret i32 %V
372}
373
374;; It may be legal to load from a null address with null pointer valid attribute.
375define i32 @test16_no_null_opt(i1 %C, ptr %P) #0 {
376; CHECK-LABEL: @test16_no_null_opt(
377; CHECK-NEXT:    [[P2:%.*]] = select i1 [[C:%.*]], ptr [[P:%.*]], ptr null
378; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P2]], align 4
379; CHECK-NEXT:    ret i32 [[V]]
380;
381  %P2 = select i1 %C, ptr %P, ptr null
382  %V = load i32, ptr %P2
383  ret i32 %V
384}
385
386define i32 @test16_no_null_opt_2(i1 %C, ptr %P) #0 {
387; CHECK-LABEL: @test16_no_null_opt_2(
388; CHECK-NEXT:    [[P2:%.*]] = select i1 [[C:%.*]], ptr null, ptr [[P:%.*]]
389; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P2]], align 4
390; CHECK-NEXT:    ret i32 [[V]]
391;
392  %P2 = select i1 %C, ptr null, ptr %P
393  %V = load i32, ptr %P2
394  ret i32 %V
395}
396
397attributes #0 = { null_pointer_is_valid }
398
399define i1 @test17(ptr %X, i1 %C) {
400; CHECK-LABEL: @test17(
401; CHECK-NEXT:    [[RV1:%.*]] = icmp eq ptr [[X:%.*]], null
402; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
403; CHECK-NEXT:    [[RV:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[RV1]]
404; CHECK-NEXT:    ret i1 [[RV]]
405;
406  %R = select i1 %C, ptr %X, ptr null
407  %RV = icmp eq ptr %R, null
408  ret i1 %RV
409}
410
411define i32 @test18(i32 %X, i32 %Y, i1 %C) {
412; CHECK-LABEL: @test18(
413; CHECK-NEXT:    [[V:%.*]] = sdiv i32 [[Y:%.*]], [[X:%.*]]
414; CHECK-NEXT:    ret i32 [[V]]
415;
416  %R = select i1 %C, i32 %X, i32 0
417  %V = sdiv i32 %Y, %R
418  ret i32 %V
419}
420
421define i32 @test19(i32 %x) {
422; CHECK-LABEL: @test19(
423; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
424; CHECK-NEXT:    ret i32 [[X_LOBIT]]
425;
426  %t = icmp ugt i32 %x, 2147483647
427  %retval = select i1 %t, i32 -1, i32 0
428  ret i32 %retval
429}
430
431define i32 @test20(i32 %x) {
432; CHECK-LABEL: @test20(
433; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
434; CHECK-NEXT:    ret i32 [[X_LOBIT]]
435;
436  %t = icmp slt i32 %x, 0
437  %retval = select i1 %t, i32 -1, i32 0
438  ret i32 %retval
439}
440
441define i64 @test21(i32 %x) {
442; CHECK-LABEL: @test21(
443; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
444; CHECK-NEXT:    [[RETVAL:%.*]] = sext i32 [[X_LOBIT]] to i64
445; CHECK-NEXT:    ret i64 [[RETVAL]]
446;
447  %t = icmp slt i32 %x, 0
448  %retval = select i1 %t, i64 -1, i64 0
449  ret i64 %retval
450}
451
452define i16 @test22(i32 %x) {
453; CHECK-LABEL: @test22(
454; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
455; CHECK-NEXT:    [[RETVAL:%.*]] = trunc nsw i32 [[X_LOBIT]] to i16
456; CHECK-NEXT:    ret i16 [[RETVAL]]
457;
458  %t = icmp slt i32 %x, 0
459  %retval = select i1 %t, i16 -1, i16 0
460  ret i16 %retval
461}
462
463define i32 @test25(i1 %c)  {
464; CHECK-LABEL: @test25(
465; CHECK-NEXT:  entry:
466; CHECK-NEXT:    br i1 [[C:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
467; CHECK:       jump:
468; CHECK-NEXT:    br label [[RET]]
469; CHECK:       ret:
470; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 10, [[JUMP]] ], [ 20, [[ENTRY:%.*]] ]
471; CHECK-NEXT:    ret i32 [[B]]
472;
473entry:
474  br i1 %c, label %jump, label %ret
475jump:
476  br label %ret
477ret:
478  %a = phi i1 [true, %jump], [false, %entry]
479  %b = select i1 %a, i32 10, i32 20
480  ret i32 %b
481}
482
483define i32 @test26(i1 %cond)  {
484; CHECK-LABEL: @test26(
485; CHECK-NEXT:  entry:
486; CHECK-NEXT:    br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
487; CHECK:       jump:
488; CHECK-NEXT:    br label [[RET]]
489; CHECK:       ret:
490; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 20, [[ENTRY:%.*]] ], [ 10, [[JUMP]] ]
491; CHECK-NEXT:    ret i32 [[B]]
492;
493entry:
494  br i1 %cond, label %jump, label %ret
495jump:
496  %c = or i1 false, false
497  br label %ret
498ret:
499  %a = phi i1 [true, %entry], [%c, %jump]
500  %b = select i1 %a, i32 20, i32 10
501  ret i32 %b
502}
503
504define i32 @test26_logical(i1 %cond)  {
505; CHECK-LABEL: @test26_logical(
506; CHECK-NEXT:  entry:
507; CHECK-NEXT:    br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
508; CHECK:       jump:
509; CHECK-NEXT:    br label [[RET]]
510; CHECK:       ret:
511; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 20, [[ENTRY:%.*]] ], [ 10, [[JUMP]] ]
512; CHECK-NEXT:    ret i32 [[B]]
513;
514entry:
515  br i1 %cond, label %jump, label %ret
516jump:
517  %c = select i1 false, i1 true, i1 false
518  br label %ret
519ret:
520  %a = phi i1 [true, %entry], [%c, %jump]
521  %b = select i1 %a, i32 20, i32 10
522  ret i32 %b
523}
524
525define i32 @test27(i1 %c, i32 %A, i32 %B)  {
526; CHECK-LABEL: @test27(
527; CHECK-NEXT:  entry:
528; CHECK-NEXT:    br i1 [[C:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
529; CHECK:       jump:
530; CHECK-NEXT:    br label [[RET]]
531; CHECK:       ret:
532; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
533; CHECK-NEXT:    ret i32 [[S]]
534;
535entry:
536  br i1 %c, label %jump, label %ret
537jump:
538  br label %ret
539ret:
540  %p = phi i1 [true, %jump], [false, %entry]
541  %s = select i1 %p, i32 %A, i32 %B
542  ret i32 %s
543}
544
545define i32 @test28(i1 %cond, i32 %A, i32 %B)  {
546; CHECK-LABEL: @test28(
547; CHECK-NEXT:  entry:
548; CHECK-NEXT:    br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
549; CHECK:       jump:
550; CHECK-NEXT:    br label [[RET]]
551; CHECK:       ret:
552; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
553; CHECK-NEXT:    ret i32 [[S]]
554;
555entry:
556  br i1 %cond, label %jump, label %ret
557jump:
558  br label %ret
559ret:
560  %c = phi i32 [%A, %jump], [%B, %entry]
561  %p = phi i1 [true, %jump], [false, %entry]
562  %s = select i1 %p, i32 %A, i32 %c
563  ret i32 %s
564}
565
566define i32 @test29(i1 %cond, i32 %A, i32 %B)  {
567; CHECK-LABEL: @test29(
568; CHECK-NEXT:  entry:
569; CHECK-NEXT:    br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
570; CHECK:       jump:
571; CHECK-NEXT:    br label [[RET]]
572; CHECK:       ret:
573; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
574; CHECK-NEXT:    br label [[NEXT:%.*]]
575; CHECK:       next:
576; CHECK-NEXT:    ret i32 [[S]]
577;
578entry:
579  br i1 %cond, label %jump, label %ret
580jump:
581  br label %ret
582ret:
583  %c = phi i32 [%A, %jump], [%B, %entry]
584  %p = phi i1 [true, %jump], [false, %entry]
585  br label %next
586
587next:
588  %s = select i1 %p, i32 %A, i32 %c
589  ret i32 %s
590}
591
592; SMAX(SMAX(x, y), x) -> SMAX(x, y)
593define i32 @test30(i32 %x, i32 %y) {
594; CHECK-LABEL: @test30(
595; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
596; CHECK-NEXT:    ret i32 [[COND]]
597;
598  %cmp = icmp sgt i32 %x, %y
599  %cond = select i1 %cmp, i32 %x, i32 %y
600  %cmp5 = icmp sgt i32 %cond, %x
601  %retval = select i1 %cmp5, i32 %cond, i32 %x
602  ret i32 %retval
603}
604
605; UMAX(UMAX(x, y), x) -> UMAX(x, y)
606define i32 @test31(i32 %x, i32 %y) {
607; CHECK-LABEL: @test31(
608; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
609; CHECK-NEXT:    ret i32 [[COND]]
610;
611  %cmp = icmp ugt i32 %x, %y
612  %cond = select i1 %cmp, i32 %x, i32 %y
613  %cmp5 = icmp ugt i32 %cond, %x
614  %retval = select i1 %cmp5, i32 %cond, i32 %x
615  ret i32 %retval
616}
617
618; SMIN(SMIN(x, y), x) -> SMIN(x, y)
619define i32 @test32(i32 %x, i32 %y) {
620; CHECK-LABEL: @test32(
621; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
622; CHECK-NEXT:    ret i32 [[COND]]
623;
624  %cmp = icmp sgt i32 %x, %y
625  %cond = select i1 %cmp, i32 %y, i32 %x
626  %cmp5 = icmp sgt i32 %cond, %x
627  %retval = select i1 %cmp5, i32 %x, i32 %cond
628  ret i32 %retval
629}
630
631; MAX(MIN(x, y), x) -> x
632define i32 @test33(i32 %x, i32 %y) {
633; CHECK-LABEL: @test33(
634; CHECK-NEXT:    ret i32 [[X:%.*]]
635;
636  %cmp = icmp sgt i32 %x, %y
637  %cond = select i1 %cmp, i32 %y, i32 %x
638  %cmp5 = icmp sgt i32 %cond, %x
639  %retval = select i1 %cmp5, i32 %cond, i32 %x
640  ret i32 %retval
641}
642
643; MIN(MAX(x, y), x) -> x
644define i32 @test34(i32 %x, i32 %y) {
645; CHECK-LABEL: @test34(
646; CHECK-NEXT:    ret i32 [[X:%.*]]
647;
648  %cmp = icmp sgt i32 %x, %y
649  %cond = select i1 %cmp, i32 %x, i32 %y
650  %cmp5 = icmp sgt i32 %cond, %x
651  %retval = select i1 %cmp5, i32 %x, i32 %cond
652  ret i32 %retval
653}
654
655define i1 @test38(i1 %cond) {
656; CHECK-LABEL: @test38(
657; CHECK-NEXT:    ret i1 false
658;
659  %zero = alloca i32
660  %one = alloca i32
661  %ptr = select i1 %cond, ptr %zero, ptr %one
662  %isnull = icmp eq ptr %ptr, null
663  ret i1 %isnull
664}
665
666define i1 @test39(i1 %cond, double %x) {
667; CHECK-LABEL: @test39(
668; CHECK-NEXT:    ret i1 true
669;
670  %s = select i1 %cond, double %x, double 0x7FF0000000000000   ; RHS = +infty
671  %cmp = fcmp ule double %x, %s
672  ret i1 %cmp
673}
674
675define i1 @test40(i1 %cond) {
676; CHECK-LABEL: @test40(
677; CHECK-NEXT:    ret i1 false
678;
679  %a = alloca i32
680  %b = alloca i32
681  %c = alloca i32
682  %s = select i1 %cond, ptr %a, ptr %b
683  %r = icmp eq ptr %s, %c
684  ret i1 %r
685}
686
687define i32 @test41(i1 %cond, i32 %x, i32 %y) {
688; CHECK-LABEL: @test41(
689; CHECK-NEXT:    [[R:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
690; CHECK-NEXT:    ret i32 [[R]]
691;
692  %z = and i32 %x, %y
693  %s = select i1 %cond, i32 %y, i32 %z
694  %r = and i32 %x, %s
695  ret i32 %r
696}
697
698define i32 @test42(i32 %x, i32 %y) {
699; CHECK-LABEL: @test42(
700; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[X:%.*]], 0
701; CHECK-NEXT:    [[B:%.*]] = sext i1 [[COND]] to i32
702; CHECK-NEXT:    [[C:%.*]] = add i32 [[Y:%.*]], [[B]]
703; CHECK-NEXT:    ret i32 [[C]]
704;
705  %b = add i32 %y, -1
706  %cond = icmp eq i32 %x, 0
707  %c = select i1 %cond, i32 %b, i32 %y
708  ret i32 %c
709}
710
711define <2 x i32> @test42vec(<2 x i32> %x, <2 x i32> %y) {
712; CHECK-LABEL: @test42vec(
713; CHECK-NEXT:    [[COND:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer
714; CHECK-NEXT:    [[B:%.*]] = sext <2 x i1> [[COND]] to <2 x i32>
715; CHECK-NEXT:    [[C:%.*]] = add <2 x i32> [[Y:%.*]], [[B]]
716; CHECK-NEXT:    ret <2 x i32> [[C]]
717;
718  %b = add <2 x i32> %y, <i32 -1, i32 -1>
719  %cond = icmp eq <2 x i32> %x, zeroinitializer
720  %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %y
721  ret <2 x i32> %c
722}
723
724; PR8994
725
726; This select instruction can't be eliminated because trying to do so would
727; change the number of vector elements. This used to assert.
728define i48 @test51(<3 x i1> %icmp, <3 x i16> %t) {
729; CHECK-LABEL: @test51(
730; CHECK-NEXT:    [[SELECT:%.*]] = select <3 x i1> [[ICMP:%.*]], <3 x i16> zeroinitializer, <3 x i16> [[T:%.*]]
731; CHECK-NEXT:    [[T2:%.*]] = bitcast <3 x i16> [[SELECT]] to i48
732; CHECK-NEXT:    ret i48 [[T2]]
733;
734  %select = select <3 x i1> %icmp, <3 x i16> zeroinitializer, <3 x i16> %t
735  %t2 = bitcast <3 x i16> %select to i48
736  ret i48 %t2
737}
738
739define <vscale x 4 x float> @bitcast_select_bitcast(<vscale x 4 x i1> %icmp, <vscale x 4 x i32> %a, <vscale x 4 x float> %b) {
740; CHECK-LABEL: @bitcast_select_bitcast(
741; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <vscale x 4 x i32> [[A:%.*]] to <vscale x 4 x float>
742; CHECK-NEXT:    [[BC2:%.*]] = select <vscale x 4 x i1> [[ICMP:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> [[TMP1]]
743; CHECK-NEXT:    ret <vscale x 4 x float> [[BC2]]
744;
745  %bc1 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32>
746  %select = select <vscale x 4 x i1> %icmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %a
747  %bc2 = bitcast <vscale x 4 x i32> %select to <vscale x 4 x float>
748  ret <vscale x 4 x float> %bc2
749}
750
751define void @select_oneuse_bitcast(<vscale x 4 x float> %a, <vscale x 4 x float> %b, <vscale x 4 x i32> %c, <vscale x 4 x i32> %d, ptr %ptr1) {
752; CHECK-LABEL: @select_oneuse_bitcast(
753; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <vscale x 4 x i32> [[C:%.*]], [[D:%.*]]
754; CHECK-NEXT:    [[SEL1_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[A:%.*]], <vscale x 4 x float> [[B:%.*]]
755; CHECK-NEXT:    store <vscale x 4 x float> [[SEL1_V]], ptr [[PTR1:%.*]], align 16
756; CHECK-NEXT:    ret void
757;
758  %cmp = icmp ult <vscale x 4 x i32> %c, %d
759  %bc1 = bitcast <vscale x 4 x float> %a to <vscale x 4 x i32>
760  %bc2 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32>
761  %sel1 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %bc2
762  store <vscale x 4 x i32> %sel1, ptr %ptr1
763  ret void
764}
765
766; Allow select promotion even if there are multiple uses of bitcasted ops.
767; Hoisting the selects allows later pattern matching to see that these are min/max ops.
768
769define void @min_max_bitcast(<4 x float> %a, <4 x float> %b, ptr %ptr1, ptr %ptr2) {
770; CHECK-LABEL: @min_max_bitcast(
771; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <4 x float> [[A:%.*]], [[B:%.*]]
772; CHECK-NEXT:    [[SEL1_V:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[A]], <4 x float> [[B]]
773; CHECK-NEXT:    [[SEL2_V:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[B]], <4 x float> [[A]]
774; CHECK-NEXT:    store <4 x float> [[SEL1_V]], ptr [[PTR1:%.*]], align 16
775; CHECK-NEXT:    store <4 x float> [[SEL2_V]], ptr [[PTR2:%.*]], align 16
776; CHECK-NEXT:    ret void
777;
778  %cmp = fcmp olt <4 x float> %a, %b
779  %bc1 = bitcast <4 x float> %a to <4 x i32>
780  %bc2 = bitcast <4 x float> %b to <4 x i32>
781  %sel1 = select <4 x i1> %cmp, <4 x i32> %bc1, <4 x i32> %bc2
782  %sel2 = select <4 x i1> %cmp, <4 x i32> %bc2, <4 x i32> %bc1
783  store <4 x i32> %sel1, ptr %ptr1
784  store <4 x i32> %sel2, ptr %ptr2
785  ret void
786}
787
788define void @min_max_bitcast1(<vscale x 4 x float> %a, <vscale x 4 x float> %b, ptr %ptr1, ptr %ptr2) {
789; CHECK-LABEL: @min_max_bitcast1(
790; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <vscale x 4 x float> [[A:%.*]], [[B:%.*]]
791; CHECK-NEXT:    [[SEL1_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[A]], <vscale x 4 x float> [[B]]
792; CHECK-NEXT:    [[SEL2_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[B]], <vscale x 4 x float> [[A]]
793; CHECK-NEXT:    store <vscale x 4 x float> [[SEL1_V]], ptr [[PTR1:%.*]], align 16
794; CHECK-NEXT:    store <vscale x 4 x float> [[SEL2_V]], ptr [[PTR2:%.*]], align 16
795; CHECK-NEXT:    ret void
796;
797  %cmp = fcmp olt <vscale x 4 x float> %a, %b
798  %bc1 = bitcast <vscale x 4 x float> %a to <vscale x 4 x i32>
799  %bc2 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32>
800  %sel1 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %bc2
801  %sel2 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc2, <vscale x 4 x i32> %bc1
802  store <vscale x 4 x i32> %sel1, ptr %ptr1
803  store <vscale x 4 x i32> %sel2, ptr %ptr2
804  ret void
805}
806
807; To avoid potential backend problems, we don't do the same transform for other casts.
808
809define void @truncs_before_selects(<4 x float> %f1, <4 x float> %f2, <4 x i64> %a, <4 x i64> %b, ptr %ptr1, ptr %ptr2) {
810; CHECK-LABEL: @truncs_before_selects(
811; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <4 x float> [[F1:%.*]], [[F2:%.*]]
812; CHECK-NEXT:    [[BC1:%.*]] = trunc <4 x i64> [[A:%.*]] to <4 x i32>
813; CHECK-NEXT:    [[BC2:%.*]] = trunc <4 x i64> [[B:%.*]] to <4 x i32>
814; CHECK-NEXT:    [[SEL1:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[BC1]], <4 x i32> [[BC2]]
815; CHECK-NEXT:    [[SEL2:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[BC2]], <4 x i32> [[BC1]]
816; CHECK-NEXT:    store <4 x i32> [[SEL1]], ptr [[PTR1:%.*]], align 16
817; CHECK-NEXT:    store <4 x i32> [[SEL2]], ptr [[PTR2:%.*]], align 16
818; CHECK-NEXT:    ret void
819;
820  %cmp = fcmp olt <4 x float> %f1, %f2
821  %bc1 = trunc <4 x i64> %a to <4 x i32>
822  %bc2 = trunc <4 x i64> %b to <4 x i32>
823  %sel1 = select <4 x i1> %cmp, <4 x i32> %bc1, <4 x i32> %bc2
824  %sel2 = select <4 x i1> %cmp, <4 x i32> %bc2, <4 x i32> %bc1
825  store <4 x i32> %sel1, ptr %ptr1, align 16
826  store <4 x i32> %sel2, ptr %ptr2, align 16
827  ret void
828}
829
830; PR8575
831
832define i32 @test52(i32 %n, i32 %m) {
833; CHECK-LABEL: @test52(
834; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], [[M:%.*]]
835; CHECK-NEXT:    [[STOREMERGE:%.*]] = select i1 [[CMP]], i32 1, i32 6
836; CHECK-NEXT:    ret i32 [[STOREMERGE]]
837;
838  %cmp = icmp sgt i32 %n, %m
839  %. = select i1 %cmp, i32 1, i32 3
840  %add = add nsw i32 %., 3
841  %storemerge = select i1 %cmp, i32 %., i32 %add
842  ret i32 %storemerge
843}
844
845; PR9454
846
847define i32 @test53(i32 %x) {
848; CHECK-LABEL: @test53(
849; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -3
850; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
851; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 2, i32 1
852; CHECK-NEXT:    ret i32 [[SEL]]
853;
854  %and = and i32 %x, 2
855  %cmp = icmp eq i32 %and, %x
856  %sel = select i1 %cmp, i32 2, i32 1
857  ret i32 %sel
858}
859
860define i32 @test54(i32 %X, i32 %Y) {
861; CHECK-LABEL: @test54(
862; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
863; CHECK-NEXT:    [[C:%.*]] = zext i1 [[B]] to i32
864; CHECK-NEXT:    ret i32 [[C]]
865;
866  %A = ashr exact i32 %X, %Y
867  %B = icmp eq i32 %A, 0
868  %C = select i1 %B, i32 %A, i32 1
869  ret i32 %C
870}
871
872define i1 @test55(i1 %X, i32 %Y, i32 %Z) {
873; CHECK-LABEL: @test55(
874; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[Y:%.*]], 0
875; CHECK-NEXT:    ret i1 [[C]]
876;
877  %A = ashr exact i32 %Y, %Z
878  %B = select i1 %X, i32 %Y, i32 %A
879  %C = icmp eq i32 %B, 0
880  ret i1 %C
881}
882
883define i32 @test56(i16 %x) {
884; CHECK-LABEL: @test56(
885; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[X:%.*]] to i32
886; CHECK-NEXT:    ret i32 [[CONV]]
887;
888  %tobool = icmp eq i16 %x, 0
889  %conv = zext i16 %x to i32
890  %cond = select i1 %tobool, i32 0, i32 %conv
891  ret i32 %cond
892}
893
894define i32 @test57(i32 %x, i32 %y) {
895; CHECK-LABEL: @test57(
896; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
897; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[X]], 0
898; CHECK-NEXT:    [[DOTAND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 [[AND]]
899; CHECK-NEXT:    ret i32 [[DOTAND]]
900;
901  %and = and i32 %x, %y
902  %tobool = icmp eq i32 %x, 0
903  %.and = select i1 %tobool, i32 0, i32 %and
904  ret i32 %.and
905}
906
907define i32 @test58(i16 %x) {
908; CHECK-LABEL: @test58(
909; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[X:%.*]] to i32
910; CHECK-NEXT:    ret i32 [[CONV]]
911;
912  %tobool = icmp ne i16 %x, 1
913  %conv = zext i16 %x to i32
914  %cond = select i1 %tobool, i32 %conv, i32 1
915  ret i32 %cond
916}
917
918define i32 @test59(i32 %x, i32 %y) {
919; CHECK-LABEL: @test59(
920; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
921; CHECK-NEXT:    ret i32 [[AND]]
922;
923  %and = and i32 %x, %y
924  %tobool = icmp ne i32 %x, %y
925  %.and = select i1 %tobool, i32 %and, i32 %y
926  ret i32 %.and
927}
928
929define i1 @test60(i32 %x, ptr %y) {
930; CHECK-LABEL: @test60(
931; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
932; CHECK-NEXT:    [[LOAD:%.*]] = load i1, ptr [[Y:%.*]], align 1
933; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 1
934; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i1 [[LOAD]], i1 [[CMP1]]
935; CHECK-NEXT:    ret i1 [[SEL]]
936;
937  %cmp = icmp eq i32 %x, 0
938  %load = load i1, ptr %y, align 1
939  %cmp1 = icmp slt i32 %x, 1
940  %sel = select i1 %cmp, i1 %load, i1 %cmp1
941  ret i1 %sel
942}
943
944@glbl = constant i32 10
945define i32 @test61(ptr %ptr) {
946; CHECK-LABEL: @test61(
947; CHECK-NEXT:    ret i32 10
948;
949  %A = load i32, ptr %ptr
950  %B = icmp eq ptr %ptr, @glbl
951  %C = select i1 %B, i32 %A, i32 10
952  ret i32 %C
953}
954
955; PR14131
956define void @test64(i32 %p, i16 %b, i1 %c1) noreturn {
957; CHECK-LABEL: @test64(
958; CHECK-NEXT:  entry:
959; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LOR_RHS:%.*]], label [[LOR_END:%.*]]
960; CHECK:       lor.rhs:
961; CHECK-NEXT:    br label [[LOR_END]]
962; CHECK:       lor.end:
963; CHECK-NEXT:    br i1 poison, label [[COND_END17:%.*]], label [[COND_FALSE16:%.*]]
964; CHECK:       cond.false16:
965; CHECK-NEXT:    br label [[COND_END17]]
966; CHECK:       cond.end17:
967; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
968; CHECK:       while.body:
969; CHECK-NEXT:    br label [[WHILE_BODY]]
970;
971entry:
972  %p.addr.0.insert.mask = and i32 %p, -65536
973  %conv2 = and i32 %p, 65535
974  br i1 %c1, label %lor.rhs, label %lor.end
975
976lor.rhs:
977  %p.addr.0.extract.trunc = trunc i32 %p.addr.0.insert.mask to i16
978  %phitmp = zext i16 %p.addr.0.extract.trunc to i32
979  br label %lor.end
980
981lor.end:
982  %t.1 = phi i32 [ 0, %entry ], [ %phitmp, %lor.rhs ]
983  %conv6 = zext i16 %b to i32
984  %div = udiv i32 %conv6, %t.1
985  %tobool8 = icmp eq i32 %div, 0
986  %cmp = icmp eq i32 %t.1, 0
987  %cmp12 = icmp ult i32 %conv2, 2
988  %cmp.sink = select i1 %tobool8, i1 %cmp12, i1 %cmp
989  br i1 %cmp.sink, label %cond.end17, label %cond.false16
990
991cond.false16:
992  br label %cond.end17
993
994cond.end17:
995  br label %while.body
996
997while.body:
998  br label %while.body
999}
1000
1001@under_aligned = external global i32, align 1
1002
1003; The load here must not be speculated around the select. One side of the
1004; select is trivially dereferenceable but may have a lower alignment than the
1005; load does.
1006define i32 @test76(i1 %flag, ptr %x) {
1007; CHECK-LABEL: @test76(
1008; CHECK-NEXT:    store i32 0, ptr [[X:%.*]], align 4
1009; CHECK-NEXT:    [[P:%.*]] = select i1 [[FLAG:%.*]], ptr @under_aligned, ptr [[X]]
1010; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P]], align 4
1011; CHECK-NEXT:    ret i32 [[V]]
1012;
1013  store i32 0, ptr %x
1014  %p = select i1 %flag, ptr @under_aligned, ptr %x
1015  %v = load i32, ptr %p
1016  ret i32 %v
1017}
1018
1019declare void @scribble_on_i32(ptr)
1020
1021; The load here must not be speculated around the select. One side of the
1022; select is trivially dereferenceable but may have a lower alignment than the
1023; load does.
1024
1025define i32 @test77(i1 %flag, ptr %x) {
1026; CHECK-LABEL: @test77(
1027; CHECK-NEXT:    [[UNDER_ALIGNED:%.*]] = alloca i32, align 1
1028; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[UNDER_ALIGNED]])
1029; CHECK-NEXT:    store i32 0, ptr [[X:%.*]], align 4
1030; CHECK-NEXT:    [[P:%.*]] = select i1 [[FLAG:%.*]], ptr [[UNDER_ALIGNED]], ptr [[X]]
1031; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P]], align 4
1032; CHECK-NEXT:    ret i32 [[V]]
1033;
1034  %under_aligned = alloca i32, align 1
1035  call void @scribble_on_i32(ptr %under_aligned)
1036  store i32 0, ptr %x
1037  %p = select i1 %flag, ptr %under_aligned, ptr %x
1038  %v = load i32, ptr %p
1039  ret i32 %v
1040}
1041
1042define i32 @test78(i1 %flag, ptr %x, ptr %y, ptr %z) {
1043; Test that we can speculate the loads around the select even when we can't
1044; fold the load completely away.
1045; CHECK-LABEL: @test78(
1046; CHECK-NEXT:  entry:
1047; CHECK-NEXT:    store i32 0, ptr [[X:%.*]], align 4
1048; CHECK-NEXT:    store i32 0, ptr [[Y:%.*]], align 4
1049; CHECK-NEXT:    store i32 42, ptr [[Z:%.*]], align 4
1050; CHECK-NEXT:    [[X_VAL:%.*]] = load i32, ptr [[X]], align 4
1051; CHECK-NEXT:    [[Y_VAL:%.*]] = load i32, ptr [[Y]], align 4
1052; CHECK-NEXT:    [[V:%.*]] = select i1 [[FLAG:%.*]], i32 [[X_VAL]], i32 [[Y_VAL]]
1053; CHECK-NEXT:    ret i32 [[V]]
1054;
1055entry:
1056  store i32 0, ptr %x
1057  store i32 0, ptr %y
1058  ; Block forwarding by storing to %z which could alias either %x or %y.
1059  store i32 42, ptr %z
1060  %p = select i1 %flag, ptr %x, ptr %y
1061  %v = load i32, ptr %p
1062  ret i32 %v
1063}
1064
1065; Test that we can speculate the loads around the select even when we can't
1066; fold the load completely away.
1067define i32 @test78_deref(i1 %flag, ptr dereferenceable(4) align 4 %x, ptr dereferenceable(4) align 4 %y, ptr %z) nofree nosync {
1068; CHECK-LABEL: @test78_deref(
1069; CHECK-NEXT:    [[X_VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
1070; CHECK-NEXT:    [[Y_VAL:%.*]] = load i32, ptr [[Y:%.*]], align 4
1071; CHECK-NEXT:    [[V:%.*]] = select i1 [[FLAG:%.*]], i32 [[X_VAL]], i32 [[Y_VAL]]
1072; CHECK-NEXT:    ret i32 [[V]]
1073;
1074  %p = select i1 %flag, ptr %x, ptr %y
1075  %v = load i32, ptr %p
1076  ret i32 %v
1077}
1078
1079; The same as @test78 but we can't speculate the load because it can trap
1080; if under-aligned.
1081define i32 @test78_neg(i1 %flag, ptr %x, ptr %y, ptr %z) {
1082; CHECK-LABEL: @test78_neg(
1083; CHECK-NEXT:    store i32 0, ptr [[X:%.*]], align 4
1084; CHECK-NEXT:    store i32 0, ptr [[Y:%.*]], align 4
1085; CHECK-NEXT:    store i32 42, ptr [[Z:%.*]], align 4
1086; CHECK-NEXT:    [[P:%.*]] = select i1 [[FLAG:%.*]], ptr [[X]], ptr [[Y]]
1087; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P]], align 16
1088; CHECK-NEXT:    ret i32 [[V]]
1089;
1090  store i32 0, ptr %x
1091  store i32 0, ptr %y
1092  ; Block forwarding by storing to %z which could alias either %x or %y.
1093  store i32 42, ptr %z
1094  %p = select i1 %flag, ptr %x, ptr %y
1095  %v = load i32, ptr %p, align 16
1096  ret i32 %v
1097}
1098
1099; The same as @test78_deref but we can't speculate the load because
1100; one of the arguments is not sufficiently dereferenceable.
1101define i32 @test78_deref_neg(i1 %flag, ptr dereferenceable(2) %x, ptr dereferenceable(4) %y, ptr %z) nofree nosync {
1102; CHECK-LABEL: @test78_deref_neg(
1103; CHECK-NEXT:    [[P:%.*]] = select i1 [[FLAG:%.*]], ptr [[X:%.*]], ptr [[Y:%.*]]
1104; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P]], align 4
1105; CHECK-NEXT:    ret i32 [[V]]
1106;
1107  %p = select i1 %flag, ptr %x, ptr %y
1108  %v = load i32, ptr %p
1109  ret i32 %v
1110}
1111
1112; Test that we can speculate the loads around the select even when we can't
1113; fold the load completely away.
1114define float @test79(i1 %flag, ptr %x, ptr %y, ptr %z) {
1115; CHECK-LABEL: @test79(
1116; CHECK-NEXT:    store i32 0, ptr [[X:%.*]], align 4
1117; CHECK-NEXT:    store i32 0, ptr [[Y:%.*]], align 4
1118; CHECK-NEXT:    store i32 42, ptr [[Z:%.*]], align 4
1119; CHECK-NEXT:    [[X_VAL:%.*]] = load float, ptr [[X]], align 4
1120; CHECK-NEXT:    [[Y_VAL:%.*]] = load float, ptr [[Y]], align 4
1121; CHECK-NEXT:    [[V:%.*]] = select i1 [[FLAG:%.*]], float [[X_VAL]], float [[Y_VAL]]
1122; CHECK-NEXT:    ret float [[V]]
1123;
1124  store i32 0, ptr %x
1125  store i32 0, ptr %y
1126  ; Block forwarding by storing to %z which could alias either %x or %y.
1127  store i32 42, ptr %z
1128  %p = select i1 %flag, ptr %x, ptr %y
1129  %v = load float, ptr %p
1130  ret float %v
1131}
1132
1133; Test that when we speculate the loads around the select they fold throug
1134; load->load folding and load->store folding.
1135define i32 @test80(i1 %flag) {
1136; CHECK-LABEL: @test80(
1137; CHECK-NEXT:    [[X:%.*]] = alloca i32, align 4
1138; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 4
1139; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[X]])
1140; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[Y]])
1141; CHECK-NEXT:    [[T:%.*]] = load i32, ptr [[X]], align 4
1142; CHECK-NEXT:    store i32 [[T]], ptr [[Y]], align 4
1143; CHECK-NEXT:    ret i32 [[T]]
1144;
1145  %x = alloca i32
1146  %y = alloca i32
1147  call void @scribble_on_i32(ptr %x)
1148  call void @scribble_on_i32(ptr %y)
1149  %t = load i32, ptr %x
1150  store i32 %t, ptr %y
1151  %p = select i1 %flag, ptr %x, ptr %y
1152  %v = load i32, ptr %p
1153  ret i32 %v
1154}
1155
1156; Test that we can speculate the load around the select even though they use
1157; differently typed pointers.
1158define float @test81(i1 %flag) {
1159; CHECK-LABEL: @test81(
1160; CHECK-NEXT:    [[X:%.*]] = alloca float, align 4
1161; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 4
1162; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[X]])
1163; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[Y]])
1164; CHECK-NEXT:    [[T:%.*]] = load i32, ptr [[X]], align 4
1165; CHECK-NEXT:    store i32 [[T]], ptr [[Y]], align 4
1166; CHECK-NEXT:    [[V:%.*]] = bitcast i32 [[T]] to float
1167; CHECK-NEXT:    ret float [[V]]
1168;
1169  %x = alloca float
1170  %y = alloca i32
1171  call void @scribble_on_i32(ptr %x)
1172  call void @scribble_on_i32(ptr %y)
1173  %t = load i32, ptr %x
1174  store i32 %t, ptr %y
1175  %p = select i1 %flag, ptr %x, ptr %y
1176  %v = load float, ptr %p
1177  ret float %v
1178}
1179
1180; Test that we can speculate the load around the select even though they use
1181; differently typed pointers.
1182define i32 @test82(i1 %flag) {
1183; CHECK-LABEL: @test82(
1184; CHECK-NEXT:    [[X:%.*]] = alloca float, align 4
1185; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 4
1186; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[X]])
1187; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[Y]])
1188; CHECK-NEXT:    [[T:%.*]] = load float, ptr [[X]], align 4
1189; CHECK-NEXT:    store float [[T]], ptr [[Y]], align 4
1190; CHECK-NEXT:    [[V:%.*]] = bitcast float [[T]] to i32
1191; CHECK-NEXT:    ret i32 [[V]]
1192;
1193  %x = alloca float
1194  %y = alloca i32
1195  call void @scribble_on_i32(ptr %x)
1196  call void @scribble_on_i32(ptr %y)
1197  %t = load float, ptr %x
1198  store float %t, ptr %y
1199  %p = select i1 %flag, ptr %x, ptr %y
1200  %v = load i32, ptr %p
1201  ret i32 %v
1202}
1203
1204declare void @scribble_on_i64(ptr)
1205declare void @scribble_on_i128(ptr)
1206
1207; Test that we can speculate the load around the select even though they use
1208; differently typed pointers and requires inttoptr casts.
1209define ptr @test83(i1 %flag) {
1210; CHECK-LABEL: @test83(
1211; CHECK-NEXT:    [[X:%.*]] = alloca ptr, align 8
1212; CHECK-NEXT:    [[Y:%.*]] = alloca i64, align 8
1213; CHECK-NEXT:    call void @scribble_on_i64(ptr nonnull [[X]])
1214; CHECK-NEXT:    call void @scribble_on_i64(ptr nonnull [[Y]])
1215; CHECK-NEXT:    [[T:%.*]] = load i64, ptr [[X]], align 4
1216; CHECK-NEXT:    store i64 [[T]], ptr [[Y]], align 4
1217; CHECK-NEXT:    [[V:%.*]] = inttoptr i64 [[T]] to ptr
1218; CHECK-NEXT:    ret ptr [[V]]
1219;
1220  %x = alloca ptr
1221  %y = alloca i64
1222  call void @scribble_on_i64(ptr %x)
1223  call void @scribble_on_i64(ptr %y)
1224  %t = load i64, ptr %x
1225  store i64 %t, ptr %y
1226  %p = select i1 %flag, ptr %x, ptr %y
1227  %v = load ptr, ptr %p
1228  ret ptr %v
1229}
1230
1231; Test that we can speculate the load around the select even though they use
1232; differently typed pointers and requires a ptrtoint cast.
1233define i64 @test84(i1 %flag) {
1234; CHECK-LABEL: @test84(
1235; CHECK-NEXT:    [[X:%.*]] = alloca ptr, align 8
1236; CHECK-NEXT:    [[Y:%.*]] = alloca i64, align 8
1237; CHECK-NEXT:    call void @scribble_on_i64(ptr nonnull [[X]])
1238; CHECK-NEXT:    call void @scribble_on_i64(ptr nonnull [[Y]])
1239; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[X]], align 8
1240; CHECK-NEXT:    store ptr [[T]], ptr [[Y]], align 8
1241; CHECK-NEXT:    [[V:%.*]] = ptrtoint ptr [[T]] to i64
1242; CHECK-NEXT:    ret i64 [[V]]
1243;
1244  %x = alloca ptr
1245  %y = alloca i64
1246  call void @scribble_on_i64(ptr %x)
1247  call void @scribble_on_i64(ptr %y)
1248  %t = load ptr, ptr %x
1249  store ptr %t, ptr %y
1250  %p = select i1 %flag, ptr %x, ptr %y
1251  %v = load i64, ptr %p
1252  ret i64 %v
1253}
1254
1255; Test that we can't speculate the load around the select. The load of the
1256; pointer doesn't load all of the stored integer bits. We could fix this, but it
1257; would require endianness checks and other nastiness.
1258define ptr @test85(i1 %flag) {
1259; CHECK-LABEL: @test85(
1260; CHECK-NEXT:    [[X:%.*]] = alloca [2 x ptr], align 8
1261; CHECK-NEXT:    [[Y:%.*]] = alloca i128, align 8
1262; CHECK-NEXT:    call void @scribble_on_i128(ptr nonnull [[X]])
1263; CHECK-NEXT:    call void @scribble_on_i128(ptr nonnull [[Y]])
1264; CHECK-NEXT:    [[T:%.*]] = load i128, ptr [[X]], align 4
1265; CHECK-NEXT:    store i128 [[T]], ptr [[Y]], align 4
1266; CHECK-NEXT:    [[X_VAL:%.*]] = load ptr, ptr [[X]], align 8
1267; CHECK-NEXT:    [[Y_VAL:%.*]] = load ptr, ptr [[Y]], align 8
1268; CHECK-NEXT:    [[V:%.*]] = select i1 [[FLAG:%.*]], ptr [[X_VAL]], ptr [[Y_VAL]]
1269; CHECK-NEXT:    ret ptr [[V]]
1270;
1271  %x = alloca [2 x ptr]
1272  %y = alloca i128
1273  call void @scribble_on_i128(ptr %x)
1274  call void @scribble_on_i128(ptr %y)
1275  %t = load i128, ptr %x
1276  store i128 %t, ptr %y
1277  %p = select i1 %flag, ptr %x, ptr %y
1278  %v = load ptr, ptr %p
1279  ret ptr %v
1280}
1281
1282; Test that we can't speculate the load around the select when the integer size
1283; is larger than the pointer size. The store of the pointer doesn't store to all
1284; the bits of the integer.
1285define i128 @test86(i1 %flag) {
1286; CHECK-LABEL: @test86(
1287; CHECK-NEXT:    [[X:%.*]] = alloca [2 x ptr], align 8
1288; CHECK-NEXT:    [[Y:%.*]] = alloca i128, align 8
1289; CHECK-NEXT:    call void @scribble_on_i128(ptr nonnull [[X]])
1290; CHECK-NEXT:    call void @scribble_on_i128(ptr nonnull [[Y]])
1291; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[X]], align 8
1292; CHECK-NEXT:    store ptr [[T]], ptr [[Y]], align 8
1293; CHECK-NEXT:    [[X_VAL:%.*]] = load i128, ptr [[X]], align 4
1294; CHECK-NEXT:    [[Y_VAL:%.*]] = load i128, ptr [[Y]], align 4
1295; CHECK-NEXT:    [[V:%.*]] = select i1 [[FLAG:%.*]], i128 [[X_VAL]], i128 [[Y_VAL]]
1296; CHECK-NEXT:    ret i128 [[V]]
1297;
1298  %x = alloca [2 x ptr]
1299  %y = alloca i128
1300  call void @scribble_on_i128(ptr %x)
1301  call void @scribble_on_i128(ptr %y)
1302  %t = load ptr, ptr %x
1303  store ptr %t, ptr %y
1304  %p = select i1 %flag, ptr %x, ptr %y
1305  %v = load i128, ptr %p
1306  ret i128 %v
1307}
1308
1309define i32 @test_select_select0(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
1310; CHECK-LABEL: @test_select_select0(
1311; CHECK-NEXT:    [[C0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[V1:%.*]]
1312; CHECK-NEXT:    [[S0:%.*]] = select i1 [[C0_NOT]], i32 [[R1:%.*]], i32 [[R0:%.*]]
1313; CHECK-NEXT:    [[C1:%.*]] = icmp slt i32 [[A]], [[V2:%.*]]
1314; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1]], i32 [[S0]], i32 [[R1]]
1315; CHECK-NEXT:    ret i32 [[S1]]
1316;
1317  %c0 = icmp sge i32 %a, %v1
1318  %s0 = select i1 %c0, i32 %r0, i32 %r1
1319  %c1 = icmp slt i32 %a, %v2
1320  %s1 = select i1 %c1, i32 %s0, i32 %r1
1321  ret i32 %s1
1322}
1323
1324define i32 @test_select_select1(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
1325; CHECK-LABEL: @test_select_select1(
1326; CHECK-NEXT:    [[C0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[V1:%.*]]
1327; CHECK-NEXT:    [[S0:%.*]] = select i1 [[C0_NOT]], i32 [[R1:%.*]], i32 [[R0:%.*]]
1328; CHECK-NEXT:    [[C1:%.*]] = icmp slt i32 [[A]], [[V2:%.*]]
1329; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1]], i32 [[R0]], i32 [[S0]]
1330; CHECK-NEXT:    ret i32 [[S1]]
1331;
1332  %c0 = icmp sge i32 %a, %v1
1333  %s0 = select i1 %c0, i32 %r0, i32 %r1
1334  %c1 = icmp slt i32 %a, %v2
1335  %s1 = select i1 %c1, i32 %r0, i32 %s0
1336  ret i32 %s1
1337}
1338
1339define i32 @PR23757(i32 %x) {
1340; CHECK-LABEL: @PR23757(
1341; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X:%.*]], 1
1342; CHECK-NEXT:    ret i32 [[ADD]]
1343;
1344  %cmp = icmp eq i32 %x, 2147483647
1345  %add = add nsw i32 %x, 1
1346  %sel = select i1 %cmp, i32 -2147483648, i32 %add
1347  ret i32 %sel
1348}
1349
1350define i32 @PR23757_swapped(i32 %x) {
1351; CHECK-LABEL: @PR23757_swapped(
1352; CHECK-NEXT:    ret i32 -2147483648
1353;
1354  %cmp = icmp eq i32 %x, 2147483647
1355  %add = add nsw i32 %x, 1
1356  %sel = select i1 %cmp, i32 %add, i32 -2147483648
1357  ret i32 %sel
1358}
1359
1360define i32 @PR23757_ne(i32 %x, ptr %p) {
1361; CHECK-LABEL: @PR23757_ne(
1362; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 2147483647
1363; CHECK-NEXT:    store i1 [[CMP]], ptr [[P:%.*]], align 1
1364; CHECK-NEXT:    ret i32 -2147483648
1365;
1366  %cmp = icmp ne i32 %x, 2147483647
1367  store i1 %cmp, ptr %p   ; thwart predicate canonicalization
1368  %add = add nsw i32 %x, 1
1369  %sel = select i1 %cmp, i32 -2147483648, i32 %add
1370  ret i32 %sel
1371}
1372
1373define i32 @PR23757_ne_swapped(i32 %x, ptr %p) {
1374; CHECK-LABEL: @PR23757_ne_swapped(
1375; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 2147483647
1376; CHECK-NEXT:    store i1 [[CMP]], ptr [[P:%.*]], align 1
1377; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 1
1378; CHECK-NEXT:    ret i32 [[ADD]]
1379;
1380  %cmp = icmp ne i32 %x, 2147483647
1381  store i1 %cmp, ptr %p   ; thwart predicate canonicalization
1382  %add = add nsw i32 %x, 1
1383  %sel = select i1 %cmp, i32 %add, i32 -2147483648
1384  ret i32 %sel
1385}
1386
1387; max(max(~a, -1), -1) --> ~min(a, 0)
1388
1389define i32 @PR27137(i32 %a) {
1390; CHECK-LABEL: @PR27137(
1391; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 0)
1392; CHECK-NEXT:    [[S1:%.*]] = xor i32 [[TMP1]], -1
1393; CHECK-NEXT:    ret i32 [[S1]]
1394;
1395  %not_a = xor i32 %a, -1
1396  %c0 = icmp slt i32 %a, 0
1397  %s0 = select i1 %c0, i32 %not_a, i32 -1
1398  %c1 = icmp sgt i32 %s0, -1
1399  %s1 = select i1 %c1, i32 %s0, i32 -1
1400  ret i32 %s1
1401}
1402
1403; ub-safe negation pattern
1404define i32 @PR27817(i32 %x) {
1405; CHECK-LABEL: @PR27817(
1406; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[X:%.*]]
1407; CHECK-NEXT:    ret i32 [[SUB]]
1408;
1409  %cmp = icmp eq i32 %x, -2147483648
1410  %sub = sub i32 0, %x
1411  %sel = select i1 %cmp, i32 -2147483648, i32 %sub
1412  ret i32 %sel
1413}
1414
1415define i32 @PR27817_nsw(i32 %x) {
1416; CHECK-LABEL: @PR27817_nsw(
1417; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[X:%.*]]
1418; CHECK-NEXT:    ret i32 [[SUB]]
1419;
1420  %cmp = icmp eq i32 %x, -2147483648
1421  %sub = sub nsw i32 0, %x
1422  %sel = select i1 %cmp, i32 -2147483648, i32 %sub
1423  ret i32 %sel
1424}
1425
1426define <2 x i32> @PR27817_nsw_vec(<2 x i32> %x) {
1427; CHECK-LABEL: @PR27817_nsw_vec(
1428; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]]
1429; CHECK-NEXT:    ret <2 x i32> [[SUB]]
1430;
1431  %cmp = icmp eq <2 x i32> %x, <i32 -2147483648, i32 -2147483648>
1432  %sub = sub nsw <2 x i32> zeroinitializer, %x
1433  %sel = select <2 x i1> %cmp, <2 x i32> <i32 -2147483648, i32 -2147483648>, <2 x i32> %sub
1434  ret <2 x i32> %sel
1435}
1436
1437define i32 @select_icmp_slt0_xor(i32 %x) {
1438; CHECK-LABEL: @select_icmp_slt0_xor(
1439; CHECK-NEXT:    [[X_XOR:%.*]] = or i32 [[X:%.*]], -2147483648
1440; CHECK-NEXT:    ret i32 [[X_XOR]]
1441;
1442  %cmp = icmp slt i32 %x, zeroinitializer
1443  %xor = xor i32 %x, 2147483648
1444  %x.xor = select i1 %cmp, i32 %x, i32 %xor
1445  ret i32 %x.xor
1446}
1447
1448define <2 x i32> @select_icmp_slt0_xor_vec(<2 x i32> %x) {
1449; CHECK-LABEL: @select_icmp_slt0_xor_vec(
1450; CHECK-NEXT:    [[X_XOR:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 -2147483648)
1451; CHECK-NEXT:    ret <2 x i32> [[X_XOR]]
1452;
1453  %cmp = icmp slt <2 x i32> %x, zeroinitializer
1454  %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648>
1455  %x.xor = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %xor
1456  ret <2 x i32> %x.xor
1457}
1458
1459define <4 x i32> @canonicalize_to_shuffle(<4 x i32> %a, <4 x i32> %b) {
1460; CHECK-LABEL: @canonicalize_to_shuffle(
1461; CHECK-NEXT:    [[SEL:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>
1462; CHECK-NEXT:    ret <4 x i32> [[SEL]]
1463;
1464  %sel = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> %a, <4 x i32> %b
1465  ret <4 x i32> %sel
1466}
1467
1468; Undef elements of the select condition may not be translated into undef elements of a shuffle mask
1469; because undef in a shuffle mask means we can return anything, not just one of the selected values.
1470; https://bugs.llvm.org/show_bug.cgi?id=32486
1471
1472define <4 x i32> @undef_elts_in_condition(<4 x i32> %a, <4 x i32> %b) {
1473; CHECK-LABEL: @undef_elts_in_condition(
1474; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]
1475; CHECK-NEXT:    ret <4 x i32> [[SEL]]
1476;
1477  %sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> %a, <4 x i32> %b
1478  ret <4 x i32> %sel
1479}
1480
1481; Don't die or try if the condition mask is a constant expression or contains a constant expression.
1482
1483@g = global i32 0
1484
1485define <4 x i32> @cannot_canonicalize_to_shuffle1(<4 x i32> %a, <4 x i32> %b) {
1486; CHECK-LABEL: @cannot_canonicalize_to_shuffle1(
1487; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> bitcast (i4 ptrtoint (ptr @g to i4) to <4 x i1>), <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]
1488; CHECK-NEXT:    ret <4 x i32> [[SEL]]
1489;
1490  %sel = select <4 x i1> bitcast (i4 ptrtoint (ptr @g to i4) to <4 x i1>), <4 x i32> %a, <4 x i32> %b
1491  ret <4 x i32> %sel
1492}
1493
1494define <4 x i32> @cannot_canonicalize_to_shuffle2(<4 x i32> %a, <4 x i32> %b) {
1495; CHECK-LABEL: @cannot_canonicalize_to_shuffle2(
1496; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 ptrtoint (ptr @g to i1)>, <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]
1497; CHECK-NEXT:    ret <4 x i32> [[SEL]]
1498;
1499  %sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 ptrtoint (ptr @g to i1)>, <4 x i32> %a, <4 x i32> %b
1500  ret <4 x i32> %sel
1501}
1502
1503declare void @llvm.assume(i1)
1504
1505define i8 @assume_cond_true(i1 %cond, i8 %x, i8 %y) {
1506; CHECK-LABEL: @assume_cond_true(
1507; CHECK-NEXT:    call void @llvm.assume(i1 [[COND:%.*]])
1508; CHECK-NEXT:    ret i8 [[X:%.*]]
1509;
1510  call void @llvm.assume(i1 %cond)
1511  %sel = select i1 %cond, i8 %x, i8 %y
1512  ret i8 %sel
1513}
1514
1515; computeKnownBitsFromAssume() understands the 'not' of an assumed condition.
1516
1517define i8 @assume_cond_false(i1 %cond, i8 %x, i8 %y) {
1518; CHECK-LABEL: @assume_cond_false(
1519; CHECK-NEXT:    [[NOTCOND:%.*]] = xor i1 [[COND:%.*]], true
1520; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTCOND]])
1521; CHECK-NEXT:    ret i8 [[Y:%.*]]
1522;
1523  %notcond = xor i1 %cond, true
1524  call void @llvm.assume(i1 %notcond)
1525  %sel = select i1 %cond, i8 %x, i8 %y
1526  ret i8 %sel
1527}
1528
1529; Test case to make sure we don't consider an all ones float values for converting the select into a sext.
1530define <4 x float> @PR33721(<4 x float> %w) {
1531; CHECK-LABEL: @PR33721(
1532; CHECK-NEXT:  entry:
1533; CHECK-NEXT:    [[TMP0:%.*]] = fcmp ole <4 x float> [[W:%.*]], zeroinitializer
1534; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[TMP0]], <4 x float> splat (float 0xFFFFFFFFE0000000), <4 x float> zeroinitializer
1535; CHECK-NEXT:    ret <4 x float> [[TMP1]]
1536;
1537entry:
1538  %0 = fcmp ole <4 x float> %w, zeroinitializer
1539  %1 = select <4 x i1> %0, <4 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>, <4 x float> zeroinitializer
1540  ret <4 x float> %1
1541}
1542
1543; select(C, binop(select(C, X, Y), W), Z) -> select(C, binop(X, W), Z)
1544define i8 @test87(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {
1545; CHECK-LABEL: @test87(
1546; CHECK-NEXT:    [[B:%.*]] = add i8 [[X:%.*]], [[W:%.*]]
1547; CHECK-NEXT:    [[C:%.*]] = select i1 [[COND:%.*]], i8 [[B]], i8 [[Z:%.*]]
1548; CHECK-NEXT:    ret i8 [[C]]
1549;
1550  %a = select i1 %cond, i8 %x, i8 %y
1551  %b = add i8 %a, %w
1552  %c = select i1 %cond, i8 %b, i8 %z
1553  ret i8 %c
1554}
1555
1556; select(C, binop(select(C, X, Y), W), Z) -> select(C, Z, binop(Y, W))
1557define i8 @test88(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {
1558; CHECK-LABEL: @test88(
1559; CHECK-NEXT:    [[B:%.*]] = sub i8 [[Y:%.*]], [[W:%.*]]
1560; CHECK-NEXT:    [[C:%.*]] = select i1 [[COND:%.*]], i8 [[Z:%.*]], i8 [[B]]
1561; CHECK-NEXT:    ret i8 [[C]]
1562;
1563  %a = select i1 %cond, i8 %x, i8 %y
1564  %b = sub i8 %a, %w
1565  %c = select i1 %cond, i8 %z, i8 %b
1566  ret i8 %c
1567}
1568
1569; select(C, Z, binop(W, select(C, X, Y))) -> select(C, binop(X, W), Z)
1570define i8 @test89(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {
1571; CHECK-LABEL: @test89(
1572; CHECK-NEXT:    [[B:%.*]] = and i8 [[W:%.*]], [[X:%.*]]
1573; CHECK-NEXT:    [[C:%.*]] = select i1 [[COND:%.*]], i8 [[B]], i8 [[Z:%.*]]
1574; CHECK-NEXT:    ret i8 [[C]]
1575;
1576  %a = select i1 %cond, i8 %x, i8 %y
1577  %b = and i8 %w, %a
1578  %c = select i1 %cond, i8 %b, i8 %z
1579  ret i8 %c
1580}
1581
1582; select(C, Z, binop(W, select(C, X, Y))) -> select(C, Z, binop(W, Y))
1583define i8 @test90(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {
1584; CHECK-LABEL: @test90(
1585; CHECK-NEXT:    [[B:%.*]] = or i8 [[W:%.*]], [[Y:%.*]]
1586; CHECK-NEXT:    [[C:%.*]] = select i1 [[COND:%.*]], i8 [[Z:%.*]], i8 [[B]]
1587; CHECK-NEXT:    ret i8 [[C]]
1588;
1589  %a = select i1 %cond, i8 %x, i8 %y
1590  %b = or i8 %w, %a
1591  %c = select i1 %cond, i8 %z, i8 %b
1592  ret i8 %c
1593}
1594
1595define i32 @test_shl_zext_bool(i1 %t) {
1596; CHECK-LABEL: @test_shl_zext_bool(
1597; CHECK-NEXT:    [[R:%.*]] = select i1 [[T:%.*]], i32 4, i32 0
1598; CHECK-NEXT:    ret i32 [[R]]
1599;
1600  %r = select i1 %t, i32 4, i32 0
1601  ret i32 %r
1602}
1603
1604define <2 x i32> @test_shl_zext_bool_splat(<2 x i1> %t) {
1605; CHECK-LABEL: @test_shl_zext_bool_splat(
1606; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> splat (i32 8), <2 x i32> zeroinitializer
1607; CHECK-NEXT:    ret <2 x i32> [[R]]
1608;
1609  %r = select <2 x i1> %t, <2 x i32> <i32 8, i32 8>, <2 x i32> zeroinitializer
1610  ret <2 x i32> %r
1611}
1612
1613define <2 x i32> @test_shl_zext_bool_vec(<2 x i1> %t) {
1614; CHECK-LABEL: @test_shl_zext_bool_vec(
1615; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer
1616; CHECK-NEXT:    ret <2 x i32> [[R]]
1617;
1618  %r = select <2 x i1> %t, <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer
1619  ret <2 x i32> %r
1620}
1621
1622define float @copysign1(float %x) {
1623; CHECK-LABEL: @copysign1(
1624; CHECK-NEXT:    [[R:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float [[X:%.*]])
1625; CHECK-NEXT:    ret float [[R]]
1626;
1627  %i = bitcast float %x to i32
1628  %ispos = icmp sgt i32 %i, -1
1629  %r = select i1 %ispos, float 1.0, float -1.0
1630  ret float %r
1631}
1632
1633define float @copysign1_fmf(float %x) {
1634; CHECK-LABEL: @copysign1_fmf(
1635; CHECK-NEXT:    [[R:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float [[X:%.*]])
1636; CHECK-NEXT:    ret float [[R]]
1637;
1638  %i = bitcast float %x to i32
1639  %ispos = icmp sgt i32 %i, -1
1640  %r = select nsz ninf i1 %ispos, float 1.0, float -1.0
1641  ret float %r
1642}
1643
1644define <2 x float> @copysign2(<2 x float> %x) {
1645; CHECK-LABEL: @copysign2(
1646; CHECK-NEXT:    [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]]
1647; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[TMP1]])
1648; CHECK-NEXT:    ret <2 x float> [[R]]
1649;
1650  %i = bitcast <2 x float> %x to <2 x i32>
1651  %isneg = icmp slt <2 x i32> %i, zeroinitializer
1652  %r = select nsz <2 x i1> %isneg, <2 x float> <float 42.0, float 42.0>, <2 x float> <float -42.0, float -42.0>
1653  ret <2 x float> %r
1654}
1655
1656define float @copysign3(float %x) {
1657; CHECK-LABEL: @copysign3(
1658; CHECK-NEXT:    [[TMP1:%.*]] = fneg float [[X:%.*]]
1659; CHECK-NEXT:    [[R:%.*]] = call float @llvm.copysign.f32(float 4.300000e+01, float [[TMP1]])
1660; CHECK-NEXT:    ret float [[R]]
1661;
1662  %i = bitcast float %x to i32
1663  %ispos = icmp ult i32 %i, 2147483648
1664  %r = select fast i1 %ispos, float -43.0, float 43.0
1665  ret float %r
1666}
1667
1668define <2 x float> @copysign_vec_poison(<2 x float> %x) {
1669; CHECK-LABEL: @copysign_vec_poison(
1670; CHECK-NEXT:    [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]]
1671; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[TMP1]])
1672; CHECK-NEXT:    ret <2 x float> [[R]]
1673;
1674  %i = bitcast <2 x float> %x to <2 x i32>
1675  %isneg = icmp ugt <2 x i32> %i, <i32 2147483647, i32 2147483647>
1676  %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float 42.0, float poison>, <2 x float> <float -42.0, float -42.0>
1677  ret <2 x float> %r
1678}
1679
1680define <2 x float> @copysign_vec_poison1(<2 x float> %x) {
1681; CHECK-LABEL: @copysign_vec_poison1(
1682; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[X:%.*]])
1683; CHECK-NEXT:    ret <2 x float> [[R]]
1684;
1685  %i = bitcast <2 x float> %x to <2 x i32>
1686  %isneg = icmp ult <2 x i32> %i, <i32 2147483648, i32 2147483648>
1687  %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float 42.0, float 42.0>, <2 x float> <float poison, float -42.0>
1688  ret <2 x float> %r
1689}
1690
1691define <2 x float> @copysign_vec_poison3(<2 x float> %x) {
1692; CHECK-LABEL: @copysign_vec_poison3(
1693; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[X:%.*]])
1694; CHECK-NEXT:    ret <2 x float> [[R]]
1695;
1696  %i = bitcast <2 x float> %x to <2 x i32>
1697  %isneg = icmp ugt <2 x i32> %i, <i32 2147483647, i32 2147483647>
1698  %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float -42.0, float poison>, <2 x float> <float +42.0, float poison>
1699  ret <2 x float> %r
1700}
1701
1702declare void @use1(i1)
1703
1704; Negative test
1705
1706define float @copysign_extra_use(float %x) {
1707; CHECK-LABEL: @copysign_extra_use(
1708; CHECK-NEXT:    [[I:%.*]] = bitcast float [[X:%.*]] to i32
1709; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[I]], 0
1710; CHECK-NEXT:    call void @use1(i1 [[ISNEG]])
1711; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISNEG]], float -4.400000e+01, float 4.400000e+01
1712; CHECK-NEXT:    ret float [[R]]
1713;
1714  %i = bitcast float %x to i32
1715  %isneg = icmp ugt i32 %i, 2147483647
1716  call void @use1(i1 %isneg)
1717  %r = select i1 %isneg, float -44.0, float 44.0
1718  ret float %r
1719}
1720
1721; Negative test
1722
1723define float @copysign_type_mismatch(double %x) {
1724; CHECK-LABEL: @copysign_type_mismatch(
1725; CHECK-NEXT:    [[I:%.*]] = bitcast double [[X:%.*]] to i64
1726; CHECK-NEXT:    [[ISPOS:%.*]] = icmp sgt i64 [[I]], -1
1727; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISPOS]], float 1.000000e+00, float -1.000000e+00
1728; CHECK-NEXT:    ret float [[R]]
1729;
1730  %i = bitcast double %x to i64
1731  %ispos = icmp sgt i64 %i, -1
1732  %r = select i1 %ispos, float 1.0, float -1.0
1733  ret float %r
1734}
1735
1736; Negative test
1737
1738define <2 x float> @copysign_type_mismatch2(<2 x float> %x) {
1739; CHECK-LABEL: @copysign_type_mismatch2(
1740; CHECK-NEXT:    [[I:%.*]] = bitcast <2 x float> [[X:%.*]] to i64
1741; CHECK-NEXT:    [[ISPOS:%.*]] = icmp sgt i64 [[I]], -1
1742; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISPOS]], <2 x float> splat (float 1.000000e+00), <2 x float> splat (float -1.000000e+00)
1743; CHECK-NEXT:    ret <2 x float> [[R]]
1744;
1745  %i = bitcast <2 x float> %x to i64
1746  %ispos = icmp sgt i64 %i, -1
1747  %r = select i1 %ispos, <2 x float> <float 1.0, float 1.0>, <2 x float> <float -1.0, float -1.0>
1748  ret <2 x float> %r
1749}
1750
1751; Negative test
1752
1753define float @copysign_wrong_cmp(float %x) {
1754; CHECK-LABEL: @copysign_wrong_cmp(
1755; CHECK-NEXT:    [[I:%.*]] = bitcast float [[X:%.*]] to i32
1756; CHECK-NEXT:    [[ISPOS:%.*]] = icmp sgt i32 [[I]], 0
1757; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISPOS]], float 1.000000e+00, float -1.000000e+00
1758; CHECK-NEXT:    ret float [[R]]
1759;
1760  %i = bitcast float %x to i32
1761  %ispos = icmp sgt i32 %i, 0
1762  %r = select i1 %ispos, float 1.0, float -1.0
1763  ret float %r
1764}
1765
1766; Negative test
1767
1768define float @copysign_wrong_const(float %x) {
1769; CHECK-LABEL: @copysign_wrong_const(
1770; CHECK-NEXT:    [[I:%.*]] = bitcast float [[X:%.*]] to i32
1771; CHECK-NEXT:    [[ISPOS:%.*]] = icmp sgt i32 [[I]], -1
1772; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISPOS]], float 2.000000e+00, float -1.000000e+00
1773; CHECK-NEXT:    ret float [[R]]
1774;
1775  %i = bitcast float %x to i32
1776  %ispos = icmp sgt i32 %i, -1
1777  %r = select i1 %ispos, float 2.0, float -1.0
1778  ret float %r
1779}
1780
1781; TODO: we can replace select with a Phi.
1782define i32 @select_dominating_cond(i1 %cond, i32 %x, i32 %y) {
1783; CHECK-LABEL: @select_dominating_cond(
1784; CHECK-NEXT:  entry:
1785; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1786; CHECK:       if.true:
1787; CHECK-NEXT:    br label [[MERGE:%.*]]
1788; CHECK:       if.false:
1789; CHECK-NEXT:    br label [[MERGE]]
1790; CHECK:       merge:
1791; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE]] ], [ [[X:%.*]], [[IF_TRUE]] ]
1792; CHECK-NEXT:    ret i32 [[S]]
1793;
1794entry:
1795  br i1 %cond, label %if.true, label %if.false
1796
1797if.true:
1798  br label %merge
1799
1800if.false:
1801  br label %merge
1802
1803merge:
1804  %s = select i1 %cond, i32 %x, i32 %y
1805  ret i32 %s
1806}
1807
1808define i32 @select_dominating_inverted(i1 %cond, i32 %x, i32 %y) {
1809; CHECK-LABEL: @select_dominating_inverted(
1810; CHECK-NEXT:  entry:
1811; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
1812; CHECK:       if.true:
1813; CHECK-NEXT:    br label [[MERGE:%.*]]
1814; CHECK:       if.false:
1815; CHECK-NEXT:    br label [[MERGE]]
1816; CHECK:       merge:
1817; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE]] ], [ [[Y:%.*]], [[IF_TRUE]] ]
1818; CHECK-NEXT:    ret i32 [[S]]
1819;
1820entry:
1821  %inverted = xor i1 %cond, 1
1822  br i1 %inverted, label %if.true, label %if.false
1823
1824if.true:
1825  br label %merge
1826
1827if.false:
1828  br label %merge
1829
1830merge:
1831  %s = select i1 %cond, i32 %x, i32 %y
1832  ret i32 %s
1833}
1834
1835; More complex CFG: the block with select has multiple predecessors.
1836define i32 @select_dominating_cond_multiple_preds(i1 %cond, i1 %cond2, i1 %cond3, i32 %x, i32 %y) {
1837; CHECK-LABEL: @select_dominating_cond_multiple_preds(
1838; CHECK-NEXT:  entry:
1839; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1840; CHECK:       if.true:
1841; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]]
1842; CHECK:       if.true.1:
1843; CHECK-NEXT:    br label [[MERGE:%.*]]
1844; CHECK:       if.true.2:
1845; CHECK-NEXT:    br label [[MERGE]]
1846; CHECK:       if.false:
1847; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]]
1848; CHECK:       if.false.1:
1849; CHECK-NEXT:    br label [[MERGE]]
1850; CHECK:       merge:
1851; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE_1]] ], [ [[X:%.*]], [[IF_TRUE_2]] ], [ [[X]], [[IF_TRUE_1]] ]
1852; CHECK-NEXT:    ret i32 [[S]]
1853; CHECK:       exit:
1854; CHECK-NEXT:    ret i32 0
1855;
1856entry:
1857  br i1 %cond, label %if.true, label %if.false
1858
1859if.true:
1860  br i1 %cond2, label %if.true.1, label %if.true.2
1861
1862if.true.1:
1863  br label %merge
1864
1865if.true.2:
1866  br label %merge
1867
1868if.false:
1869  br i1 %cond3, label %if.false.1, label %exit
1870
1871if.false.1:
1872  br label %merge
1873
1874merge:
1875  %s = select i1 %cond, i32 %x, i32 %y
1876  ret i32 %s
1877
1878exit:
1879  ret i32 0
1880}
1881
1882; More complex CFG for inverted case: the block with select has multiple predecessors.
1883define i32 @select_dominating_cond_inverted_multiple_preds(i1 %cond, i1 %cond2, i1 %cond3, i32 %x, i32 %y) {
1884; CHECK-LABEL: @select_dominating_cond_inverted_multiple_preds(
1885; CHECK-NEXT:  entry:
1886; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
1887; CHECK:       if.true:
1888; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]]
1889; CHECK:       if.true.1:
1890; CHECK-NEXT:    br label [[MERGE:%.*]]
1891; CHECK:       if.true.2:
1892; CHECK-NEXT:    br label [[MERGE]]
1893; CHECK:       if.false:
1894; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]]
1895; CHECK:       if.false.1:
1896; CHECK-NEXT:    br label [[MERGE]]
1897; CHECK:       merge:
1898; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE_1]] ], [ [[Y:%.*]], [[IF_TRUE_2]] ], [ [[Y]], [[IF_TRUE_1]] ]
1899; CHECK-NEXT:    ret i32 [[S]]
1900; CHECK:       exit:
1901; CHECK-NEXT:    ret i32 0
1902;
1903entry:
1904  %inverted = xor i1 %cond, 1
1905  br i1 %inverted, label %if.true, label %if.false
1906
1907if.true:
1908  br i1 %cond2, label %if.true.1, label %if.true.2
1909
1910if.true.1:
1911  br label %merge
1912
1913if.true.2:
1914  br label %merge
1915
1916if.false:
1917  br i1 %cond3, label %if.false.1, label %exit
1918
1919if.false.1:
1920  br label %merge
1921
1922merge:
1923  %s = select i1 %cond, i32 %x, i32 %y
1924  ret i32 %s
1925
1926exit:
1927  ret i32 0
1928}
1929
1930; More complex CFG for inverted case: the block with select has multiple predecessors that can duplicate.
1931define i32 @select_dominating_cond_inverted_multiple_duplicating_preds(i1 %cond, i32 %cond2, i1 %cond3, i32 %x, i32 %y) {
1932; CHECK-LABEL: @select_dominating_cond_inverted_multiple_duplicating_preds(
1933; CHECK-NEXT:  entry:
1934; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
1935; CHECK:       if.true:
1936; CHECK-NEXT:    switch i32 [[COND2:%.*]], label [[SWITCH_CASE_1:%.*]] [
1937; CHECK-NEXT:      i32 1, label [[MERGE:%.*]]
1938; CHECK-NEXT:      i32 2, label [[MERGE]]
1939; CHECK-NEXT:      i32 3, label [[MERGE]]
1940; CHECK-NEXT:    ]
1941; CHECK:       switch.case.1:
1942; CHECK-NEXT:    br label [[MERGE]]
1943; CHECK:       if.false:
1944; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]]
1945; CHECK:       if.false.1:
1946; CHECK-NEXT:    br label [[MERGE]]
1947; CHECK:       merge:
1948; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE_1]] ], [ [[Y:%.*]], [[SWITCH_CASE_1]] ], [ [[Y]], [[IF_TRUE]] ], [ [[Y]], [[IF_TRUE]] ], [ [[Y]], [[IF_TRUE]] ]
1949; CHECK-NEXT:    ret i32 [[S]]
1950; CHECK:       exit:
1951; CHECK-NEXT:    ret i32 0
1952;
1953entry:
1954  %inverted = xor i1 %cond, 1
1955  br i1 %inverted, label %if.true, label %if.false
1956
1957if.true:
1958  switch i32 %cond2, label %switch.case.1 [
1959  i32 1, label %merge
1960  i32 2, label %merge
1961  i32 3, label %merge
1962  ]
1963
1964switch.case.1:
1965  br label %merge
1966
1967if.false:
1968  br i1 %cond3, label %if.false.1, label %exit
1969
1970if.false.1:
1971  br label %merge
1972
1973merge:
1974  %s = select i1 %cond, i32 %x, i32 %y
1975  ret i32 %s
1976
1977exit:
1978  ret i32 0
1979}
1980
1981; Negative test: currently we take condition from IDom, but might be willing to expand it in the future.
1982define i32 @select_not_imm_dominating_cond_neg(i1 %cond, i32 %x, i32 %y) {
1983; CHECK-LABEL: @select_not_imm_dominating_cond_neg(
1984; CHECK-NEXT:  entry:
1985; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1986; CHECK:       if.true:
1987; CHECK-NEXT:    br label [[MERGE:%.*]]
1988; CHECK:       if.false:
1989; CHECK-NEXT:    br label [[MERGE]]
1990; CHECK:       merge:
1991; CHECK-NEXT:    br label [[EXIT:%.*]]
1992; CHECK:       exit:
1993; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], i32 [[X:%.*]], i32 [[Y:%.*]]
1994; CHECK-NEXT:    ret i32 [[S]]
1995;
1996entry:
1997  br i1 %cond, label %if.true, label %if.false
1998
1999if.true:
2000  br label %merge
2001
2002if.false:
2003  br label %merge
2004
2005merge:
2006  br label %exit
2007
2008exit:
2009  %s = select i1 %cond, i32 %x, i32 %y
2010  ret i32 %s
2011}
2012
2013; Shows how we can leverage dominance to eliminate duplicating selects.
2014define i32 @select_dominance_chain(i1 %cond, i32 %x, i32 %y) {
2015; CHECK-LABEL: @select_dominance_chain(
2016; CHECK-NEXT:  entry:
2017; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]]
2018; CHECK:       if.true.1:
2019; CHECK-NEXT:    br label [[MERGE_1:%.*]]
2020; CHECK:       if.false.1:
2021; CHECK-NEXT:    br label [[MERGE_1]]
2022; CHECK:       merge.1:
2023; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]]
2024; CHECK:       if.true.2:
2025; CHECK-NEXT:    br label [[MERGE_2:%.*]]
2026; CHECK:       if.false.2:
2027; CHECK-NEXT:    br label [[MERGE_2]]
2028; CHECK:       merge.2:
2029; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE_3:%.*]], label [[IF_FALSE_3:%.*]]
2030; CHECK:       if.true.3:
2031; CHECK-NEXT:    br label [[MERGE_3:%.*]]
2032; CHECK:       if.false.3:
2033; CHECK-NEXT:    br label [[MERGE_3]]
2034; CHECK:       merge.3:
2035; CHECK-NEXT:    [[S_1:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE_3]] ], [ [[X:%.*]], [[IF_TRUE_3]] ]
2036; CHECK-NEXT:    [[SUM_2:%.*]] = mul i32 [[S_1]], 3
2037; CHECK-NEXT:    ret i32 [[SUM_2]]
2038;
2039entry:
2040  br i1 %cond, label %if.true.1, label %if.false.1
2041
2042if.true.1:
2043  br label %merge.1
2044
2045if.false.1:
2046  br label %merge.1
2047
2048merge.1:
2049  %s.1 = select i1 %cond, i32 %x, i32 %y
2050  br i1 %cond, label %if.true.2, label %if.false.2
2051
2052if.true.2:
2053  br label %merge.2
2054
2055if.false.2:
2056  br label %merge.2
2057
2058merge.2:
2059  %s.2 = select i1 %cond, i32 %x, i32 %y
2060  br i1 %cond, label %if.true.3, label %if.false.3
2061
2062if.true.3:
2063  br label %merge.3
2064
2065if.false.3:
2066  br label %merge.3
2067
2068merge.3:
2069  %s.3 = select i1 %cond, i32 %x, i32 %y
2070  %sum.1 = add i32 %s.1, %s.2
2071  %sum.2 = add i32 %sum.1, %s.3
2072  ret i32 %sum.2
2073}
2074
2075; TODO: We can replace select with a Phi and then sink a and b to respective
2076; branches.
2077define i32 @select_dominating_cond_and_sink(i1 %cond, i32 %x, i32 %y) {
2078; CHECK-LABEL: @select_dominating_cond_and_sink(
2079; CHECK-NEXT:  entry:
2080; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2081; CHECK:       if.true:
2082; CHECK-NEXT:    br label [[MERGE:%.*]]
2083; CHECK:       if.false:
2084; CHECK-NEXT:    br label [[MERGE]]
2085; CHECK:       merge:
2086; CHECK-NEXT:    [[B:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
2087; CHECK-NEXT:    [[A:%.*]] = add i32 [[X]], [[Y]]
2088; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
2089; CHECK-NEXT:    ret i32 [[S]]
2090;
2091entry:
2092  %a = add i32 %x, %y
2093  %b = mul i32 %x, %y
2094  br i1 %cond, label %if.true, label %if.false
2095
2096if.true:
2097  br label %merge
2098
2099if.false:
2100  br label %merge
2101
2102merge:
2103  %s = select i1 %cond, i32 %a, i32 %b
2104  ret i32 %s
2105}
2106
2107define i32 @select_dominating_cond_same_labels(i1 %cond) {
2108; CHECK-LABEL: @select_dominating_cond_same_labels(
2109; CHECK-NEXT:  entry:
2110; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[EXIT]]
2111; CHECK:       exit:
2112; CHECK-NEXT:    [[RESULT:%.*]] = select i1 [[COND:%.*]], i32 123, i32 456
2113; CHECK-NEXT:    ret i32 [[RESULT]]
2114;
2115entry:
2116  %result = select i1 %cond, i32 123, i32 456
2117  br i1 %cond, label %exit, label %exit
2118exit:
2119  ret i32 %result
2120}
2121
2122define i32 @select_phi_same_condition(i1 %cond, i32 %x, i32 %y, i32 %z) {
2123; CHECK-LABEL: @select_phi_same_condition(
2124; CHECK-NEXT:  entry:
2125; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2126; CHECK:       if.true:
2127; CHECK-NEXT:    br label [[MERGE:%.*]]
2128; CHECK:       if.false:
2129; CHECK-NEXT:    br label [[MERGE]]
2130; CHECK:       merge:
2131; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_TRUE]] ], [ [[Z:%.*]], [[IF_FALSE]] ]
2132; CHECK-NEXT:    ret i32 [[S]]
2133;
2134entry:
2135  br i1 %cond, label %if.true, label %if.false
2136
2137if.true:
2138  br label %merge
2139
2140if.false:
2141  br label %merge
2142
2143merge:
2144  %phi = phi i32 [0, %if.true], [%z, %if.false]
2145  %s = select i1 %cond, i32 %x, i32 %phi
2146  ret i32 %s
2147}
2148
2149
2150; TODO: Replace with phi[a, c] and sink them to respective branches.
2151define i32 @select_phi_same_condition_sink(i1 %cond, i32 %x, i32 %y, i32 %z) {
2152; CHECK-LABEL: @select_phi_same_condition_sink(
2153; CHECK-NEXT:  entry:
2154; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2155; CHECK:       if.true:
2156; CHECK-NEXT:    br label [[MERGE:%.*]]
2157; CHECK:       if.false:
2158; CHECK-NEXT:    [[B:%.*]] = mul i32 [[X:%.*]], [[Z:%.*]]
2159; CHECK-NEXT:    br label [[MERGE]]
2160; CHECK:       merge:
2161; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]
2162; CHECK-NEXT:    [[A:%.*]] = add i32 [[X]], [[Y:%.*]]
2163; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[PHI]]
2164; CHECK-NEXT:    ret i32 [[S]]
2165;
2166entry:
2167  %a = add i32 %x, %y
2168  %b = mul i32 %x, %z
2169  br i1 %cond, label %if.true, label %if.false
2170
2171if.true:
2172  br label %merge
2173
2174if.false:
2175  br label %merge
2176
2177merge:
2178  %phi = phi i32 [0, %if.true], [%b, %if.false]
2179  %s = select i1 %cond, i32 %a, i32 %phi
2180  ret i32 %s
2181}
2182
2183declare i32 @__gxx_personality_v0(...)
2184declare i1 @foo()
2185
2186define i32 @test_invoke_neg(i32 %x, i32 %y) nounwind uwtable ssp personality ptr @__gxx_personality_v0 {
2187; CHECK-LABEL: @test_invoke_neg(
2188; CHECK-NEXT:  entry:
2189; CHECK-NEXT:    [[COND:%.*]] = invoke i1 @foo()
2190; CHECK-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
2191; CHECK:       invoke.cont:
2192; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 [[X:%.*]], i32 [[Y:%.*]]
2193; CHECK-NEXT:    ret i32 [[SEL]]
2194; CHECK:       lpad:
2195; CHECK-NEXT:    [[LP:%.*]] = landingpad { i1, i32 }
2196; CHECK-NEXT:            filter [0 x i1] zeroinitializer
2197; CHECK-NEXT:    unreachable
2198;
2199entry:
2200  %cond = invoke i1 @foo()
2201  to label %invoke.cont unwind label %lpad
2202
2203invoke.cont:
2204  %sel = select i1 %cond, i32 %x, i32 %y
2205  ret i32 %sel
2206
2207lpad:
2208  %lp = landingpad { i1, i32 }
2209  filter [0 x i1] zeroinitializer
2210  unreachable
2211}
2212
2213declare i32 @bar()
2214
2215define i32 @test_invoke_2_neg(i1 %cond, i32 %x, i32 %y) nounwind uwtable ssp personality ptr @__gxx_personality_v0 {
2216; CHECK-LABEL: @test_invoke_2_neg(
2217; CHECK-NEXT:  entry:
2218; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2219; CHECK:       if.true:
2220; CHECK-NEXT:    br label [[MERGE:%.*]]
2221; CHECK:       if.false:
2222; CHECK-NEXT:    [[RESULT:%.*]] = invoke i32 @bar()
2223; CHECK-NEXT:            to label [[MERGE]] unwind label [[LPAD:%.*]]
2224; CHECK:       merge:
2225; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[RESULT]], [[IF_FALSE]] ]
2226; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 1, i32 [[PHI]]
2227; CHECK-NEXT:    ret i32 [[SEL]]
2228; CHECK:       lpad:
2229; CHECK-NEXT:    [[LP:%.*]] = landingpad { i1, i32 }
2230; CHECK-NEXT:            filter [0 x i1] zeroinitializer
2231; CHECK-NEXT:    unreachable
2232;
2233entry:
2234  br i1 %cond, label %if.true, label %if.false
2235
2236if.true:
2237  br label %merge
2238
2239if.false:
2240  %result = invoke i32 @bar()
2241  to label %merge unwind label %lpad
2242
2243merge:
2244  %phi = phi i32 [ 0, %if.true ], [ %result, %if.false ]
2245  %sel = select i1 %cond, i32 1, i32 %phi
2246  ret i32 %sel
2247
2248lpad:
2249  %lp = landingpad { i1, i32 }
2250  filter [0 x i1] zeroinitializer
2251  unreachable
2252}
2253
2254define i32 @select_phi_same_condition_switch(i1 %cond, i32 %x, i32 %y) {
2255; CHECK-LABEL: @select_phi_same_condition_switch(
2256; CHECK-NEXT:  entry:
2257; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2258; CHECK:       if.true:
2259; CHECK-NEXT:    switch i32 [[X:%.*]], label [[EXIT:%.*]] [
2260; CHECK-NEXT:      i32 1, label [[MERGE:%.*]]
2261; CHECK-NEXT:      i32 2, label [[MERGE]]
2262; CHECK-NEXT:    ]
2263; CHECK:       exit:
2264; CHECK-NEXT:    ret i32 0
2265; CHECK:       if.false:
2266; CHECK-NEXT:    br label [[MERGE]]
2267; CHECK:       merge:
2268; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[X]], [[IF_TRUE]] ], [ [[X]], [[IF_TRUE]] ], [ [[Y:%.*]], [[IF_FALSE]] ]
2269; CHECK-NEXT:    ret i32 [[S]]
2270;
2271entry:
2272  br i1 %cond, label %if.true, label %if.false
2273
2274if.true:
2275  switch i32 %x, label %exit [
2276  i32 1, label %merge
2277  i32 2, label %merge
2278  ]
2279
2280exit:
2281  ret i32 0
2282
2283if.false:
2284  br label %merge
2285
2286merge:
2287  %phi = phi i32 [0, %if.true], [0, %if.true], [%y, %if.false]
2288  %s = select i1 %cond, i32 %x, i32 %phi
2289  ret i32 %s
2290}
2291
2292define i32 @transit_different_values_through_phi(i1 %cond, i1 %cond2) {
2293; CHECK-LABEL: @transit_different_values_through_phi(
2294; CHECK-NEXT:  entry:
2295; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2296; CHECK:       if.true:
2297; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]]
2298; CHECK:       if.true.1:
2299; CHECK-NEXT:    br label [[MERGE:%.*]]
2300; CHECK:       if.true.2:
2301; CHECK-NEXT:    br label [[MERGE]]
2302; CHECK:       if.false:
2303; CHECK-NEXT:    br label [[MERGE]]
2304; CHECK:       merge:
2305; CHECK-NEXT:    [[S:%.*]] = phi i32 [ 1, [[IF_TRUE_1]] ], [ 2, [[IF_TRUE_2]] ], [ 3, [[IF_FALSE]] ]
2306; CHECK-NEXT:    ret i32 [[S]]
2307; CHECK:       exit:
2308; CHECK-NEXT:    ret i32 0
2309;
2310entry:
2311  br i1 %cond, label %if.true, label %if.false
2312
2313if.true:
2314  br i1 %cond2, label %if.true.1, label %if.true.2
2315
2316if.true.1:
2317  br label %merge
2318
2319if.true.2:
2320  br label %merge
2321
2322if.false:
2323  br label %merge
2324
2325merge:
2326  %p = phi i32 [ 1, %if.true.1 ], [ 2, %if.true.2 ], [ 4, %if.false ]
2327  %s = select i1 %cond, i32 %p, i32 3
2328  ret i32 %s
2329
2330exit:
2331  ret i32 0
2332}
2333
2334define i32 @select_phi_degenerate(i1 %cond, i1 %cond2) {
2335; CHECK-LABEL: @select_phi_degenerate(
2336; CHECK-NEXT:  entry:
2337; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP:%.*]], label [[EXIT:%.*]]
2338; CHECK:       loop:
2339; CHECK-NEXT:    [[SELECT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[LOOP]] ]
2340; CHECK-NEXT:    [[IV_INC]] = add i32 [[SELECT]], 1
2341; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT2:%.*]]
2342; CHECK:       exit:
2343; CHECK-NEXT:    ret i32 0
2344; CHECK:       exit2:
2345; CHECK-NEXT:    ret i32 [[IV_INC]]
2346;
2347entry:
2348  br i1 %cond, label %loop, label %exit
2349
2350loop:
2351  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
2352  %select = select i1 %cond, i32 %iv, i32 -1
2353  %iv.inc = add i32 %select, 1
2354  br i1 %cond2, label %loop, label %exit2
2355
2356exit:
2357  ret i32 0
2358
2359exit2:
2360  ret i32 %iv.inc
2361}
2362
2363define i32 @test_select_into_phi_not_idom(i1 %cond, i32 %A, i32 %B)  {
2364; CHECK-LABEL: @test_select_into_phi_not_idom(
2365; CHECK-NEXT:  entry:
2366; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2367; CHECK:       if.true:
2368; CHECK-NEXT:    br label [[MERGE:%.*]]
2369; CHECK:       if.false:
2370; CHECK-NEXT:    br label [[MERGE]]
2371; CHECK:       merge:
2372; CHECK-NEXT:    br label [[EXIT:%.*]]
2373; CHECK:       exit:
2374; CHECK-NEXT:    ret i32 [[A:%.*]]
2375;
2376entry:
2377  br i1 %cond, label %if.true, label %if.false
2378
2379if.true:
2380  br label %merge
2381
2382if.false:
2383  br label %merge
2384
2385merge:
2386  %phi = phi i32 [%A, %if.true], [%B, %if.false]
2387  br label %exit
2388
2389exit:
2390  %sel = select i1 %cond, i32 %phi, i32 %A
2391  ret i32 %sel
2392}
2393
2394define i32 @test_select_into_phi_not_idom_2(i1 %cond, i32 %A, i32 %B)  {
2395; CHECK-LABEL: @test_select_into_phi_not_idom_2(
2396; CHECK-NEXT:  entry:
2397; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2398; CHECK:       if.true:
2399; CHECK-NEXT:    br label [[MERGE:%.*]]
2400; CHECK:       if.false:
2401; CHECK-NEXT:    br label [[MERGE]]
2402; CHECK:       merge:
2403; CHECK-NEXT:    br label [[EXIT:%.*]]
2404; CHECK:       exit:
2405; CHECK-NEXT:    ret i32 [[B:%.*]]
2406;
2407entry:
2408  br i1 %cond, label %if.true, label %if.false
2409
2410if.true:
2411  br label %merge
2412
2413if.false:
2414  br label %merge
2415
2416merge:
2417  %phi = phi i32 [%A, %if.true], [%B, %if.false]
2418  br label %exit
2419
2420exit:
2421  %sel = select i1 %cond, i32 %B, i32 %phi
2422  ret i32 %sel
2423}
2424
2425define i32 @test_select_into_phi_not_idom_inverted(i1 %cond, i32 %A, i32 %B)  {
2426; CHECK-LABEL: @test_select_into_phi_not_idom_inverted(
2427; CHECK-NEXT:  entry:
2428; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
2429; CHECK:       if.true:
2430; CHECK-NEXT:    br label [[MERGE:%.*]]
2431; CHECK:       if.false:
2432; CHECK-NEXT:    br label [[MERGE]]
2433; CHECK:       merge:
2434; CHECK-NEXT:    [[SEL:%.*]] = phi i32 [ [[A:%.*]], [[IF_TRUE]] ], [ [[B:%.*]], [[IF_FALSE]] ]
2435; CHECK-NEXT:    br label [[EXIT:%.*]]
2436; CHECK:       exit:
2437; CHECK-NEXT:    ret i32 [[SEL]]
2438;
2439entry:
2440  %inverted = xor i1 %cond, 1
2441  br i1 %inverted, label %if.true, label %if.false
2442
2443if.true:
2444  br label %merge
2445
2446if.false:
2447  br label %merge
2448
2449merge:
2450  %phi = phi i32 [%A, %if.true], [%B, %if.false]
2451  br label %exit
2452
2453exit:
2454  %sel = select i1 %cond, i32 %phi, i32 %A
2455  ret i32 %sel
2456}
2457
2458define i32 @test_select_into_phi_not_idom_inverted_2(i1 %cond, i32 %A, i32 %B)  {
2459; CHECK-LABEL: @test_select_into_phi_not_idom_inverted_2(
2460; CHECK-NEXT:  entry:
2461; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
2462; CHECK:       if.true:
2463; CHECK-NEXT:    br label [[MERGE:%.*]]
2464; CHECK:       if.false:
2465; CHECK-NEXT:    br label [[MERGE]]
2466; CHECK:       merge:
2467; CHECK-NEXT:    [[SEL:%.*]] = phi i32 [ [[A:%.*]], [[IF_TRUE]] ], [ [[B:%.*]], [[IF_FALSE]] ]
2468; CHECK-NEXT:    br label [[EXIT:%.*]]
2469; CHECK:       exit:
2470; CHECK-NEXT:    ret i32 [[SEL]]
2471;
2472entry:
2473  %inverted = xor i1 %cond, 1
2474  br i1 %inverted, label %if.true, label %if.false
2475
2476if.true:
2477  br label %merge
2478
2479if.false:
2480  br label %merge
2481
2482merge:
2483  %phi = phi i32 [%A, %if.true], [%B, %if.false]
2484  br label %exit
2485
2486exit:
2487  %sel = select i1 %cond, i32 %B, i32 %phi
2488  ret i32 %sel
2489}
2490
2491define i32 @test_select_into_phi_not_idom_no_dom_input_1(i1 %cond, i32 %A, i32 %B, ptr %p)  {
2492; CHECK-LABEL: @test_select_into_phi_not_idom_no_dom_input_1(
2493; CHECK-NEXT:  entry:
2494; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2495; CHECK:       if.true:
2496; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[P:%.*]], align 4
2497; CHECK-NEXT:    br label [[MERGE:%.*]]
2498; CHECK:       if.false:
2499; CHECK-NEXT:    br label [[MERGE]]
2500; CHECK:       merge:
2501; CHECK-NEXT:    [[SEL:%.*]] = phi i32 [ [[C]], [[IF_TRUE]] ], [ [[A:%.*]], [[IF_FALSE]] ]
2502; CHECK-NEXT:    br label [[EXIT:%.*]]
2503; CHECK:       exit:
2504; CHECK-NEXT:    ret i32 [[SEL]]
2505;
2506entry:
2507  br i1 %cond, label %if.true, label %if.false
2508
2509if.true:
2510  %C = load i32, ptr %p
2511  br label %merge
2512
2513if.false:
2514  br label %merge
2515
2516merge:
2517  %phi = phi i32 [%C, %if.true], [%B, %if.false]
2518  br label %exit
2519
2520exit:
2521  %sel = select i1 %cond, i32 %phi, i32 %A
2522  ret i32 %sel
2523}
2524
2525define i32 @test_select_into_phi_not_idom_no_dom_input_2(i1 %cond, i32 %A, i32 %B, ptr %p)  {
2526; CHECK-LABEL: @test_select_into_phi_not_idom_no_dom_input_2(
2527; CHECK-NEXT:  entry:
2528; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2529; CHECK:       if.true:
2530; CHECK-NEXT:    br label [[MERGE:%.*]]
2531; CHECK:       if.false:
2532; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[P:%.*]], align 4
2533; CHECK-NEXT:    br label [[MERGE]]
2534; CHECK:       merge:
2535; CHECK-NEXT:    [[SEL:%.*]] = phi i32 [ [[B:%.*]], [[IF_TRUE]] ], [ [[C]], [[IF_FALSE]] ]
2536; CHECK-NEXT:    br label [[EXIT:%.*]]
2537; CHECK:       exit:
2538; CHECK-NEXT:    ret i32 [[SEL]]
2539;
2540entry:
2541  br i1 %cond, label %if.true, label %if.false
2542
2543if.true:
2544  br label %merge
2545
2546if.false:
2547  %C = load i32, ptr %p
2548  br label %merge
2549
2550merge:
2551  %phi = phi i32 [%A, %if.true], [%C, %if.false]
2552  br label %exit
2553
2554exit:
2555  %sel = select i1 %cond, i32 %B, i32 %phi
2556  ret i32 %sel
2557}
2558
2559; Negative tests to ensure we don't remove selects with undef true/false values.
2560; See https://bugs.llvm.org/show_bug.cgi?id=31633
2561; https://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html
2562; https://reviews.llvm.org/D83360
2563define i32 @false_undef(i1 %cond, i32 %x) {
2564; CHECK-LABEL: @false_undef(
2565; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 undef
2566; CHECK-NEXT:    ret i32 [[S]]
2567;
2568  %s = select i1 %cond, i32 %x, i32 undef
2569  ret i32 %s
2570}
2571
2572define i32 @true_undef(i1 %cond, i32 %x) {
2573; CHECK-LABEL: @true_undef(
2574; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], i32 undef, i32 [[X:%.*]]
2575; CHECK-NEXT:    ret i32 [[S]]
2576;
2577  %s = select i1 %cond, i32 undef, i32 %x
2578  ret i32 %s
2579}
2580
2581define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) {
2582; CHECK-LABEL: @false_undef_vec(
2583; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> [[X:%.*]], <2 x i32> undef
2584; CHECK-NEXT:    ret <2 x i32> [[S]]
2585;
2586  %s = select i1 %cond, <2 x i32> %x, <2 x i32> undef
2587  ret <2 x i32> %s
2588}
2589
2590define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) {
2591; CHECK-LABEL: @true_undef_vec(
2592; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> undef, <2 x i32> [[X:%.*]]
2593; CHECK-NEXT:    ret <2 x i32> [[S]]
2594;
2595  %s = select i1 %cond, <2 x i32> undef, <2 x i32> %x
2596  ret <2 x i32> %s
2597}
2598
2599define i8 @cond_freeze(i8 %x, i8 %y) {
2600; CHECK-LABEL: @cond_freeze(
2601; CHECK-NEXT:    ret i8 [[Y:%.*]]
2602;
2603  %cond.fr = freeze i1 undef
2604  %s = select i1 %cond.fr, i8 %x, i8 %y
2605  ret i8 %s
2606}
2607
2608define i8 @cond_freeze_constant_false_val(i8 %x) {
2609; CHECK-LABEL: @cond_freeze_constant_false_val(
2610; CHECK-NEXT:    ret i8 1
2611;
2612  %cond.fr = freeze i1 undef
2613  %s = select i1 %cond.fr, i8 %x, i8 1
2614  ret i8 %s
2615}
2616
2617define i8 @cond_freeze_constant_true_val(i8 %x) {
2618; CHECK-LABEL: @cond_freeze_constant_true_val(
2619; CHECK-NEXT:    ret i8 1
2620;
2621  %cond.fr = freeze i1 undef
2622  %s = select i1 %cond.fr, i8 1, i8 %x
2623  ret i8 %s
2624}
2625
2626define i8 @cond_freeze_both_arms_constant() {
2627; CHECK-LABEL: @cond_freeze_both_arms_constant(
2628; CHECK-NEXT:    ret i8 42
2629;
2630  %cond.fr = freeze i1 undef
2631  %s = select i1 %cond.fr, i8 42, i8 3
2632  ret i8 %s
2633}
2634
2635define <2 x i8> @cond_freeze_constant_true_val_vec(<2 x i8> %x) {
2636; CHECK-LABEL: @cond_freeze_constant_true_val_vec(
2637; CHECK-NEXT:    ret <2 x i8> <i8 1, i8 2>
2638;
2639  %cond.fr = freeze <2 x i1> <i1 undef, i1 undef>
2640  %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> %x
2641  ret <2 x i8> %s
2642}
2643
2644define <2 x i8> @partial_cond_freeze_constant_true_val_vec(<2 x i8> %x) {
2645; CHECK-LABEL: @partial_cond_freeze_constant_true_val_vec(
2646; CHECK-NEXT:    ret <2 x i8> <i8 1, i8 2>
2647;
2648  %cond.fr = freeze <2 x i1> <i1 true, i1 undef>
2649  %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> %x
2650  ret <2 x i8> %s
2651}
2652
2653define <2 x i8> @partial_cond_freeze_constant_false_val_vec(<2 x i8> %x) {
2654; CHECK-LABEL: @partial_cond_freeze_constant_false_val_vec(
2655; CHECK-NEXT:    [[S1:%.*]] = insertelement <2 x i8> [[X:%.*]], i8 2, i64 1
2656; CHECK-NEXT:    ret <2 x i8> [[S1]]
2657;
2658  %cond.fr = freeze <2 x i1> <i1 true, i1 undef>
2659  %s = select <2 x i1> %cond.fr, <2 x i8> %x, <2 x i8> <i8 1, i8 2>
2660  ret <2 x i8> %s
2661}
2662
2663define <2 x i8> @partial_cond_freeze_both_arms_constant_vec() {
2664; CHECK-LABEL: @partial_cond_freeze_both_arms_constant_vec(
2665; CHECK-NEXT:    ret <2 x i8> <i8 42, i8 2>
2666;
2667  %cond.fr = freeze <2 x i1> <i1 false, i1 undef>
2668  %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> <i8 42, i8 43>
2669  ret <2 x i8> %s
2670}
2671
2672declare void @foo2(i8, i8)
2673
2674define void @cond_freeze_multipleuses(i8 %x, i8 %y) {
2675; CHECK-LABEL: @cond_freeze_multipleuses(
2676; CHECK-NEXT:    call void @foo2(i8 [[Y:%.*]], i8 [[X:%.*]])
2677; CHECK-NEXT:    ret void
2678;
2679  %cond.fr = freeze i1 undef
2680  %s = select i1 %cond.fr, i8 %x, i8 %y
2681  %s2 = select i1 %cond.fr, i8 %y, i8 %x
2682  call void @foo2(i8 %s, i8 %s2)
2683  ret void
2684}
2685
2686define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) {
2687; CHECK-LABEL: @select_freeze_icmp_eq(
2688; CHECK-NEXT:    ret i32 [[Y:%.*]]
2689;
2690  %c = icmp eq i32 %x, %y
2691  %c.fr = freeze i1 %c
2692  %v = select i1 %c.fr, i32 %x, i32 %y
2693  ret i32 %v
2694}
2695
2696define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) {
2697; CHECK-LABEL: @select_freeze_icmp_ne(
2698; CHECK-NEXT:    ret i32 [[X:%.*]]
2699;
2700  %c = icmp ne i32 %x, %y
2701  %c.fr = freeze i1 %c
2702  %v = select i1 %c.fr, i32 %x, i32 %y
2703  ret i32 %v
2704}
2705
2706define i32 @select_freeze_icmp_else(i32 %x, i32 %y) {
2707; CHECK-LABEL: @select_freeze_icmp_else(
2708; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2709; CHECK-NEXT:    [[C_FR:%.*]] = freeze i1 [[C]]
2710; CHECK-NEXT:    [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]]
2711; CHECK-NEXT:    ret i32 [[V]]
2712;
2713  %c = icmp ult i32 %x, %y
2714  %c.fr = freeze i1 %c
2715  %v = select i1 %c.fr, i32 %x, i32 %y
2716  ret i32 %v
2717}
2718
2719declare void @use_i1_i32(i1, i32)
2720
2721define void @select_freeze_icmp_multuses(i32 %x, i32 %y) {
2722; CHECK-LABEL: @select_freeze_icmp_multuses(
2723; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
2724; CHECK-NEXT:    [[C_FR:%.*]] = freeze i1 [[C]]
2725; CHECK-NEXT:    [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]]
2726; CHECK-NEXT:    call void @use_i1_i32(i1 [[C_FR]], i32 [[V]])
2727; CHECK-NEXT:    ret void
2728;
2729  %c = icmp ne i32 %x, %y
2730  %c.fr = freeze i1 %c
2731  %v = select i1 %c.fr, i32 %x, i32 %y
2732  call void @use_i1_i32(i1 %c.fr, i32 %v)
2733  ret void
2734}
2735
2736define i32 @pr47322_more_poisonous_replacement(i32 %arg) {
2737; CHECK-LABEL: @pr47322_more_poisonous_replacement(
2738; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ARG:%.*]], 0
2739; CHECK-NEXT:    [[TRAILING:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[ARG]], i1 true)
2740; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr i32 [[ARG]], [[TRAILING]]
2741; CHECK-NEXT:    [[R1_SROA_0_1:%.*]] = select i1 [[CMP]], i32 0, i32 [[SHIFTED]]
2742; CHECK-NEXT:    ret i32 [[R1_SROA_0_1]]
2743;
2744  %cmp = icmp eq i32 %arg, 0
2745  %trailing = call i32 @llvm.cttz.i32(i32 %arg, i1 true)
2746  %shifted = lshr i32 %arg, %trailing
2747  %r1.sroa.0.1 = select i1 %cmp, i32 0, i32 %shifted
2748  ret i32 %r1.sroa.0.1
2749}
2750
2751define i8 @select_replacement_add_eq(i8 %x, i8 %y) {
2752; CHECK-LABEL: @select_replacement_add_eq(
2753; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 1
2754; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y:%.*]]
2755; CHECK-NEXT:    ret i8 [[SEL]]
2756;
2757  %cmp = icmp eq i8 %x, 1
2758  %add = add i8 %x, 1
2759  %sel = select i1 %cmp, i8 %add, i8 %y
2760  ret i8 %sel
2761}
2762
2763define <2 x i8> @select_replacement_add_eq_vec(<2 x i8> %x, <2 x i8> %y) {
2764; CHECK-LABEL: @select_replacement_add_eq_vec(
2765; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 1)
2766; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> splat (i8 2), <2 x i8> [[Y:%.*]]
2767; CHECK-NEXT:    ret <2 x i8> [[SEL]]
2768;
2769  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 1>
2770  %add = add <2 x i8> %x, <i8 1, i8 1>
2771  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2772  ret <2 x i8> %sel
2773}
2774
2775define <2 x i8> @select_replacement_add_eq_vec_nonuniform(<2 x i8> %x, <2 x i8> %y) {
2776; CHECK-LABEL: @select_replacement_add_eq_vec_nonuniform(
2777; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 2>
2778; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 4, i8 6>, <2 x i8> [[Y:%.*]]
2779; CHECK-NEXT:    ret <2 x i8> [[SEL]]
2780;
2781  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 2>
2782  %add = add <2 x i8> %x, <i8 3, i8 4>
2783  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2784  ret <2 x i8> %sel
2785}
2786
2787define <2 x i8> @select_replacement_add_eq_vec_poison(<2 x i8> %x, <2 x i8> %y) {
2788; CHECK-LABEL: @select_replacement_add_eq_vec_poison(
2789; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 poison>
2790; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 2, i8 poison>, <2 x i8> [[Y:%.*]]
2791; CHECK-NEXT:    ret <2 x i8> [[SEL]]
2792;
2793  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 poison>
2794  %add = add <2 x i8> %x, <i8 1, i8 1>
2795  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2796  ret <2 x i8> %sel
2797}
2798
2799define <2 x i8> @select_replacement_add_eq_vec_undef(<2 x i8> %x, <2 x i8> %y) {
2800; CHECK-LABEL: @select_replacement_add_eq_vec_undef(
2801; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 undef>
2802; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i8> [[X]], splat (i8 1)
2803; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[ADD]], <2 x i8> [[Y:%.*]]
2804; CHECK-NEXT:    ret <2 x i8> [[SEL]]
2805;
2806  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 undef>
2807  %add = add <2 x i8> %x, <i8 1, i8 1>
2808  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2809  ret <2 x i8> %sel
2810}
2811
2812define <2 x i8> @select_replacement_add_eq_vec_undef_okay(<2 x i8> %x, <2 x i8> %y) {
2813; CHECK-LABEL: @select_replacement_add_eq_vec_undef_okay(
2814; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 1)
2815; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 2, i8 undef>, <2 x i8> [[Y:%.*]]
2816; CHECK-NEXT:    ret <2 x i8> [[SEL]]
2817;
2818  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 1>
2819  %add = add <2 x i8> %x, <i8 1, i8 undef>
2820  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2821  ret <2 x i8> %sel
2822}
2823
2824
2825define <2 x i8> @select_replacement_add_eq_vec_undef_okay_todo(<2 x i8> %x, <2 x i8> %y) {
2826; CHECK-LABEL: @select_replacement_add_eq_vec_undef_okay_todo(
2827; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 undef>
2828; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i8> [[X]], <i8 1, i8 undef>
2829; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[ADD]], <2 x i8> [[Y:%.*]]
2830; CHECK-NEXT:    ret <2 x i8> [[SEL]]
2831;
2832  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 undef>
2833  %add = add <2 x i8> %x, <i8 1, i8 undef>
2834  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2835  ret <2 x i8> %sel
2836}
2837
2838define <2 x i8> @select_replacement_xor_eq_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
2839; CHECK-LABEL: @select_replacement_xor_eq_vec(
2840; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], [[Y:%.*]]
2841; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> zeroinitializer, <2 x i8> [[Z:%.*]]
2842; CHECK-NEXT:    ret <2 x i8> [[SEL]]
2843;
2844  %cmp = icmp eq <2 x i8> %x, %y
2845  %add = xor <2 x i8> %x, %y
2846  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %z
2847  ret <2 x i8> %sel
2848}
2849
2850
2851define i8 @select_replacement_add_ne(i8 %x, i8 %y) {
2852; CHECK-LABEL: @select_replacement_add_ne(
2853; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 1
2854; CHECK-NEXT:    call void @use(i1 [[CMP]])
2855; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 [[Y:%.*]], i8 2
2856; CHECK-NEXT:    ret i8 [[SEL]]
2857;
2858  %cmp = icmp ne i8 %x, 1
2859  call void @use(i1 %cmp)
2860  %add = add i8 %x, 1
2861  %sel = select i1 %cmp, i8 %y, i8 %add
2862  ret i8 %sel
2863}
2864
2865define i8 @select_replacement_add_nuw(i8 %x, i8 %y) {
2866; CHECK-LABEL: @select_replacement_add_nuw(
2867; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 1
2868; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y:%.*]]
2869; CHECK-NEXT:    ret i8 [[SEL]]
2870;
2871  %cmp = icmp eq i8 %x, 1
2872  %add = add nuw i8 %x, 1
2873  %sel = select i1 %cmp, i8 %add, i8 %y
2874  ret i8 %sel
2875}
2876
2877define i8 @select_replacement_sub_noundef(i8 %x, i8 noundef %y, i8 %z) {
2878; CHECK-LABEL: @select_replacement_sub_noundef(
2879; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
2880; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z:%.*]]
2881; CHECK-NEXT:    ret i8 [[SEL]]
2882;
2883  %cmp = icmp eq i8 %x, %y
2884  %sub = sub i8 %x, %y
2885  %sel = select i1 %cmp, i8 %sub, i8 %z
2886  ret i8 %sel
2887}
2888
2889define i8 @select_replacement_sub_noundef_but_may_be_poison(i8 %x, i8 noundef %yy, i8 %z) {
2890; CHECK-LABEL: @select_replacement_sub_noundef_but_may_be_poison(
2891; CHECK-NEXT:    [[Y:%.*]] = shl nuw i8 [[YY:%.*]], 1
2892; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y]]
2893; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z:%.*]]
2894; CHECK-NEXT:    ret i8 [[SEL]]
2895;
2896  %y = shl nuw i8 %yy, 1
2897  %cmp = icmp eq i8 %x, %y
2898  %sub = sub i8 %x, %y
2899  %sel = select i1 %cmp, i8 %sub, i8 %z
2900  ret i8 %sel
2901}
2902
2903; TODO: The transform is also safe without noundef.
2904define i8 @select_replacement_sub(i8 %x, i8 %y, i8 %z) {
2905; CHECK-LABEL: @select_replacement_sub(
2906; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
2907; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z:%.*]]
2908; CHECK-NEXT:    ret i8 [[SEL]]
2909;
2910  %cmp = icmp eq i8 %x, %y
2911  %sub = sub i8 %x, %y
2912  %sel = select i1 %cmp, i8 %sub, i8 %z
2913  ret i8 %sel
2914}
2915
2916; FIXME: This is safe to fold.
2917define i8 @select_replacement_shift_noundef(i8 %x, i8 %y, i8 %z) {
2918; CHECK-LABEL: @select_replacement_shift_noundef(
2919; CHECK-NEXT:    [[SHR:%.*]] = lshr exact i8 [[X:%.*]], 1
2920; CHECK-NEXT:    call void @use_i8(i8 noundef [[SHR]])
2921; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y:%.*]]
2922; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[Y]], 1
2923; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z:%.*]]
2924; CHECK-NEXT:    ret i8 [[SEL]]
2925;
2926  %shr = lshr exact i8 %x, 1
2927  call void @use_i8(i8 noundef %shr)
2928  %cmp = icmp eq i8 %shr, %y
2929  %shl = shl i8 %y, 1
2930  %sel = select i1 %cmp, i8 %shl, i8 %z
2931  ret i8 %sel
2932}
2933
2934; TODO: The transform is also safe without noundef.
2935define i8 @select_replacement_shift(i8 %x, i8 %y, i8 %z) {
2936; CHECK-LABEL: @select_replacement_shift(
2937; CHECK-NEXT:    [[SHR:%.*]] = lshr exact i8 [[X:%.*]], 1
2938; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y:%.*]]
2939; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[Y]], 1
2940; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z:%.*]]
2941; CHECK-NEXT:    ret i8 [[SEL]]
2942;
2943  %shr = lshr exact i8 %x, 1
2944  %cmp = icmp eq i8 %shr, %y
2945  %shl = shl i8 %y, 1
2946  %sel = select i1 %cmp, i8 %shl, i8 %z
2947  ret i8 %sel
2948}
2949
2950define i8 @select_replacement_loop(i8 %x, i8 %y, i8 %z) {
2951; CHECK-LABEL: @select_replacement_loop(
2952; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
2953; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[Z:%.*]]
2954; CHECK-NEXT:    ret i8 [[SEL]]
2955;
2956  %cmp = icmp eq i8 %x, %y
2957  %sel = select i1 %cmp, i8 %x, i8 %z
2958  ret i8 %sel
2959}
2960
2961define i32 @select_replacement_loop2(i32 %arg, i32 %arg2) {
2962; CHECK-LABEL: @select_replacement_loop2(
2963; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[ARG:%.*]], [[ARG2:%.*]]
2964; CHECK-NEXT:    ret i32 [[DIV]]
2965;
2966  %div = udiv i32 %arg, %arg2
2967  %mul = mul nsw i32 %div, %arg2
2968  %cmp = icmp eq i32 %mul, %arg
2969  %sel = select i1 %cmp, i32 %div, i32 undef
2970  ret i32 %sel
2971}
2972
2973define i8 @select_replacement_loop3(i32 noundef %x) {
2974; CHECK-LABEL: @select_replacement_loop3(
2975; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[X:%.*]] to i8
2976; CHECK-NEXT:    [[REV:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TRUNC]])
2977; CHECK-NEXT:    [[EXT:%.*]] = zext i8 [[REV]] to i32
2978; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], [[EXT]]
2979; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 [[TRUNC]], i8 0
2980; CHECK-NEXT:    ret i8 [[SEL]]
2981;
2982  %trunc = trunc i32 %x to i8
2983  %rev = call i8 @llvm.bitreverse.i8(i8 %trunc)
2984  %ext = zext i8 %rev to i32
2985  %cmp = icmp eq i32 %ext, %x
2986  %sel = select i1 %cmp, i8 %trunc, i8 0
2987  ret i8 %sel
2988}
2989
2990define i16 @select_replacement_loop4(i16 noundef %p_12) {
2991; CHECK-LABEL: @select_replacement_loop4(
2992; CHECK-NEXT:    [[P_12:%.*]] = call i16 @llvm.umin.i16(i16 [[P_13:%.*]], i16 2)
2993; CHECK-NEXT:    [[AND1:%.*]] = and i16 [[P_12]], 1
2994; CHECK-NEXT:    ret i16 [[AND1]]
2995;
2996  %cmp1 = icmp ult i16 %p_12, 2
2997  %and1 = and i16 %p_12, 1
2998  %and2 = select i1 %cmp1, i16 %and1, i16 0
2999  %cmp2 = icmp eq i16 %and2, %p_12
3000  %and3 = select i1 %cmp2, i16 %and1, i16 0
3001  ret i16 %and3
3002}
3003
3004define ptr @select_replacement_gep_inbounds(ptr %base, i64 %offset) {
3005; CHECK-LABEL: @select_replacement_gep_inbounds(
3006; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[BASE:%.*]], i64 [[OFFSET:%.*]]
3007; CHECK-NEXT:    ret ptr [[GEP]]
3008;
3009  %cmp = icmp eq i64 %offset, 0
3010  %gep = getelementptr inbounds i8, ptr %base, i64 %offset
3011  %sel = select i1 %cmp, ptr %base, ptr %gep
3012  ret ptr %sel
3013}
3014
3015define i8 @replace_false_op_eq_shl_or_disjoint(i8 %x) {
3016; CHECK-LABEL: @replace_false_op_eq_shl_or_disjoint(
3017; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[X:%.*]], 3
3018; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X]], [[SHL]]
3019; CHECK-NEXT:    ret i8 [[OR]]
3020;
3021  %eq0 = icmp eq i8 %x, -1
3022  %shl = shl i8 %x, 3
3023  %or = or disjoint i8 %x, %shl
3024  %sel = select i1 %eq0, i8 -1, i8 %or
3025  ret i8 %sel
3026}
3027
3028define i8 @select_or_disjoint_eq(i8 %x, i8 %y) {
3029; CHECK-LABEL: @select_or_disjoint_eq(
3030; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
3031; CHECK-NEXT:    ret i8 [[OR]]
3032;
3033  %cmp = icmp eq i8 %x, %y
3034  %or = or disjoint i8 %x, %y
3035  %sel = select i1 %cmp, i8 %x, i8 %or
3036  ret i8 %sel
3037}
3038
3039define <2 x i1> @partial_true_undef_condval(<2 x i1> %x) {
3040; CHECK-LABEL: @partial_true_undef_condval(
3041; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 poison>
3042;
3043  %r = select <2 x i1> <i1 true, i1 poison>, <2 x i1> <i1 true, i1 poison>, <2 x i1> %x
3044  ret <2 x i1> %r
3045}
3046
3047define <2 x i1> @partial_false_undef_condval(<2 x i1> %x) {
3048; CHECK-LABEL: @partial_false_undef_condval(
3049; CHECK-NEXT:    ret <2 x i1> <i1 false, i1 poison>
3050;
3051  %r = select <2 x i1> <i1 false, i1 poison>, <2 x i1> %x, <2 x i1> <i1 false, i1 poison>
3052  ret <2 x i1> %r
3053}
3054
3055; select (x == 0), 0, x * y --> freeze(y) * x
3056define i32 @mul_select_eq_zero(i32 %x, i32 %y) {
3057; CHECK-LABEL: @mul_select_eq_zero(
3058; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
3059; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X:%.*]], [[Y_FR]]
3060; CHECK-NEXT:    ret i32 [[M]]
3061;
3062  %c = icmp eq i32 %x, 0
3063  %m = mul i32 %x, %y
3064  %r = select i1 %c, i32 0, i32 %m
3065  ret i32 %r
3066}
3067
3068; select (y == 0), 0, x * y --> freeze(x) * y
3069define i32 @mul_select_eq_zero_commute(i32 %x, i32 %y) {
3070; CHECK-LABEL: @mul_select_eq_zero_commute(
3071; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X:%.*]]
3072; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X_FR]], [[Y:%.*]]
3073; CHECK-NEXT:    ret i32 [[M]]
3074;
3075  %c = icmp eq i32 %y, 0
3076  %m = mul i32 %x, %y
3077  %r = select i1 %c, i32 0, i32 %m
3078  ret i32 %r
3079}
3080
3081; Check that mul's flags preserved during the transformation.
3082define i32 @mul_select_eq_zero_copy_flags(i32 %x, i32 %y) {
3083; CHECK-LABEL: @mul_select_eq_zero_copy_flags(
3084; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
3085; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X:%.*]], [[Y_FR]]
3086; CHECK-NEXT:    ret i32 [[M]]
3087;
3088  %c = icmp eq i32 %x, 0
3089  %m = mul nuw nsw i32 %x, %y
3090  %r = select i1 %c, i32 0, i32 %m
3091  ret i32 %r
3092}
3093
3094; Check that the transformation could be applied after condition's inversion.
3095; select (x != 0), x * y, 0 --> freeze(y) * x
3096define i32 @mul_select_ne_zero(i32 %x, i32 %y) {
3097; CHECK-LABEL: @mul_select_ne_zero(
3098; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[X:%.*]], 0
3099; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
3100; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y_FR]]
3101; CHECK-NEXT:    call void @use(i1 [[C]])
3102; CHECK-NEXT:    ret i32 [[M]]
3103;
3104  %c = icmp ne i32 %x, 0
3105  %m = mul i32 %x, %y
3106  %r = select i1 %c, i32 %m, i32 0
3107  call void @use(i1 %c)
3108  ret i32 %r
3109}
3110
3111; Check that if one of a select's branches returns undef then
3112; an expression could be folded into mul as if there was a 0 instead of undef.
3113; select (x == 0), undef, x * y --> freeze(y) * x
3114define i32 @mul_select_eq_zero_sel_undef(i32 %x, i32 %y) {
3115; CHECK-LABEL: @mul_select_eq_zero_sel_undef(
3116; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
3117; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X:%.*]], [[Y_FR]]
3118; CHECK-NEXT:    ret i32 [[M]]
3119;
3120  %c = icmp eq i32 %x, 0
3121  %m = mul i32 %x, %y
3122  %r = select i1 %c, i32 undef, i32 %m
3123  ret i32 %r
3124}
3125
3126; Check that the transformation is applied disregard to a number
3127; of expression's users.
3128define i32 @mul_select_eq_zero_multiple_users(i32 %x, i32 %y) {
3129; CHECK-LABEL: @mul_select_eq_zero_multiple_users(
3130; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
3131; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X:%.*]], [[Y_FR]]
3132; CHECK-NEXT:    call void @use_i32(i32 [[M]])
3133; CHECK-NEXT:    call void @use_i32(i32 [[M]])
3134; CHECK-NEXT:    call void @use_i32(i32 [[M]])
3135; CHECK-NEXT:    ret i32 [[M]]
3136;
3137  %m = mul i32 %x, %y
3138  call void @use_i32(i32 %m)
3139  %c = icmp eq i32 %x, 0
3140  %r = select i1 %c, i32 0, i32 %m
3141  call void @use_i32(i32 %m)
3142  call void @use_i32(i32 %r)
3143  ret i32 %r
3144}
3145
3146; Negative test: select's condition is unrelated to multiplied values,
3147; so the transformation should not be applied.
3148define i32 @mul_select_eq_zero_unrelated_condition(i32 %x, i32 %y, i32 %z) {
3149; CHECK-LABEL: @mul_select_eq_zero_unrelated_condition(
3150; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[Z:%.*]], 0
3151; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
3152; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 0, i32 [[M]]
3153; CHECK-NEXT:    ret i32 [[R]]
3154;
3155  %c = icmp eq i32 %z, 0
3156  %m = mul i32 %x, %y
3157  %r = select i1 %c, i32 0, i32 %m
3158  ret i32 %r
3159}
3160
3161; select (<k x elt> x == 0), <k x elt> 0, <k x elt> x * y --> freeze(y) * x
3162define <4 x i32> @mul_select_eq_zero_vector(<4 x i32> %x, <4 x i32> %y) {
3163; CHECK-LABEL: @mul_select_eq_zero_vector(
3164; CHECK-NEXT:    [[Y_FR:%.*]] = freeze <4 x i32> [[Y:%.*]]
3165; CHECK-NEXT:    [[M:%.*]] = mul <4 x i32> [[X:%.*]], [[Y_FR]]
3166; CHECK-NEXT:    ret <4 x i32> [[M]]
3167;
3168  %c = icmp eq <4 x i32> %x, zeroinitializer
3169  %m = mul <4 x i32> %x, %y
3170  %r = select <4 x i1> %c, <4 x i32> zeroinitializer, <4 x i32> %m
3171  ret <4 x i32> %r
3172}
3173
3174; Check that a select is folded into multiplication if condition's operand
3175; is a vector consisting of zeros and poisons.
3176; select (<k x elt> x == {0, poison, ...}), <k x elt> 0, <k x elt> x * y --> freeze(y) * x
3177define <2 x i32> @mul_select_eq_poison_vector(<2 x i32> %x, <2 x i32> %y) {
3178; CHECK-LABEL: @mul_select_eq_poison_vector(
3179; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 0, i32 poison>
3180; CHECK-NEXT:    [[M:%.*]] = mul <2 x i32> [[X]], [[Y:%.*]]
3181; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C]], <2 x i32> <i32 0, i32 42>, <2 x i32> [[M]]
3182; CHECK-NEXT:    ret <2 x i32> [[R]]
3183;
3184  %c = icmp eq <2 x i32> %x, <i32 0, i32 poison>
3185  %m = mul <2 x i32> %x, %y
3186  %r = select <2 x i1> %c, <2 x i32> <i32 0, i32 42>, <2 x i32> %m
3187  ret <2 x i32> %r
3188}
3189
3190; Check that a select is folded into multiplication if other select's operand
3191; is a vector consisting of zeros and poisons.
3192; select (<k x elt> x == 0), <k x elt> {0, poison, ...}, <k x elt> x * y --> freeze(y) * x
3193define <2 x i32> @mul_select_eq_zero_sel_poison_vector(<2 x i32> %x, <2 x i32> %y) {
3194; CHECK-LABEL: @mul_select_eq_zero_sel_poison_vector(
3195; CHECK-NEXT:    [[Y_FR:%.*]] = freeze <2 x i32> [[Y:%.*]]
3196; CHECK-NEXT:    [[M:%.*]] = mul <2 x i32> [[X:%.*]], [[Y_FR]]
3197; CHECK-NEXT:    ret <2 x i32> [[M]]
3198;
3199  %c = icmp eq <2 x i32> %x, zeroinitializer
3200  %m = mul <2 x i32> %x, %y
3201  %r = select <2 x i1> %c, <2 x i32> <i32 0, i32 poison>, <2 x i32> %m
3202  ret <2 x i32> %r
3203}
3204
3205; Negative test: select should not be folded into mul because
3206; condition's operand and select's operand do not merge into zero vector.
3207define <2 x i32> @mul_select_eq_poison_vector_not_merging_to_zero(<2 x i32> %x, <2 x i32> %y) {
3208; CHECK-LABEL: @mul_select_eq_poison_vector_not_merging_to_zero(
3209; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 0, i32 poison>
3210; CHECK-NEXT:    [[M:%.*]] = mul <2 x i32> [[X]], [[Y:%.*]]
3211; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C]], <2 x i32> <i32 1, i32 0>, <2 x i32> [[M]]
3212; CHECK-NEXT:    ret <2 x i32> [[R]]
3213;
3214  %c = icmp eq <2 x i32> %x, <i32 0, i32 poison>
3215  %m = mul <2 x i32> %x, %y
3216  %r = select <2 x i1> %c, <2 x i32> <i32 1, i32 0>, <2 x i32> %m
3217  ret <2 x i32> %r
3218}
3219
3220define i8 @ne0_is_all_ones(i8 %x) {
3221; CHECK-LABEL: @ne0_is_all_ones(
3222; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
3223; CHECK-NEXT:    [[R:%.*]] = sext i1 [[TMP1]] to i8
3224; CHECK-NEXT:    ret i8 [[R]]
3225;
3226  %negx = sub i8 0, %x
3227  %ugt1 = icmp ugt i8 %x, 1
3228  %r = select i1 %ugt1, i8 -1, i8 %negx
3229  ret i8 %r
3230}
3231
3232define i8 @ne0_is_all_ones_use1(i8 %x) {
3233; CHECK-LABEL: @ne0_is_all_ones_use1(
3234; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
3235; CHECK-NEXT:    call void @use_i8(i8 [[NEGX]])
3236; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[X]], 0
3237; CHECK-NEXT:    [[R:%.*]] = sext i1 [[TMP1]] to i8
3238; CHECK-NEXT:    ret i8 [[R]]
3239;
3240  %negx = sub i8 0, %x
3241  call void @use_i8(i8 %negx)
3242  %ugt1 = icmp ugt i8 %x, 1
3243  %r = select i1 %ugt1, i8 -1, i8 %negx
3244  ret i8 %r
3245}
3246
3247; negative test
3248
3249define i8 @ne0_is_all_ones_use2(i8 %x) {
3250; CHECK-LABEL: @ne0_is_all_ones_use2(
3251; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
3252; CHECK-NEXT:    [[UGT1:%.*]] = icmp ugt i8 [[X]], 1
3253; CHECK-NEXT:    call void @use(i1 [[UGT1]])
3254; CHECK-NEXT:    [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]]
3255; CHECK-NEXT:    ret i8 [[R]]
3256;
3257  %negx = sub i8 0, %x
3258  %ugt1 = icmp ugt i8 %x, 1
3259  call void @use(i1 %ugt1)
3260  %r = select i1 %ugt1, i8 -1, i8 %negx
3261  ret i8 %r
3262}
3263
3264; negative test
3265
3266define i8 @ne0_is_all_ones_wrong_pred(i8 %x) {
3267; CHECK-LABEL: @ne0_is_all_ones_wrong_pred(
3268; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
3269; CHECK-NEXT:    [[UGT1:%.*]] = icmp sgt i8 [[X]], 2
3270; CHECK-NEXT:    [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]]
3271; CHECK-NEXT:    ret i8 [[R]]
3272;
3273  %negx = sub i8 0, %x
3274  %ugt1 = icmp sgt i8 %x, 2
3275  %r = select i1 %ugt1, i8 -1, i8 %negx
3276  ret i8 %r
3277}
3278
3279; negative test
3280
3281define i8 @ne0_is_all_ones_wrong_cmp(i8 %x) {
3282; CHECK-LABEL: @ne0_is_all_ones_wrong_cmp(
3283; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
3284; CHECK-NEXT:    [[UGT1:%.*]] = icmp ugt i8 [[X]], 2
3285; CHECK-NEXT:    [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]]
3286; CHECK-NEXT:    ret i8 [[R]]
3287;
3288  %negx = sub i8 0, %x
3289  %ugt1 = icmp ugt i8 %x, 2
3290  %r = select i1 %ugt1, i8 -1, i8 %negx
3291  ret i8 %r
3292}
3293
3294; negative test
3295
3296define i8 @ne0_is_all_ones_wrong_sel(i8 %x) {
3297; CHECK-LABEL: @ne0_is_all_ones_wrong_sel(
3298; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
3299; CHECK-NEXT:    [[UGT1:%.*]] = icmp ugt i8 [[X]], 2
3300; CHECK-NEXT:    [[R:%.*]] = select i1 [[UGT1]], i8 1, i8 [[NEGX]]
3301; CHECK-NEXT:    ret i8 [[R]]
3302;
3303  %negx = sub i8 0, %x
3304  %ugt1 = icmp ugt i8 %x, 2
3305  %r = select i1 %ugt1, i8 1, i8 %negx
3306  ret i8 %r
3307}
3308
3309define <2 x i8> @ne0_is_all_ones_swap_vec(<2 x i8> %x) {
3310; CHECK-LABEL: @ne0_is_all_ones_swap_vec(
3311; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer
3312; CHECK-NEXT:    [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>
3313; CHECK-NEXT:    ret <2 x i8> [[R]]
3314;
3315  %negx = sub <2 x i8> zeroinitializer, %x
3316  %ult2 = icmp ult <2 x i8> %x, <i8 2, i8 2>
3317  %r = select <2 x i1> %ult2, <2 x i8> %negx, <2 x i8> <i8 -1, i8 -1>
3318  ret <2 x i8> %r
3319}
3320
3321define <2 x i8> @ne0_is_all_ones_swap_vec_poison(<2 x i8> %x) {
3322; CHECK-LABEL: @ne0_is_all_ones_swap_vec_poison(
3323; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer
3324; CHECK-NEXT:    [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>
3325; CHECK-NEXT:    ret <2 x i8> [[R]]
3326;
3327  %negx = sub <2 x i8> <i8 0, i8 poison>, %x
3328  %ult2 = icmp ult <2 x i8> %x, <i8 2, i8 poison>
3329  %r = select <2 x i1> %ult2, <2 x i8> %negx, <2 x i8> <i8 -1, i8 poison>
3330  ret <2 x i8> %r
3331}
3332
3333define i64 @udiv_of_select_constexpr(i1 %c, i64 %x) {
3334; CHECK-LABEL: @udiv_of_select_constexpr(
3335; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C:%.*]], i64 [[X:%.*]], i64 ptrtoint (ptr @glbl to i64)
3336; CHECK-NEXT:    [[OP:%.*]] = udiv i64 [[SEL]], 3
3337; CHECK-NEXT:    ret i64 [[OP]]
3338;
3339  %sel = select i1 %c, i64 %x, i64 ptrtoint (ptr @glbl to i64)
3340  %op = udiv i64 %sel, 3
3341  ret i64 %op
3342}
3343
3344define i64 @udiv_of_select_constexpr_commuted(i1 %c, i64 %x) {
3345; CHECK-LABEL: @udiv_of_select_constexpr_commuted(
3346; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C:%.*]], i64 ptrtoint (ptr @glbl to i64), i64 [[X:%.*]]
3347; CHECK-NEXT:    [[OP:%.*]] = udiv i64 [[SEL]], 3
3348; CHECK-NEXT:    ret i64 [[OP]]
3349;
3350  %sel = select i1 %c, i64 ptrtoint (ptr @glbl to i64), i64 %x
3351  %op = udiv i64 %sel, 3
3352  ret i64 %op
3353}
3354
3355declare void @use(i1)
3356declare void @use_i8(i8)
3357declare void @use_i32(i32)
3358declare i32 @llvm.cttz.i32(i32, i1 immarg)
3359
3360define i32 @select_cond_zext_cond(i1 %cond, i32 %b) {
3361; CHECK-LABEL: @select_cond_zext_cond(
3362; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 1, i32 [[B:%.*]]
3363; CHECK-NEXT:    ret i32 [[SEL]]
3364;
3365  %zext = zext i1 %cond to i32
3366  %sel = select i1 %cond, i32 %zext, i32 %b
3367  ret i32 %sel
3368}
3369
3370define <2 x i32> @select_cond_zext_cond_vec(<2 x i1> %cond, <2 x i32> %b) {
3371; CHECK-LABEL: @select_cond_zext_cond_vec(
3372; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> splat (i32 1), <2 x i32> [[B:%.*]]
3373; CHECK-NEXT:    ret <2 x i32> [[SEL]]
3374;
3375  %zext = zext <2 x i1> %cond to <2 x i32>
3376  %sel = select <2 x i1> %cond, <2 x i32> %zext, <2 x i32> %b
3377  ret <2 x i32> %sel
3378}
3379
3380define i32 @select_cond_sext_cond(i1 %cond, i32 %b) {
3381; CHECK-LABEL: @select_cond_sext_cond(
3382; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 -1, i32 [[B:%.*]]
3383; CHECK-NEXT:    ret i32 [[SEL]]
3384;
3385  %sext = sext i1 %cond to i32
3386  %sel = select i1 %cond, i32 %sext, i32 %b
3387  ret i32 %sel
3388}
3389
3390define <2 x i32> @select_cond_sext_cond_vec(<2 x i1> %cond, <2 x i32> %b) {
3391; CHECK-LABEL: @select_cond_sext_cond_vec(
3392; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> splat (i32 -1), <2 x i32> [[B:%.*]]
3393; CHECK-NEXT:    ret <2 x i32> [[SEL]]
3394;
3395  %sext = sext <2 x i1> %cond to <2 x i32>
3396  %sel = select <2 x i1> %cond, <2 x i32> %sext, <2 x i32> %b
3397  ret <2 x i32> %sel
3398}
3399
3400define i32 @select_cond_val_zext_cond(i1 %cond, i32 %b) {
3401; CHECK-LABEL: @select_cond_val_zext_cond(
3402; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 0
3403; CHECK-NEXT:    ret i32 [[SEL]]
3404;
3405  %zext = zext i1 %cond to i32
3406  %sel = select i1 %cond, i32 %b, i32 %zext
3407  ret i32 %sel
3408}
3409
3410define <2 x i32> @select_cond_val_zext_cond_vec(<2 x i1> %cond, <2 x i32> %b) {
3411; CHECK-LABEL: @select_cond_val_zext_cond_vec(
3412; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> [[B:%.*]], <2 x i32> zeroinitializer
3413; CHECK-NEXT:    ret <2 x i32> [[SEL]]
3414;
3415  %zext = zext <2 x i1> %cond to <2 x i32>
3416  %sel = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %zext
3417  ret <2 x i32> %sel
3418}
3419
3420define i32 @select_cond_val_sext_cond(i1 %cond, i32 %b) {
3421; CHECK-LABEL: @select_cond_val_sext_cond(
3422; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 0
3423; CHECK-NEXT:    ret i32 [[SEL]]
3424;
3425  %sext = sext i1 %cond to i32
3426  %sel = select i1 %cond, i32 %b, i32 %sext
3427  ret i32 %sel
3428}
3429
3430define i32 @select_cond_zext_not_cond_val(i1 %cond, i32 %b) {
3431; CHECK-LABEL: @select_cond_zext_not_cond_val(
3432; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 0, i32 [[B:%.*]]
3433; CHECK-NEXT:    ret i32 [[SEL]]
3434;
3435  %not_cond = xor i1 %cond, true
3436  %zext = zext i1 %not_cond to i32
3437  %sel = select i1 %cond, i32 %zext, i32 %b
3438  ret i32 %sel
3439}
3440
3441define i32 @select_cond_sext_not_cond_val(i1 %cond, i32 %b) {
3442; CHECK-LABEL: @select_cond_sext_not_cond_val(
3443; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 0, i32 [[B:%.*]]
3444; CHECK-NEXT:    ret i32 [[SEL]]
3445;
3446  %not_cond = xor i1 %cond, true
3447  %sext = sext i1 %not_cond to i32
3448  %sel = select i1 %cond, i32 %sext, i32 %b
3449  ret i32 %sel
3450}
3451
3452
3453define i32 @select_cond_val_zext_not_cond(i1 %cond, i32 %b) {
3454; CHECK-LABEL: @select_cond_val_zext_not_cond(
3455; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 1
3456; CHECK-NEXT:    ret i32 [[SEL]]
3457;
3458  %not_cond = xor i1 %cond, true
3459  %zext = zext i1 %not_cond to i32
3460  %sel = select i1 %cond, i32 %b, i32 %zext
3461  ret i32 %sel
3462}
3463
3464define i32 @select_cond_val_sext_not_cond(i1 %cond, i32 %b) {
3465; CHECK-LABEL: @select_cond_val_sext_not_cond(
3466; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 -1
3467; CHECK-NEXT:    ret i32 [[SEL]]
3468;
3469  %not_cond = xor i1 %cond, true
3470  %sext = sext i1 %not_cond to i32
3471  %sel = select i1 %cond, i32 %b, i32 %sext
3472  ret i32 %sel
3473}
3474
3475define i32 @select_cond_not_cond_cond1(i1 %cond) {
3476; CHECK-LABEL: @select_cond_not_cond_cond1(
3477; CHECK-NEXT:    ret i32 0
3478;
3479  %z = zext i1 %cond to i32
3480  %not_cond = xor i1 %cond, true
3481  %s = sext i1 %not_cond to i32
3482  %v = select i1 %cond, i32 %s, i32 %z
3483  ret i32 %v
3484}
3485
3486define i32 @select_cond_not_cond_cond2(i1 %cond) {
3487; CHECK-LABEL: @select_cond_not_cond_cond2(
3488; CHECK-NEXT:    ret i32 0
3489;
3490  %z = sext i1 %cond to i32
3491  %not_cond = xor i1 %cond, true
3492  %s = zext i1 %not_cond to i32
3493  %v = select i1 %cond, i32 %s, i32 %z
3494  ret i32 %v
3495}
3496
3497; This previously crashed due to Constant::getUniqueInteger not handling
3498; scalable vector splat ConstantExprs.
3499define <vscale x 2 x i32> @and_constant_select_svec(<vscale x 2 x i32> %x, <vscale x 2 x i1> %cond) {
3500; CHECK-LABEL: @and_constant_select_svec(
3501; CHECK-NEXT:    [[A:%.*]] = and <vscale x 2 x i32> [[X:%.*]], splat (i32 1)
3502; CHECK-NEXT:    [[B:%.*]] = select <vscale x 2 x i1> [[COND:%.*]], <vscale x 2 x i32> [[A]], <vscale x 2 x i32> [[X]]
3503; CHECK-NEXT:    ret <vscale x 2 x i32> [[B]]
3504;
3505  %a = and <vscale x 2 x i32> %x, splat (i32 1)
3506  %b = select <vscale x 2 x i1> %cond, <vscale x 2 x i32> %a, <vscale x 2 x i32> %x
3507  ret <vscale x 2 x i32> %b
3508}
3509
3510define <vscale x 2 x i32> @scalable_sign_bits(<vscale x 2 x i8> %x) {
3511; CHECK-LABEL: @scalable_sign_bits(
3512; CHECK-NEXT:    [[A:%.*]] = sext <vscale x 2 x i8> [[X:%.*]] to <vscale x 2 x i32>
3513; CHECK-NEXT:    [[B:%.*]] = shl nsw <vscale x 2 x i32> [[A]], splat (i32 16)
3514; CHECK-NEXT:    ret <vscale x 2 x i32> [[B]]
3515;
3516  %a = sext <vscale x 2 x i8> %x to <vscale x 2 x i32>
3517  %b = shl <vscale x 2 x i32> %a, splat (i32 16)
3518  ret <vscale x 2 x i32> %b
3519}
3520
3521define <vscale x 2 x i1> @scalable_non_zero(<vscale x 2 x i32> %x) {
3522; CHECK-LABEL: @scalable_non_zero(
3523; CHECK-NEXT:    [[A:%.*]] = or <vscale x 2 x i32> [[X:%.*]], splat (i32 1)
3524; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <vscale x 2 x i32> [[A]], splat (i32 57)
3525; CHECK-NEXT:    ret <vscale x 2 x i1> [[CMP]]
3526;
3527  %a = or <vscale x 2 x i32> %x, splat (i32 1)
3528  %b = add <vscale x 2 x i32> %a, splat (i32 -1)
3529  %cmp = icmp ult <vscale x 2 x i32> %b, splat (i32 56)
3530  ret <vscale x 2 x i1> %cmp
3531}
3532
3533define i32 @clamp_umin(i32 %x) {
3534; CHECK-LABEL: @clamp_umin(
3535; CHECK-NEXT:    [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 1)
3536; CHECK-NEXT:    ret i32 [[SEL]]
3537;
3538  %cmp = icmp eq i32 %x, 0
3539  %sel = select i1 %cmp, i32 1, i32 %x
3540  ret i32 %sel
3541}
3542
3543define i32 @clamp_umin_use(i32 %x) {
3544; CHECK-LABEL: @clamp_umin_use(
3545; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
3546; CHECK-NEXT:    call void @use1(i1 [[CMP]])
3547; CHECK-NEXT:    [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1)
3548; CHECK-NEXT:    ret i32 [[SEL]]
3549;
3550  %cmp = icmp eq i32 %x, 0
3551  call void @use1(i1 %cmp)
3552  %sel = select i1 %cmp, i32 1, i32 %x
3553  ret i32 %sel
3554}
3555
3556; negative test - wrong cmp constant
3557
3558define i32 @not_clamp_umin1(i32 %x) {
3559; CHECK-LABEL: @not_clamp_umin1(
3560; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2
3561; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 [[X]]
3562; CHECK-NEXT:    ret i32 [[SEL]]
3563;
3564  %cmp = icmp eq i32 %x, 2
3565  %sel = select i1 %cmp, i32 1, i32 %x
3566  ret i32 %sel
3567}
3568
3569; negative test - wrong select constant
3570
3571define i32 @not_clamp_umin2(i32 %x) {
3572; CHECK-LABEL: @not_clamp_umin2(
3573; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
3574; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[X]]
3575; CHECK-NEXT:    ret i32 [[SEL]]
3576;
3577  %cmp = icmp eq i32 %x, 0
3578  %sel = select i1 %cmp, i32 -1, i32 %x
3579  ret i32 %sel
3580}
3581
3582define <2 x i8> @clamp_umaxval(<2 x i8> %x) {
3583; CHECK-LABEL: @clamp_umaxval(
3584; CHECK-NEXT:    [[SEL:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 -2))
3585; CHECK-NEXT:    ret <2 x i8> [[SEL]]
3586;
3587  %cmp = icmp eq <2 x i8> %x, <i8 255, i8 255>
3588  %sel = select <2 x i1> %cmp, <2 x i8> <i8 254, i8 254>, <2 x i8> %x
3589  ret <2 x i8> %sel
3590}
3591
3592; negative test - wrong cmp constant
3593
3594define i8 @not_clamp_umax1(i8 %x) {
3595; CHECK-LABEL: @not_clamp_umax1(
3596; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -3
3597; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 -2, i8 [[X]]
3598; CHECK-NEXT:    ret i8 [[SEL]]
3599;
3600  %cmp = icmp eq i8 %x, 253
3601  %sel = select i1 %cmp, i8 254, i8 %x
3602  ret i8 %sel
3603}
3604
3605; negative test - wrong select constant
3606
3607define i8 @not_clamp_umax2(i8 %x) {
3608; CHECK-LABEL: @not_clamp_umax2(
3609; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -1
3610; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 1, i8 [[X]]
3611; CHECK-NEXT:    ret i8 [[SEL]]
3612;
3613  %cmp = icmp eq i8 %x, 255
3614  %sel = select i1 %cmp, i8 1, i8 %x
3615  ret i8 %sel
3616}
3617
3618define i8 @clamp_smin(i8 %x) {
3619; CHECK-LABEL: @clamp_smin(
3620; CHECK-NEXT:    [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 -127)
3621; CHECK-NEXT:    ret i8 [[SEL]]
3622;
3623  %cmp = icmp eq i8 %x, -128
3624  %sel = select i1 %cmp, i8 -127, i8 %x
3625  ret i8 %sel
3626}
3627
3628define i8 @clamp_smin_use(i8 %x) {
3629; CHECK-LABEL: @clamp_smin_use(
3630; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128
3631; CHECK-NEXT:    call void @use1(i1 [[CMP]])
3632; CHECK-NEXT:    [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 -127)
3633; CHECK-NEXT:    ret i8 [[SEL]]
3634;
3635  %cmp = icmp eq i8 %x, -128
3636  call void @use1(i1 %cmp)
3637  %sel = select i1 %cmp, i8 -127, i8 %x
3638  ret i8 %sel
3639}
3640
3641; negative test - wrong cmp constant
3642
3643define i8 @not_clamp_smin1(i8 %x) {
3644; CHECK-LABEL: @not_clamp_smin1(
3645; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 127
3646; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 -127, i8 [[X]]
3647; CHECK-NEXT:    ret i8 [[SEL]]
3648;
3649  %cmp = icmp eq i8 %x, 127
3650  %sel = select i1 %cmp, i8 -127, i8 %x
3651  ret i8 %sel
3652}
3653
3654; negative test - wrong select constant
3655
3656define i8 @not_clamp_smin2(i8 %x) {
3657; CHECK-LABEL: @not_clamp_smin2(
3658; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128
3659; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 -1, i8 [[X]]
3660; CHECK-NEXT:    ret i8 [[SEL]]
3661;
3662  %cmp = icmp eq i8 %x, -128
3663  %sel = select i1 %cmp, i8 -1, i8 %x
3664  ret i8 %sel
3665}
3666
3667define <2 x i8> @clamp_smaxval(<2 x i8> %x) {
3668; CHECK-LABEL: @clamp_smaxval(
3669; CHECK-NEXT:    [[SEL:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 126))
3670; CHECK-NEXT:    ret <2 x i8> [[SEL]]
3671;
3672  %cmp = icmp eq <2 x i8> %x, <i8 127, i8 127>
3673  %sel = select <2 x i1> %cmp, <2 x i8> <i8 126, i8 126>, <2 x i8> %x
3674  ret <2 x i8> %sel
3675}
3676
3677; negative test - wrong cmp constant
3678
3679define i8 @not_clamp_smax1(i8 %x) {
3680; CHECK-LABEL: @not_clamp_smax1(
3681; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128
3682; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 126, i8 [[X]]
3683; CHECK-NEXT:    ret i8 [[SEL]]
3684;
3685  %cmp = icmp eq i8 %x, -128
3686  %sel = select i1 %cmp, i8 126, i8 %x
3687  ret i8 %sel
3688}
3689
3690; negative test - wrong select constant
3691
3692define i8 @not_clamp_smax2(i8 %x) {
3693; CHECK-LABEL: @not_clamp_smax2(
3694; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 127
3695; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 125, i8 [[X]]
3696; CHECK-NEXT:    ret i8 [[SEL]]
3697;
3698  %cmp = icmp eq i8 %x, 127
3699  %sel = select i1 %cmp, i8 125, i8 %x
3700  ret i8 %sel
3701}
3702
3703; Used to infinite loop.
3704define i32 @pr61361(i32 %arg) {
3705; CHECK-LABEL: @pr61361(
3706; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[ARG:%.*]], 0
3707; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[CMP2]], i32 16777215, i32 0
3708; CHECK-NEXT:    ret i32 [[SEL2]]
3709;
3710  %cmp1 = icmp eq i32 %arg, 1
3711  %sel1 = select i1 %cmp1, i32 0, i32 33554431
3712  %cmp2 = icmp eq i32 %arg, 0
3713  %sel2 = select i1 %cmp2, i32 %sel1, i32 0
3714  %ashr = ashr i32 %sel2, 1
3715  ret i32 %ashr
3716}
3717
3718define i32 @pr62088() {
3719; CHECK-LABEL: @pr62088(
3720; CHECK-NEXT:  entry:
3721; CHECK-NEXT:    br label [[LOOP:%.*]]
3722; CHECK:       loop:
3723; CHECK-NEXT:    [[NOT2:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ -2, [[LOOP]] ]
3724; CHECK-NEXT:    [[H_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ 1, [[LOOP]] ]
3725; CHECK-NEXT:    [[XOR:%.*]] = or disjoint i32 [[H_0]], [[NOT2]]
3726; CHECK-NEXT:    [[SUB5:%.*]] = sub i32 -1824888657, [[XOR]]
3727; CHECK-NEXT:    [[XOR6:%.*]] = xor i32 [[SUB5]], -1260914025
3728; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[XOR6]], 824855120
3729; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
3730; CHECK:       exit:
3731; CHECK-NEXT:    ret i32 [[H_0]]
3732;
3733entry:
3734  br label %loop
3735
3736loop:
3737  %not2 = phi i32 [ 0, %entry ], [ -2, %loop ]
3738  %i.0 = phi i32 [ 0, %entry ], [ %shr, %loop ]
3739  %h.0 = phi i32 [ 0, %entry ], [ 1, %loop ]
3740  %i.0.fr = freeze i32 %i.0
3741  %sext = shl i32 %i.0.fr, 16
3742  %conv = ashr exact i32 %sext, 16
3743  %not = xor i32 %conv, -1
3744  %and = and i32 %h.0, 1
3745  %rem.urem = sub nsw i32 %and, %conv
3746  %rem.cmp = icmp ult i32 %and, %conv
3747  %rem = select i1 %rem.cmp, i32 %not, i32 %rem.urem
3748  %xor = xor i32 %rem, %not2
3749  %sub = sub nsw i32 0, %xor
3750  %sub5 = sub i32 -1824888657, %xor
3751  %xor6 = xor i32 %sub5, -1260914025
3752  %cmp = icmp slt i32 %xor6, 824855120
3753  %shr = ashr i32 %xor6, 40
3754  br i1 %cmp, label %loop, label %exit
3755
3756exit:
3757  ret i32 %rem
3758}
3759
3760; Select icmp and/or/xor
3761; https://alive2.llvm.org/ce/z/QXQDwF
3762; X&Y==C?X|Y:X^Y, X&Y==C?X^Y:X|Y
3763; TODO: X&Y==0 could imply no_common_bit to TrueValue
3764define i32 @src_and_eq_0_or_xor(i32 %x, i32 %y) {
3765; CHECK-LABEL: @src_and_eq_0_or_xor(
3766; CHECK-NEXT:  entry:
3767; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3768; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
3769; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
3770; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3771; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[XOR]]
3772; CHECK-NEXT:    ret i32 [[COND]]
3773;
3774entry:
3775  %and = and i32 %y, %x
3776  %cmp = icmp eq i32 %and, 0
3777  %or = or i32 %y, %x
3778  %xor = xor i32 %y, %x
3779  %cond = select i1 %cmp, i32 %or, i32 %xor
3780  ret i32 %cond
3781}
3782
3783; TODO: X&Y==0 could imply no_common_bit to TrueValue
3784define i32 @src_and_eq_0_xor_or(i32 %x, i32 %y) {
3785; CHECK-LABEL: @src_and_eq_0_xor_or(
3786; CHECK-NEXT:  entry:
3787; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3788; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
3789; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3790; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
3791; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[OR]]
3792; CHECK-NEXT:    ret i32 [[COND]]
3793;
3794entry:
3795  %and = and i32 %y, %x
3796  %cmp = icmp eq i32 %and, 0
3797  %xor = xor i32 %y, %x
3798  %or = or i32 %y, %x
3799  %cond = select i1 %cmp, i32 %xor, i32 %or
3800  ret i32 %cond
3801}
3802
3803; TODO: X&Y==-1 could imply all_common_bit to TrueValue
3804define i32 @src_and_eq_neg1_or_xor(i32 %x, i32 %y) {
3805; CHECK-LABEL: @src_and_eq_neg1_or_xor(
3806; CHECK-NEXT:  entry:
3807; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3808; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -1
3809; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3810; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[XOR]]
3811; CHECK-NEXT:    ret i32 [[COND]]
3812;
3813entry:
3814  %and = and i32 %y, %x
3815  %cmp = icmp eq i32 %and, -1
3816  %or = or i32 %y, %x
3817  %xor = xor i32 %y, %x
3818  %cond = select i1 %cmp, i32 %or, i32 %xor
3819  ret i32 %cond
3820}
3821
3822; TODO: X&Y==-1 could imply all_common_bit to TrueValue
3823define i32 @src_and_eq_neg1_xor_or(i32 %x, i32 %y) {
3824; CHECK-LABEL: @src_and_eq_neg1_xor_or(
3825; CHECK-NEXT:  entry:
3826; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3827; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -1
3828; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
3829; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 0, i32 [[OR]]
3830; CHECK-NEXT:    ret i32 [[COND]]
3831;
3832entry:
3833  %and = and i32 %y, %x
3834  %cmp = icmp eq i32 %and, -1
3835  %xor = xor i32 %y, %x
3836  %or = or i32 %y, %x
3837  %cond = select i1 %cmp, i32 %xor, i32 %or
3838  ret i32 %cond
3839}
3840
3841define i32 @src_and_eq_C_or_xororC(i32 %x, i32 %y, i32 %c) {
3842; CHECK-LABEL: @src_and_eq_C_or_xororC(
3843; CHECK-NEXT:  entry:
3844; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3845; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], [[C:%.*]]
3846; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
3847; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3848; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[XOR]], [[C]]
3849; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[OR1]]
3850; CHECK-NEXT:    ret i32 [[COND]]
3851;
3852entry:
3853  %and = and i32 %y, %x
3854  %cmp = icmp eq i32 %and, %c
3855  %or = or i32 %y, %x
3856  %xor = xor i32 %y, %x
3857  %or1 = or i32 %xor, %c
3858  %cond = select i1 %cmp, i32 %or, i32 %or1
3859  ret i32 %cond
3860}
3861
3862define i32 @src_and_eq_C_or_xorxorC(i32 %x, i32 %y, i32 %c) {
3863; CHECK-LABEL: @src_and_eq_C_or_xorxorC(
3864; CHECK-NEXT:  entry:
3865; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3866; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], [[C:%.*]]
3867; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
3868; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3869; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[XOR]], [[C]]
3870; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[XOR1]]
3871; CHECK-NEXT:    ret i32 [[COND]]
3872;
3873entry:
3874  %and = and i32 %y, %x
3875  %cmp = icmp eq i32 %and, %c
3876  %or = or i32 %y, %x
3877  %xor = xor i32 %y, %x
3878  %xor1 = xor i32 %xor, %c
3879  %cond = select i1 %cmp, i32 %or, i32 %xor1
3880  ret i32 %cond
3881}
3882
3883define i32 @src_and_eq_C_xor_OrAndNotC(i32 %x, i32 %y, i32 %c) {
3884; CHECK-LABEL: @src_and_eq_C_xor_OrAndNotC(
3885; CHECK-NEXT:  entry:
3886; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3887; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], [[C:%.*]]
3888; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3889; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
3890; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[C]], -1
3891; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[OR]], [[NOT]]
3892; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[AND1]]
3893; CHECK-NEXT:    ret i32 [[COND]]
3894;
3895entry:
3896  %and = and i32 %y, %x
3897  %cmp = icmp eq i32 %and, %c
3898  %xor = xor i32 %y, %x
3899  %or = or i32 %y, %x
3900  %not = xor i32 %c, -1
3901  %and1 = and i32 %or, %not
3902  %cond = select i1 %cmp, i32 %xor, i32 %and1
3903  ret i32 %cond
3904}
3905
3906define <2 x i32> @src_and_eq_C_xor_OrAndNotC_vec_poison(<2 x i32> %0, <2 x i32> %1, <2 x i32> %2) {
3907; CHECK-LABEL: @src_and_eq_C_xor_OrAndNotC_vec_poison(
3908; CHECK-NEXT:  entry:
3909; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[TMP1:%.*]], [[TMP0:%.*]]
3910; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], [[TMP2:%.*]]
3911; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[TMP1]], [[TMP0]]
3912; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[TMP1]], [[TMP0]]
3913; CHECK-NEXT:    [[NOT:%.*]] = xor <2 x i32> [[TMP2]], <i32 -1, i32 poison>
3914; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i32> [[OR]], [[NOT]]
3915; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[XOR]], <2 x i32> [[AND1]]
3916; CHECK-NEXT:    ret <2 x i32> [[COND]]
3917;
3918entry:
3919  %and = and <2 x i32> %1, %0
3920  %cmp = icmp eq <2 x i32> %and, %2
3921  %xor = xor <2 x i32> %1, %0
3922  %or = or <2 x i32> %1, %0
3923  %not = xor <2 x i32> %2, <i32 -1, i32 poison>
3924  %and1 = and <2 x i32> %or, %not
3925  %cond = select <2 x i1> %cmp, <2 x i32> %xor, <2 x i32> %and1
3926  ret <2 x i32> %cond
3927}
3928
3929define i32 @src_and_eq_C_xor_orxorC(i32 %x, i32 %y, i32 %c) {
3930; CHECK-LABEL: @src_and_eq_C_xor_orxorC(
3931; CHECK-NEXT:  entry:
3932; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3933; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], [[C:%.*]]
3934; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3935; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
3936; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[OR]], [[C]]
3937; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[XOR1]]
3938; CHECK-NEXT:    ret i32 [[COND]]
3939;
3940entry:
3941  %and = and i32 %y, %x
3942  %cmp = icmp eq i32 %and, %c
3943  %xor = xor i32 %y, %x
3944  %or = or i32 %y, %x
3945  %xor1 = xor i32 %or, %c
3946  %cond = select i1 %cmp, i32 %xor, i32 %xor1
3947  ret i32 %cond
3948}
3949
3950; https://alive2.llvm.org/ce/z/9RPwfN
3951; X|Y==C?X&Y:X^Y, X|Y==C?X^Y:X&Y
3952; TODO: X|Y==0 could imply no_common_bit to TrueValue
3953define i32 @src_or_eq_0_and_xor(i32 %x, i32 %y) {
3954; CHECK-LABEL: @src_or_eq_0_and_xor(
3955; CHECK-NEXT:  entry:
3956; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
3957; CHECK-NEXT:    ret i32 [[XOR]]
3958;
3959entry:
3960  %or = or i32 %y, %x
3961  %cmp = icmp eq i32 %or, 0
3962  %and = and i32 %y, %x
3963  %xor = xor i32 %y, %x
3964  %cond = select i1 %cmp, i32 %and, i32 %xor
3965  ret i32 %cond
3966}
3967
3968; TODO: X|Y==0 could imply no_common_bit to TrueValue
3969define i32 @src_or_eq_0_xor_and(i32 %x, i32 %y) {
3970; CHECK-LABEL: @src_or_eq_0_xor_and(
3971; CHECK-NEXT:  entry:
3972; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3973; CHECK-NEXT:    ret i32 [[AND]]
3974;
3975entry:
3976  %or = or i32 %y, %x
3977  %cmp = icmp eq i32 %or, 0
3978  %xor = xor i32 %y, %x
3979  %and = and i32 %y, %x
3980  %cond = select i1 %cmp, i32 %xor, i32 %and
3981  ret i32 %cond
3982}
3983
3984define i32 @src_or_eq_neg1_and_xor(i32 %x, i32 %y) {
3985; CHECK-LABEL: @src_or_eq_neg1_and_xor(
3986; CHECK-NEXT:  entry:
3987; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
3988; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -1
3989; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
3990; CHECK-NEXT:    [[TMP0:%.*]] = xor i32 [[X]], [[Y]]
3991; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[TMP0]], -1
3992; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[NOT]]
3993; CHECK-NEXT:    ret i32 [[COND]]
3994;
3995entry:
3996  %or = or i32 %y, %x
3997  %cmp = icmp eq i32 %or, -1
3998  %and = and i32 %y, %x
3999  %0 = xor i32 %x, %y
4000  %not = xor i32 %0, -1
4001  %cond = select i1 %cmp, i32 %and, i32 %not
4002  ret i32 %cond
4003}
4004
4005define i32 @src_or_eq_neg1_xor_and(i32 %x, i32 %y) {
4006; CHECK-LABEL: @src_or_eq_neg1_xor_and(
4007; CHECK-NEXT:  entry:
4008; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
4009; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -1
4010; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
4011; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
4012; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[AND]], -1
4013; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[NOT]]
4014; CHECK-NEXT:    ret i32 [[COND]]
4015;
4016entry:
4017  %or = or i32 %y, %x
4018  %cmp = icmp eq i32 %or, -1
4019  %xor = xor i32 %y, %x
4020  %and = and i32 %y, %x
4021  %not = xor i32 %and, -1
4022  %cond = select i1 %cmp, i32 %xor, i32 %not
4023  ret i32 %cond
4024}
4025
4026define i32 @src_or_eq_C_and_xorC(i32 %x, i32 %y, i32 %c) {
4027; CHECK-LABEL: @src_or_eq_C_and_xorC(
4028; CHECK-NEXT:  entry:
4029; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
4030; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], [[C:%.*]]
4031; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
4032; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
4033; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[XOR]], [[C]]
4034; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[XOR1]]
4035; CHECK-NEXT:    ret i32 [[COND]]
4036;
4037entry:
4038  %or = or i32 %y, %x
4039  %cmp = icmp eq i32 %or, %c
4040  %and = and i32 %y, %x
4041  %xor = xor i32 %y, %x
4042  %xor1 = xor i32 %xor, %c
4043  %cond = select i1 %cmp, i32 %and, i32 %xor1
4044  ret i32 %cond
4045}
4046
4047define i32 @src_or_eq_C_and_andnotxorC(i32 %x, i32 %y, i32 %c) {
4048; CHECK-LABEL: @src_or_eq_C_and_andnotxorC(
4049; CHECK-NEXT:  entry:
4050; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
4051; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], [[C:%.*]]
4052; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
4053; CHECK-NEXT:    [[TMP0:%.*]] = xor i32 [[X]], [[Y]]
4054; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[TMP0]], -1
4055; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT]]
4056; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[AND1]]
4057; CHECK-NEXT:    ret i32 [[COND]]
4058;
4059entry:
4060  %or = or i32 %y, %x
4061  %cmp = icmp eq i32 %or, %c
4062  %and = and i32 %y, %x
4063  %0 = xor i32 %x, %y
4064  %not = xor i32 %0, -1
4065  %and1 = and i32 %not, %c
4066  %cond = select i1 %cmp, i32 %and, i32 %and1
4067  ret i32 %cond
4068}
4069
4070define i32 @src_or_eq_C_xor_xorandC(i32 %x, i32 %y, i32 %c) {
4071; CHECK-LABEL: @src_or_eq_C_xor_xorandC(
4072; CHECK-NEXT:  entry:
4073; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
4074; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], [[C:%.*]]
4075; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
4076; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
4077; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[AND]], [[C]]
4078; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[XOR1]]
4079; CHECK-NEXT:    ret i32 [[COND]]
4080;
4081entry:
4082  %or = or i32 %y, %x
4083  %cmp = icmp eq i32 %or, %c
4084  %xor = xor i32 %y, %x
4085  %and = and i32 %y, %x
4086  %xor1 = xor i32 %and, %c
4087  %cond = select i1 %cmp, i32 %xor, i32 %xor1
4088  ret i32 %cond
4089}
4090
4091define i32 @src_or_eq_C_xor_andnotandC(i32 %x, i32 %y, i32 %c) {
4092; CHECK-LABEL: @src_or_eq_C_xor_andnotandC(
4093; CHECK-NEXT:  entry:
4094; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
4095; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], [[C:%.*]]
4096; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
4097; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
4098; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[AND]], -1
4099; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT]]
4100; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[AND1]]
4101; CHECK-NEXT:    ret i32 [[COND]]
4102;
4103entry:
4104  %or = or i32 %y, %x
4105  %cmp = icmp eq i32 %or, %c
4106  %xor = xor i32 %y, %x
4107  %and = and i32 %y, %x
4108  %not = xor i32 %and, -1
4109  %and1 = and i32 %not, %c
4110  %cond = select i1 %cmp, i32 %xor, i32 %and1
4111  ret i32 %cond
4112}
4113
4114; https://alive2.llvm.org/ce/z/c6oXi4
4115; X^Y==C?X&Y:X|Y, X^Y==C?X|Y:X&Y
4116define i32 @src_xor_eq_neg1_and(i32 %x, i32 %y) {
4117; CHECK-LABEL: @src_xor_eq_neg1_and(
4118; CHECK-NEXT:  entry:
4119; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
4120; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], -1
4121; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
4122; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
4123; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[OR]], -1
4124; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[NOT]]
4125; CHECK-NEXT:    ret i32 [[COND]]
4126;
4127entry:
4128  %xor = xor i32 %y, %x
4129  %cmp = icmp eq i32 %xor, -1
4130  %and = and i32 %y, %x
4131  %or = or i32 %y, %x
4132  %not = xor i32 %or, -1
4133  %cond = select i1 %cmp, i32 %and, i32 %not
4134  ret i32 %cond
4135}
4136
4137; TODO: X^Y==-1 could imply no_common_bit to TrueValue
4138define i32 @src_xor_eq_neg1_or(i32 %x, i32 %y) {
4139; CHECK-LABEL: @src_xor_eq_neg1_or(
4140; CHECK-NEXT:  entry:
4141; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
4142; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], -1
4143; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
4144; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 -1
4145; CHECK-NEXT:    ret i32 [[COND]]
4146;
4147entry:
4148  %xor = xor i32 %y, %x
4149  %cmp = icmp eq i32 %xor, -1
4150  %or = or i32 %y, %x
4151  %cond = select i1 %cmp, i32 %or, i32 -1
4152  ret i32 %cond
4153}
4154
4155define i32 @src_xor_eq_C_and_xororC(i32 %x, i32 %y, i32 %c) {
4156; CHECK-LABEL: @src_xor_eq_C_and_xororC(
4157; CHECK-NEXT:  entry:
4158; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
4159; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C:%.*]]
4160; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
4161; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
4162; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[OR]], [[C]]
4163; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[XOR1]]
4164; CHECK-NEXT:    ret i32 [[COND]]
4165;
4166entry:
4167  %xor = xor i32 %y, %x
4168  %cmp = icmp eq i32 %xor, %c
4169  %and = and i32 %y, %x
4170  %or = or i32 %y, %x
4171  %xor1 = xor i32 %or, %c
4172  %cond = select i1 %cmp, i32 %and, i32 %xor1
4173  ret i32 %cond
4174}
4175
4176define i32 @src_xor_eq_C_and_andornotC(i32 %x, i32 %y, i32 %c) {
4177; CHECK-LABEL: @src_xor_eq_C_and_andornotC(
4178; CHECK-NEXT:  entry:
4179; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
4180; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C:%.*]]
4181; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
4182; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
4183; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[C]], -1
4184; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[OR]], [[NOT]]
4185; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[AND1]]
4186; CHECK-NEXT:    ret i32 [[COND]]
4187;
4188entry:
4189  %xor = xor i32 %y, %x
4190  %cmp = icmp eq i32 %xor, %c
4191  %and = and i32 %y, %x
4192  %or = or i32 %y, %x
4193  %not = xor i32 %c, -1
4194  %and1 = and i32 %or, %not
4195  %cond = select i1 %cmp, i32 %and, i32 %and1
4196  ret i32 %cond
4197}
4198
4199define i32 @src_xor_eq_C_or_xorandC(i32 %x, i32 %y, i32 %c) {
4200; CHECK-LABEL: @src_xor_eq_C_or_xorandC(
4201; CHECK-NEXT:  entry:
4202; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
4203; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C:%.*]]
4204; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
4205; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
4206; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[AND]], [[C]]
4207; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[XOR1]]
4208; CHECK-NEXT:    ret i32 [[COND]]
4209;
4210entry:
4211  %xor = xor i32 %y, %x
4212  %cmp = icmp eq i32 %xor, %c
4213  %or = or i32 %y, %x
4214  %and = and i32 %y, %x
4215  %xor1 = xor i32 %and, %c
4216  %cond = select i1 %cmp, i32 %or, i32 %xor1
4217  ret i32 %cond
4218}
4219
4220define i32 @src_xor_eq_C_or_orandC(i32 %x, i32 %y, i32 %c) {
4221; CHECK-LABEL: @src_xor_eq_C_or_orandC(
4222; CHECK-NEXT:  entry:
4223; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
4224; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C:%.*]]
4225; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]
4226; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]
4227; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[AND]], [[C]]
4228; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[OR1]]
4229; CHECK-NEXT:    ret i32 [[COND]]
4230;
4231entry:
4232  %xor = xor i32 %y, %x
4233  %cmp = icmp eq i32 %xor, %c
4234  %or = or i32 %y, %x
4235  %and = and i32 %y, %x
4236  %or1 = or i32 %and, %c
4237  %cond = select i1 %cmp, i32 %or, i32 %or1
4238  ret i32 %cond
4239}
4240
4241; Select icmp and/or/xor
4242; NO TRANSFORMED - select condition is compare with not 0
4243define i32 @src_select_and_min_positive_int(i32 %x, i32 %y) {
4244; CHECK-LABEL: @src_select_and_min_positive_int(
4245; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4246; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 1
4247; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4248; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4249; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]]
4250; CHECK-NEXT:    ret i32 [[COND]]
4251;
4252  %and = and i32 %x, %y
4253  %and0 = icmp eq i32 %and, 1
4254  %xor = xor i32 %x, %y
4255  %or = or i32 %x, %y
4256  %cond = select i1 %and0, i32 %or, i32 %xor
4257  ret i32 %cond
4258}
4259
4260define i32 @src_select_and_max_positive_int(i32 %x, i32 %y) {
4261; CHECK-LABEL: @src_select_and_max_positive_int(
4262; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4263; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 2147483647
4264; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4265; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4266; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]]
4267; CHECK-NEXT:    ret i32 [[COND]]
4268;
4269  %and = and i32 %x, %y
4270  %and0 = icmp eq i32 %and, 2147483647
4271  %xor = xor i32 %x, %y
4272  %or = or i32 %x, %y
4273  %cond = select i1 %and0, i32 %or, i32 %xor
4274  ret i32 %cond
4275}
4276
4277define i32 @src_select_and_min_negative_int(i32 %x, i32 %y) {
4278; CHECK-LABEL: @src_select_and_min_negative_int(
4279; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4280; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], -2147483648
4281; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4282; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4283; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]]
4284; CHECK-NEXT:    ret i32 [[COND]]
4285;
4286  %and = and i32 %x, %y
4287  %and0 = icmp eq i32 %and, -2147483648
4288  %xor = xor i32 %x, %y
4289  %or = or i32 %x, %y
4290  %cond = select i1 %and0, i32 %or, i32 %xor
4291  ret i32 %cond
4292}
4293
4294define i32 @src_select_or_min_positive_int(i32 %x, i32 %y) {
4295; CHECK-LABEL: @src_select_or_min_positive_int(
4296; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4297; CHECK-NEXT:    [[OR0:%.*]] = icmp eq i32 [[OR]], 1
4298; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
4299; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4300; CHECK-NEXT:    [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]
4301; CHECK-NEXT:    ret i32 [[COND]]
4302;
4303  %or = or i32 %x, %y
4304  %or0 = icmp eq i32 %or, 1
4305  %and = and i32 %x, %y
4306  %xor = xor i32 %x, %y
4307  %cond = select i1 %or0, i32 %and, i32 %xor
4308  ret i32 %cond
4309}
4310
4311define i32 @src_select_or_max_positive_int(i32 %x, i32 %y) {
4312; CHECK-LABEL: @src_select_or_max_positive_int(
4313; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4314; CHECK-NEXT:    [[OR0:%.*]] = icmp eq i32 [[OR]], 2147483647
4315; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
4316; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4317; CHECK-NEXT:    [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]
4318; CHECK-NEXT:    ret i32 [[COND]]
4319;
4320  %or = or i32 %x, %y
4321  %or0 = icmp eq i32 %or, 2147483647
4322  %and = and i32 %x, %y
4323  %xor = xor i32 %x, %y
4324  %cond = select i1 %or0, i32 %and, i32 %xor
4325  ret i32 %cond
4326}
4327
4328define i32 @src_select_or_min_negative_int(i32 %x, i32 %y) {
4329; CHECK-LABEL: @src_select_or_min_negative_int(
4330; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4331; CHECK-NEXT:    [[OR0:%.*]] = icmp eq i32 [[OR]], -2147483648
4332; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
4333; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4334; CHECK-NEXT:    [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]
4335; CHECK-NEXT:    ret i32 [[COND]]
4336;
4337  %or = or i32 %x, %y
4338  %or0 = icmp eq i32 %or, -2147483648
4339  %and = and i32 %x, %y
4340  %xor = xor i32 %x, %y
4341  %cond = select i1 %or0, i32 %and, i32 %xor
4342  ret i32 %cond
4343}
4344
4345define i32 @src_select_or_max_negative_int(i32 %x, i32 %y) {
4346; CHECK-LABEL: @src_select_or_max_negative_int(
4347; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4348; CHECK-NEXT:    [[OR0:%.*]] = icmp eq i32 [[OR]], -1
4349; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
4350; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4351; CHECK-NEXT:    [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]
4352; CHECK-NEXT:    ret i32 [[COND]]
4353;
4354  %or = or i32 %x, %y
4355  %or0 = icmp eq i32 %or, -1
4356  %and = and i32 %x, %y
4357  %xor = xor i32 %x, %y
4358  %cond = select i1 %or0, i32 %and, i32 %xor
4359  ret i32 %cond
4360}
4361
4362define i32 @src_select_xor_min_positive_int(i32 %x, i32 %y) {
4363; CHECK-LABEL: @src_select_xor_min_positive_int(
4364; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4365; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[XOR]], 1
4366; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
4367; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4368; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]
4369; CHECK-NEXT:    ret i32 [[COND]]
4370;
4371  %xor = xor i32 %x, %y
4372  %xor0 = icmp eq i32 %xor, 1
4373  %and = and i32 %x, %y
4374  %or = or i32 %x, %y
4375  %cond = select i1 %xor0, i32 %and, i32 %or
4376  ret i32 %cond
4377}
4378
4379define i32 @src_select_xor_max_positive_int(i32 %x, i32 %y) {
4380; CHECK-LABEL: @src_select_xor_max_positive_int(
4381; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4382; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[XOR]], 2147483647
4383; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
4384; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4385; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]
4386; CHECK-NEXT:    ret i32 [[COND]]
4387;
4388  %xor = xor i32 %x, %y
4389  %xor0 = icmp eq i32 %xor, 2147483647
4390  %and = and i32 %x, %y
4391  %or = or i32 %x, %y
4392  %cond = select i1 %xor0, i32 %and, i32 %or
4393  ret i32 %cond
4394}
4395
4396define i32 @src_select_xor_min_negative_int(i32 %x, i32 %y) {
4397; CHECK-LABEL: @src_select_xor_min_negative_int(
4398; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4399; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[XOR]], -2147483648
4400; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
4401; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4402; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]
4403; CHECK-NEXT:    ret i32 [[COND]]
4404;
4405  %xor = xor i32 %x, %y
4406  %xor0 = icmp eq i32 %xor, -2147483648
4407  %and = and i32 %x, %y
4408  %or = or i32 %x, %y
4409  %cond = select i1 %xor0, i32 %and, i32 %or
4410  ret i32 %cond
4411}
4412
4413define i32 @src_select_xor_max_negative_int(i32 %x, i32 %y) {
4414; CHECK-LABEL: @src_select_xor_max_negative_int(
4415; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4416; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[XOR]], -1
4417; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
4418; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4419; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]
4420; CHECK-NEXT:    ret i32 [[COND]]
4421;
4422  %xor = xor i32 %x, %y
4423  %xor0 = icmp eq i32 %xor, -1
4424  %and = and i32 %x, %y
4425  %or = or i32 %x, %y
4426  %cond = select i1 %xor0, i32 %and, i32 %or
4427  ret i32 %cond
4428}
4429
4430; Select icmp and/or/xor
4431; https://alive2.llvm.org/ce/z/BVgrJ-
4432; NO TRANSFORMED - not supported
4433define i32 @src_no_trans_select_and_eq0_and_or(i32 %x, i32 %y) {
4434; CHECK-LABEL: @src_no_trans_select_and_eq0_and_or(
4435; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4436; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 0
4437; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4438; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 0, i32 [[OR]]
4439; CHECK-NEXT:    ret i32 [[COND]]
4440;
4441  %and = and i32 %x, %y
4442  %and0 = icmp eq i32 %and, 0
4443  %or = or i32 %x, %y
4444  %cond = select i1 %and0, i32 %and, i32 %or
4445  ret i32 %cond
4446}
4447
4448define i32 @src_no_trans_select_and_eq0_and_xor(i32 %x, i32 %y) {
4449; CHECK-LABEL: @src_no_trans_select_and_eq0_and_xor(
4450; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4451; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 0
4452; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4453; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 0, i32 [[XOR]]
4454; CHECK-NEXT:    ret i32 [[COND]]
4455;
4456  %and = and i32 %x, %y
4457  %and0 = icmp eq i32 %and, 0
4458  %xor = xor i32 %x, %y
4459  %cond = select i1 %and0, i32 %and, i32 %xor
4460  ret i32 %cond
4461}
4462
4463define i32 @src_no_trans_select_and_eq0_or_and(i32 %x, i32 %y) {
4464; CHECK-LABEL: @src_no_trans_select_and_eq0_or_and(
4465; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4466; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 0
4467; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4468; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[AND]]
4469; CHECK-NEXT:    ret i32 [[COND]]
4470;
4471  %and = and i32 %x, %y
4472  %and0 = icmp eq i32 %and, 0
4473  %or = or i32 %x, %y
4474  %cond = select i1 %and0, i32 %or, i32 %and
4475  ret i32 %cond
4476}
4477
4478define i32 @src_no_trans_select_and_eq0_xor_and(i32 %x, i32 %y) {
4479; CHECK-LABEL: @src_no_trans_select_and_eq0_xor_and(
4480; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4481; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 0
4482; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4483; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 [[XOR]], i32 [[AND]]
4484; CHECK-NEXT:    ret i32 [[COND]]
4485;
4486  %and = and i32 %x, %y
4487  %and0 = icmp eq i32 %and, 0
4488  %xor = xor i32 %x, %y
4489  %cond = select i1 %and0, i32 %xor, i32 %and
4490  ret i32 %cond
4491}
4492
4493define i32 @src_no_trans_select_or_eq0_or_and(i32 %x, i32 %y) {
4494; CHECK-LABEL: @src_no_trans_select_or_eq0_or_and(
4495; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4496; CHECK-NEXT:    ret i32 [[AND]]
4497;
4498  %or = or i32 %x, %y
4499  %or0 = icmp eq i32 %or, 0
4500  %and = and i32 %x, %y
4501  %cond = select i1 %or0, i32 %or, i32 %and
4502  ret i32 %cond
4503}
4504
4505define i32 @src_no_trans_select_or_eq0_or_xor(i32 %x, i32 %y) {
4506; CHECK-LABEL: @src_no_trans_select_or_eq0_or_xor(
4507; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4508; CHECK-NEXT:    ret i32 [[XOR]]
4509;
4510  %or = or i32 %x, %y
4511  %or0 = icmp eq i32 %or, 0
4512  %xor = xor i32 %x, %y
4513  %cond = select i1 %or0, i32 %or, i32 %xor
4514  ret i32 %cond
4515}
4516
4517define i32 @src_no_trans_select_or_eq0_and_or(i32 %x, i32 %y) {
4518; CHECK-LABEL: @src_no_trans_select_or_eq0_and_or(
4519; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4520; CHECK-NEXT:    ret i32 [[OR]]
4521;
4522  %or = or i32 %x, %y
4523  %or0 = icmp eq i32 %or, 0
4524  %and = and i32 %x, %y
4525  %cond = select i1 %or0, i32 %and, i32 %or
4526  ret i32 %cond
4527}
4528
4529define i32 @src_no_trans_select_or_eq0_xor_or(i32 %x, i32 %y) {
4530; CHECK-LABEL: @src_no_trans_select_or_eq0_xor_or(
4531; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4532; CHECK-NEXT:    ret i32 [[OR]]
4533;
4534  %or = or i32 %x, %y
4535  %or0 = icmp eq i32 %or, 0
4536  %xor = xor i32 %x, %y
4537  %cond = select i1 %or0, i32 %xor, i32 %or
4538  ret i32 %cond
4539}
4540
4541define i32 @src_no_trans_select_and_ne0_xor_or(i32 %x, i32 %y) {
4542; CHECK-LABEL: @src_no_trans_select_and_ne0_xor_or(
4543; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4544; CHECK-NEXT:    ret i32 [[XOR]]
4545;
4546  %or = or i32 %x, %y
4547  %or0 = icmp ne i32 %or, 0
4548  %xor = xor i32 %x, %y
4549  %cond = select i1 %or0, i32 %xor, i32 %or
4550  ret i32 %cond
4551}
4552
4553define i32 @src_no_trans_select_xor_eq0_xor_and(i32 %x, i32 %y) {
4554; CHECK-LABEL: @src_no_trans_select_xor_eq0_xor_and(
4555; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
4556; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
4557; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[AND]]
4558; CHECK-NEXT:    ret i32 [[COND]]
4559;
4560  %xor = xor i32 %x, %y
4561  %xor0 = icmp eq i32 %xor, 0
4562  %and = and i32 %x, %y
4563  %cond = select i1 %xor0, i32 %xor, i32 %and
4564  ret i32 %cond
4565}
4566
4567define i32 @src_no_trans_select_xor_eq0_xor_or(i32 %x, i32 %y) {
4568; CHECK-LABEL: @src_no_trans_select_xor_eq0_xor_or(
4569; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
4570; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4571; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[OR]]
4572; CHECK-NEXT:    ret i32 [[COND]]
4573;
4574  %xor = xor i32 %x, %y
4575  %xor0 = icmp eq i32 %xor, 0
4576  %or = or i32 %x, %y
4577  %cond = select i1 %xor0, i32 %xor, i32 %or
4578  ret i32 %cond
4579}
4580
4581define i32 @src_no_trans_select_xor_eq0_and_xor(i32 %x, i32 %y) {
4582; CHECK-LABEL: @src_no_trans_select_xor_eq0_and_xor(
4583; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4584; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]
4585; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]
4586; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[XOR]]
4587; CHECK-NEXT:    ret i32 [[COND]]
4588;
4589  %xor = xor i32 %x, %y
4590  %xor0 = icmp eq i32 %xor, 0
4591  %and = and i32 %x, %y
4592  %cond = select i1 %xor0, i32 %and, i32 %xor
4593  ret i32 %cond
4594}
4595
4596; https://alive2.llvm.org/ce/z/SBe8ei
4597define i32 @src_no_trans_select_xor_eq0_or_xor(i32 %x, i32 %y) {
4598; CHECK-LABEL: @src_no_trans_select_xor_eq0_or_xor(
4599; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4600; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]
4601; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]
4602; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[OR]], i32 [[XOR]]
4603; CHECK-NEXT:    ret i32 [[COND]]
4604;
4605  %xor = xor i32 %x, %y
4606  %xor0 = icmp eq i32 %xor, 0
4607  %or = or i32 %x, %y
4608  %cond = select i1 %xor0, i32 %or, i32 %xor
4609  ret i32 %cond
4610}
4611
4612; (X == C) ? X : Y -> (X == C) ? C : Y
4613; Fixed #77553
4614define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
4615; CHECK-LABEL: @src_select_xxory_eq0_xorxy_y(
4616; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
4617; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[Y]]
4618; CHECK-NEXT:    ret i32 [[COND]]
4619;
4620  %xor = xor i32 %x, %y
4621  %xor0 = icmp eq i32 %xor, 0
4622  %cond = select i1 %xor0, i32 %xor, i32 %y
4623  ret i32 %cond
4624}
4625
4626define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
4627; CHECK-LABEL: @sequence_select_with_same_cond_false(
4628; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 45
4629; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1:%.*]], i32 789, i32 [[S2]]
4630; CHECK-NEXT:    ret i32 [[S3]]
4631;
4632  %s1 = select i1 %c1, i32 23, i32 45
4633  %s2 = select i1 %c2, i32 666, i32 %s1
4634  %s3 = select i1 %c1, i32 789, i32 %s2
4635  ret i32 %s3
4636}
4637
4638define i32 @sequence_select_with_same_cond_true(i1 %c1, i1 %c2){
4639; CHECK-LABEL: @sequence_select_with_same_cond_true(
4640; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], i32 45, i32 666
4641; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1:%.*]], i32 [[S2]], i32 789
4642; CHECK-NEXT:    ret i32 [[S3]]
4643;
4644  %s1 = select i1 %c1, i32 45, i32 23
4645  %s2 = select i1 %c2, i32 %s1, i32 666
4646  %s3 = select i1 %c1, i32 %s2, i32 789
4647  ret i32 %s3
4648}
4649
4650define double @sequence_select_with_same_cond_double(double %a, i1 %c1, i1 %c2, double %r1, double %r2){
4651; CHECK-LABEL: @sequence_select_with_same_cond_double(
4652; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1:%.*]], double 1.000000e+00, double 0.000000e+00
4653; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], double [[S1]], double 2.000000e+00
4654; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1]], double [[S2]], double 3.000000e+00
4655; CHECK-NEXT:    ret double [[S3]]
4656;
4657  %s1 = select i1 %c1, double 1.0, double 0.0
4658  %s2 = select i1 %c2, double %s1, double 2.0
4659  %s3 = select i1 %c1, double %s2, double 3.0
4660  ret double %s3
4661}
4662
4663declare void @use32(i32)
4664
4665define i32 @sequence_select_with_same_cond_extra_use(i1 %c1, i1 %c2){
4666; CHECK-LABEL: @sequence_select_with_same_cond_extra_use(
4667; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1:%.*]], i32 23, i32 45
4668; CHECK-NEXT:    call void @use32(i32 [[S1]])
4669; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 [[S1]]
4670; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]
4671; CHECK-NEXT:    ret i32 [[S3]]
4672;
4673  %s1 = select i1 %c1, i32 23, i32 45
4674  call void @use32(i32 %s1)
4675  %s2 = select i1 %c2, i32 666, i32 %s1
4676  %s3 = select i1 %c1, i32 789, i32 %s2
4677  ret i32 %s3
4678}
4679
4680define i8 @test_replace_freeze_multiuse(i1 %x, i8 %y) {
4681; CHECK-LABEL: @test_replace_freeze_multiuse(
4682; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[X:%.*]] to i8
4683; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y:%.*]]
4684; CHECK-NEXT:    [[SHL_FR:%.*]] = freeze i8 [[SHL]]
4685; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]]
4686; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SHL_FR]], [[SEL]]
4687; CHECK-NEXT:    ret i8 [[ADD]]
4688;
4689  %ext = zext i1 %x to i8
4690  %shl = shl nuw i8 %ext, %y
4691  %shl.fr = freeze i8 %shl
4692  %sel = select i1 %x, i8 0, i8 %shl.fr
4693  %add = add i8 %shl.fr, %sel
4694  ret i8 %add
4695}
4696
4697define i8 @test_replace_freeze_oneuse(i1 %x, i8 %y) {
4698; CHECK-LABEL: @test_replace_freeze_oneuse(
4699; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[X:%.*]] to i8
4700; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y:%.*]]
4701; CHECK-NEXT:    [[SHL_FR:%.*]] = freeze i8 [[SHL]]
4702; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]]
4703; CHECK-NEXT:    ret i8 [[SEL]]
4704;
4705  %ext = zext i1 %x to i8
4706  %shl = shl nuw i8 %ext, %y
4707  %shl.fr = freeze i8 %shl
4708  %sel = select i1 %x, i8 0, i8 %shl.fr
4709  ret i8 %sel
4710}
4711
4712define i8 @select_knownbits_simplify(i8 noundef %x)  {
4713; CHECK-LABEL: @select_knownbits_simplify(
4714; CHECK-NEXT:    [[X_LO:%.*]] = and i8 [[X:%.*]], 1
4715; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4716; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -2
4717; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0
4718; CHECK-NEXT:    ret i8 [[RES]]
4719;
4720  %x.lo = and i8 %x, 1
4721  %cmp = icmp eq i8 %x.lo, 0
4722  %and = and i8 %x, -2
4723  %res = select i1 %cmp, i8 %and, i8 0
4724  ret i8 %res
4725}
4726
4727define i8 @select_knownbits_simplify_nested(i8 noundef %x)  {
4728; CHECK-LABEL: @select_knownbits_simplify_nested(
4729; CHECK-NEXT:    [[X_LO:%.*]] = and i8 [[X:%.*]], 1
4730; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4731; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -2
4732; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[AND]], [[AND]]
4733; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 0
4734; CHECK-NEXT:    ret i8 [[RES]]
4735;
4736  %x.lo = and i8 %x, 1
4737  %cmp = icmp eq i8 %x.lo, 0
4738  %and = and i8 %x, -2
4739  %mul = mul i8 %and, %and
4740  %res = select i1 %cmp, i8 %mul, i8 0
4741  ret i8 %res
4742}
4743
4744define i8 @select_knownbits_simplify_missing_noundef(i8 %x)  {
4745; CHECK-LABEL: @select_knownbits_simplify_missing_noundef(
4746; CHECK-NEXT:    [[X_LO:%.*]] = and i8 [[X:%.*]], 1
4747; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4748; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -2
4749; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0
4750; CHECK-NEXT:    ret i8 [[RES]]
4751;
4752  %x.lo = and i8 %x, 1
4753  %cmp = icmp eq i8 %x.lo, 0
4754  %and = and i8 %x, -2
4755  %res = select i1 %cmp, i8 %and, i8 0
4756  ret i8 %res
4757}
4758
4759@g_ext = external global i8
4760
4761; Make sure we don't replace %ptr with @g_ext, which may cause the load to trigger UB.
4762define i32 @pr99436(ptr align 4 dereferenceable(4) %ptr) {
4763; CHECK-LABEL: @pr99436(
4764; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[PTR:%.*]], @g_ext
4765; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[PTR]], align 4
4766; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[VAL]], i32 0
4767; CHECK-NEXT:    ret i32 [[RET]]
4768;
4769  %cmp = icmp eq ptr %ptr, @g_ext
4770  %val = load i32, ptr %ptr, align 4
4771  %ret = select i1 %cmp, i32 %val, i32 0
4772  ret i32 %ret
4773}
4774
4775define i8 @sel_trunc_simplify(i1 %c, i8 %x, i16 %y) {
4776; CHECK-LABEL: @sel_trunc_simplify(
4777; CHECK-NEXT:    [[TMP1:%.*]] = trunc i16 [[Y:%.*]] to i8
4778; CHECK-NEXT:    [[TRUNC:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
4779; CHECK-NEXT:    ret i8 [[TRUNC]]
4780;
4781  %x.ext = zext i8 %x to i16
4782  %sel = select i1 %c, i16 %x.ext, i16 %y
4783  %trunc = trunc i16 %sel to i8
4784  ret i8 %trunc
4785}
4786
4787define i32 @sel_umin_simplify(i1 %c, i32 %x, i16 %y) {
4788; CHECK-LABEL: @sel_umin_simplify(
4789; CHECK-NEXT:    [[ARG2_EXT:%.*]] = zext i16 [[ARG2:%.*]] to i32
4790; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[ARG2_EXT]])
4791; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C:%.*]], i32 [[TMP1]], i32 0
4792; CHECK-NEXT:    ret i32 [[RES]]
4793;
4794  %sel = select i1 %c, i32 %x, i32 0
4795  %y.ext = zext i16 %y to i32
4796  %res = call i32 @llvm.umin.i32(i32 %sel, i32 %y.ext)
4797  ret i32 %res
4798}
4799
4800define i32 @sel_extractvalue_simplify(i1 %c, { i32, i32 } %agg1, i32 %x, i32 %y) {
4801; CHECK-LABEL: @sel_extractvalue_simplify(
4802; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i32 } [[AGG1:%.*]], 1
4803; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C:%.*]], i32 [[TMP1]], i32 [[Y:%.*]]
4804; CHECK-NEXT:    ret i32 [[RES]]
4805;
4806  %agg2.0 = insertvalue { i32, i32 } poison, i32 %x, 0
4807  %agg2.1 = insertvalue { i32, i32 } %agg2.0, i32 %y, 1
4808  %sel = select i1 %c, { i32, i32 } %agg1, { i32, i32 } %agg2.1
4809  %res = extractvalue { i32, i32 } %sel, 1
4810  ret i32 %res
4811}
4812
4813define i1 @replace_select_cond_true(i1 %cond, i32 %v1, i32 %v2, i32 %v3) {
4814; CHECK-LABEL: @replace_select_cond_true(
4815; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[SEL:%.*]], [[V2:%.*]]
4816; CHECK-NEXT:    [[AND:%.*]] = select i1 [[COND:%.*]], i1 [[CMP]], i1 false
4817; CHECK-NEXT:    ret i1 [[AND]]
4818;
4819  %sel = select i1 %cond, i32 %v1, i32 %v3
4820  %cmp = icmp eq i32 %sel, %v2
4821  %and = select i1 %cond, i1 %cmp, i1 false
4822  ret i1 %and
4823}
4824
4825define i1 @replace_select_cond_false(i1 %cond, i32 %v1, i32 %v2, i32 %v3) {
4826; CHECK-LABEL: @replace_select_cond_false(
4827; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[SEL:%.*]], [[V2:%.*]]
4828; CHECK-NEXT:    [[OR:%.*]] = select i1 [[COND:%.*]], i1 true, i1 [[CMP]]
4829; CHECK-NEXT:    ret i1 [[OR]]
4830;
4831  %sel = select i1 %cond, i32 %v1, i32 %v3
4832  %cmp = icmp eq i32 %sel, %v2
4833  %or = select i1 %cond, i1 true, i1 %cmp
4834  ret i1 %or
4835}
4836
4837define i32 @replace_and_cond(i1 %cond1, i1 %cond2) {
4838; CHECK-LABEL: @replace_and_cond(
4839; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[AND:%.*]], i32 3, i32 2
4840; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[COND1:%.*]], i32 [[SEL]], i32 1
4841; CHECK-NEXT:    ret i32 [[MUX]]
4842;
4843  %and = and i1 %cond1, %cond2
4844  %sel = select i1 %and, i32 3, i32 2
4845  %mux = select i1 %cond1, i32 %sel, i32 1
4846  ret i32 %mux
4847}
4848
4849define <2 x i32> @replace_and_cond_vec(<2 x i1> %cond1, <2 x i1> %cond2) {
4850; CHECK-LABEL: @replace_and_cond_vec(
4851; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND2:%.*]], <2 x i32> splat (i32 3), <2 x i32> splat (i32 2)
4852; CHECK-NEXT:    [[MUX:%.*]] = select <2 x i1> [[COND1:%.*]], <2 x i32> [[SEL]], <2 x i32> splat (i32 1)
4853; CHECK-NEXT:    ret <2 x i32> [[MUX]]
4854;
4855  %and = and <2 x i1> %cond1, %cond2
4856  %sel = select <2 x i1> %and, <2 x i32> splat(i32 3), <2 x i32> splat(i32 2)
4857  %mux = select <2 x i1> %cond1, <2 x i32> %sel, <2 x i32> splat(i32 1)
4858  ret <2 x i32> %mux
4859}
4860
4861; TODO: We can still replace the use of %and with %cond2
4862define i32 @replace_and_cond_multiuse1(i1 %cond1, i1 %cond2) {
4863; CHECK-LABEL: @replace_and_cond_multiuse1(
4864; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]]
4865; CHECK-NEXT:    call void @use(i1 [[AND]])
4866; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2
4867; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1
4868; CHECK-NEXT:    ret i32 [[MUX]]
4869;
4870  %and = and i1 %cond1, %cond2
4871  call void @use(i1 %and)
4872  %sel = select i1 %and, i32 3, i32 2
4873  %mux = select i1 %cond1, i32 %sel, i32 1
4874  ret i32 %mux
4875}
4876
4877define i32 @replace_and_cond_multiuse2(i1 %cond1, i1 %cond2) {
4878; CHECK-LABEL: @replace_and_cond_multiuse2(
4879; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]]
4880; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2
4881; CHECK-NEXT:    call void @use32(i32 [[SEL]])
4882; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1
4883; CHECK-NEXT:    ret i32 [[MUX]]
4884;
4885  %and = and i1 %cond1, %cond2
4886  %sel = select i1 %and, i32 3, i32 2
4887  call void @use32(i32 %sel)
4888  %mux = select i1 %cond1, i32 %sel, i32 1
4889  ret i32 %mux
4890}
4891
4892define i32 @src_simplify_2x_at_once_and(i32 %x, i32 %y) {
4893; CHECK-LABEL: @src_simplify_2x_at_once_and(
4894; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4895; CHECK-NEXT:    ret i32 [[XOR]]
4896;
4897  %and = and i32 %x, %y
4898  %and0 = icmp eq i32 %and, -1
4899  %sub = sub i32 %x, %y
4900  %xor = xor i32 %x, %y
4901  %cond = select i1 %and0, i32 %sub, i32 %xor
4902  ret i32 %cond
4903}
4904