xref: /llvm-project/llvm/test/Transforms/InstCombine/select-binop-cmp.ll (revision 9568f88b7f05015a438ed8beb4f4d07782c34dc2)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare void @use(<2 x i1>)
5declare void @use2(i1)
6declare void @use.i32(i32)
7
8define i32 @select_xor_icmp(i32 %x, i32 %y, i32 %z) {
9; CHECK-LABEL: @select_xor_icmp(
10; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
11; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
12; CHECK-NEXT:    ret i32 [[C]]
13;
14  %A = icmp eq i32 %x, 0
15  %B = xor i32 %x, %z
16  %C = select i1 %A, i32 %B, i32 %y
17  ret i32 %C
18}
19
20define i32 @select_xor_icmp2(i32 %x, i32 %y, i32 %z) {
21; CHECK-LABEL: @select_xor_icmp2(
22; CHECK-NEXT:    [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0
23; CHECK-NEXT:    [[C:%.*]] = select i1 [[A_NOT]], i32 [[Z:%.*]], i32 [[Y:%.*]]
24; CHECK-NEXT:    ret i32 [[C]]
25;
26  %A = icmp ne i32 %x, 0
27  %B = xor i32 %x, %z
28  %C = select i1 %A, i32 %y, i32 %B
29  ret i32 %C
30}
31
32define i32 @select_xor_icmp_meta(i32 %x, i32 %y, i32 %z) {
33; CHECK-LABEL: @select_xor_icmp_meta(
34; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
35; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]], !prof [[PROF0:![0-9]+]]
36; CHECK-NEXT:    ret i32 [[C]]
37;
38  %A = icmp eq i32 %x, 0
39  %B = xor i32 %x, %z
40  %C = select i1 %A, i32 %B, i32 %y, !prof !0
41  ret i32 %C
42}
43
44define i32 @select_mul_icmp(i32 %x, i32 %y, i32 %z) {
45; CHECK-LABEL: @select_mul_icmp(
46; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
47; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
48; CHECK-NEXT:    ret i32 [[C]]
49;
50  %A = icmp eq i32 %x, 1
51  %B = mul i32 %x, %z
52  %C = select i1 %A, i32 %B, i32 %y
53  ret i32 %C
54}
55
56define i32 @select_add_icmp(i32 %x, i32 %y, i32 %z) {
57; CHECK-LABEL: @select_add_icmp(
58; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
59; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
60; CHECK-NEXT:    ret i32 [[C]]
61;
62  %A = icmp eq i32 %x, 0
63  %B = add i32 %x, %z
64  %C = select i1 %A, i32 %B, i32 %y
65  ret i32 %C
66}
67
68define i32 @select_or_icmp(i32 %x, i32 %y, i32 %z) {
69; CHECK-LABEL: @select_or_icmp(
70; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
71; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
72; CHECK-NEXT:    ret i32 [[C]]
73;
74  %A = icmp eq i32 %x, 0
75  %B = or i32 %x, %z
76  %C = select i1 %A, i32 %B, i32 %y
77  ret i32 %C
78}
79
80define i32 @select_and_icmp(i32 %x, i32 %y, i32 %z) {
81; CHECK-LABEL: @select_and_icmp(
82; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], -1
83; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
84; CHECK-NEXT:    ret i32 [[C]]
85;
86  %A = icmp eq i32 %x, -1
87  %B = and i32 %x, %z
88  %C = select i1 %A, i32 %B, i32 %y
89  ret i32 %C
90}
91
92define <2 x i8> @select_xor_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
93; CHECK-LABEL: @select_xor_icmp_vec(
94; CHECK-NEXT:    [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer
95; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]]
96; CHECK-NEXT:    ret <2 x i8> [[C]]
97;
98  %A = icmp eq <2 x i8>  %x, <i8 0, i8 0>
99  %B = xor <2 x i8>  %x, %z
100  %C = select <2 x i1>  %A, <2 x i8>  %B, <2 x i8>  %y
101  ret <2 x i8>  %C
102}
103
104define <2 x i8> @select_xor_icmp_vec_use(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
105; CHECK-LABEL: @select_xor_icmp_vec_use(
106; CHECK-NEXT:    [[A:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer
107; CHECK-NEXT:    call void @use(<2 x i1> [[A]])
108; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]]
109; CHECK-NEXT:    ret <2 x i8> [[C]]
110;
111  %A = icmp ne <2 x i8>  %x, <i8 0, i8 0>
112  call void @use(<2 x i1> %A)
113  %B = xor <2 x i8>  %x, %z
114  %C = select <2 x i1>  %A, <2 x i8>  %y, <2 x i8>  %B
115  ret <2 x i8>  %C
116}
117
118define i32 @select_xor_inv_icmp(i32 %x, i32 %y, i32 %z) {
119; CHECK-LABEL: @select_xor_inv_icmp(
120; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
121; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
122; CHECK-NEXT:    ret i32 [[C]]
123;
124  %A = icmp eq i32 %x, 0
125  %B = xor i32 %z, %x
126  %C = select i1 %A, i32 %B, i32 %y
127  ret i32 %C
128}
129
130define i32 @select_xor_inv_icmp2(i32 %x, i32 %y, i32 %z) {
131; CHECK-LABEL: @select_xor_inv_icmp2(
132; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
133; CHECK-NEXT:    call void @use2(i1 [[A]])
134; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
135; CHECK-NEXT:    ret i32 [[C]]
136;
137  %A = icmp ne i32 %x, 0
138  call void @use2(i1 %A) ; thwart predicate canonicalization
139  %B = xor i32 %x, %z
140  %C = select i1 %A, i32 %y, i32 %B
141  ret i32 %C
142}
143
144define float @select_fadd_fcmp(float %x, float %y, float %z) {
145; CHECK-LABEL: @select_fadd_fcmp(
146; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
147; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
148; CHECK-NEXT:    ret float [[C]]
149;
150  %A = fcmp oeq float %x, -0.0
151  %B = fadd nsz float %x, %z
152  %C = select i1 %A, float %B, float %y
153  ret float %C
154}
155
156; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
157
158define float @select_fadd_fcmp_poszero(float %x, float %y, float %z) {
159; CHECK-LABEL: @select_fadd_fcmp_poszero(
160; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
161; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
162; CHECK-NEXT:    ret float [[C]]
163;
164  %A = fcmp oeq float %x, 0.0
165  %B = fadd nsz float %z, %x
166  %C = select i1 %A, float %B, float %y
167  ret float %C
168}
169
170define float @select_fadd_fcmp_2(float %x, float %y, float %v) {
171; CHECK-LABEL: @select_fadd_fcmp_2(
172; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
173; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
174; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
175; CHECK-NEXT:    ret float [[C]]
176;
177  %A = fcmp une float %x, -0.0
178  %z = fadd float %v, 0.0 ; cannot produce -0.0
179  %B = fadd float %z, %x
180  %C = select i1 %A, float %y, float %B
181  ret float %C
182}
183
184; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
185
186define float @select_fadd_fcmp_2_poszero(float %x, float %y, float %v) {
187; CHECK-LABEL: @select_fadd_fcmp_2_poszero(
188; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
189; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
190; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
191; CHECK-NEXT:    ret float [[C]]
192;
193  %A = fcmp une float %x, 0.0
194  %z = fadd float %v, 0.0 ; cannot produce -0.0
195  %B = fadd float %z, %x
196  %C = select i1 %A, float %y, float %B
197  ret float %C
198}
199
200define float @select_fadd_fcmp_3(float %x, float %y) {
201; CHECK-LABEL: @select_fadd_fcmp_3(
202; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
203; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00
204; CHECK-NEXT:    ret float [[C]]
205;
206  %A = fcmp une float %x, -0.0
207  %B = fadd float 6.0, %x
208  %C = select i1 %A, float %y, float %B
209  ret float %C
210}
211
212; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
213
214define float @select_fadd_fcmp_3_poszero(float %x, float %y) {
215; CHECK-LABEL: @select_fadd_fcmp_3_poszero(
216; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
217; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00
218; CHECK-NEXT:    ret float [[C]]
219;
220  %A = fcmp une float %x, 0.0
221  %B = fadd float 6.0, %x
222  %C = select i1 %A, float %y, float %B
223  ret float %C
224}
225
226define float @select_fadd_fcmp_4(float %x, float %y, float %z) {
227; CHECK-LABEL: @select_fadd_fcmp_4(
228; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
229; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]
230; CHECK-NEXT:    ret float [[C]]
231;
232  %A = fcmp une float %x, -0.0
233  %B = fadd nsz float %z, %x
234  %C = select i1 %A, float %y, float %B
235  ret float %C
236}
237
238; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
239
240define float @select_fadd_fcmp_4_poszero(float %x, float %y, float %z) {
241; CHECK-LABEL: @select_fadd_fcmp_4_poszero(
242; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
243; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]
244; CHECK-NEXT:    ret float [[C]]
245;
246  %A = fcmp une float %x, 0.0
247  %B = fadd nsz float %z, %x
248  %C = select i1 %A, float %y, float %B
249  ret float %C
250}
251
252define float @select_fadd_fcmp_5(float %x, float %y, float %v) {
253; CHECK-LABEL: @select_fadd_fcmp_5(
254; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
255; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
256; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]
257; CHECK-NEXT:    ret float [[C]]
258;
259  %A = fcmp oeq float %x, -0.0
260  %z = fadd float %v, 0.0 ; cannot produce -0.0
261  %B = fadd float %z, %x
262  %C = select i1 %A, float %B, float %y
263  ret float %C
264}
265
266; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
267
268define float @select_fadd_fcmp_5_poszero(float %x, float %y, float %v) {
269; CHECK-LABEL: @select_fadd_fcmp_5_poszero(
270; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
271; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
272; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]
273; CHECK-NEXT:    ret float [[C]]
274;
275  %A = fcmp oeq float %x, 0.0
276  %z = fadd float %v, 0.0 ; cannot produce -0.0
277  %B = fadd float %z, %x
278  %C = select i1 %A, float %B, float %y
279  ret float %C
280}
281
282define float @select_fadd_fcmp_6(float %x, float %y, float %z) {
283; CHECK-LABEL: @select_fadd_fcmp_6(
284; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
285; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]
286; CHECK-NEXT:    ret float [[C]]
287;
288  %A = fcmp oeq float %x, -0.0
289  %B = fadd float %x, 6.0
290  %C = select i1 %A, float %B, float %y
291  ret float %C
292}
293
294; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
295
296define float @select_fadd_fcmp_6_poszero(float %x, float %y, float %z) {
297; CHECK-LABEL: @select_fadd_fcmp_6_poszero(
298; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
299; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]
300; CHECK-NEXT:    ret float [[C]]
301;
302  %A = fcmp oeq float %x, 0.0
303  %B = fadd float %x, 6.0
304  %C = select i1 %A, float %B, float %y
305  ret float %C
306}
307
308define float @select_fmul_fcmp(float %x, float %y, float %z) {
309; CHECK-LABEL: @select_fmul_fcmp(
310; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
311; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
312; CHECK-NEXT:    ret float [[C]]
313;
314  %A = fcmp oeq float %x, 1.0
315  %B = fmul nsz float %x, %z
316  %C = select i1 %A, float %B, float %y
317  ret float %C
318}
319
320define float @select_fsub_fcmp(float %x, float %y, float %z) {
321; CHECK-LABEL: @select_fsub_fcmp(
322; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
323; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
324; CHECK-NEXT:    ret float [[C]]
325;
326  %A = fcmp oeq float %x, 0.0
327  %B = fsub nsz float %z, %x
328  %C = select i1 %A, float %B, float %y
329  ret float %C
330}
331
332; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
333
334define float @select_fsub_fcmp_negzero(float %x, float %y, float %z) {
335; CHECK-LABEL: @select_fsub_fcmp_negzero(
336; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
337; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
338; CHECK-NEXT:    ret float [[C]]
339;
340  %A = fcmp oeq float %x, -0.0
341  %B = fsub nsz float %z, %x
342  %C = select i1 %A, float %B, float %y
343  ret float %C
344}
345
346define float @select_fdiv_fcmp(float %x, float %y, float %z) {
347; CHECK-LABEL: @select_fdiv_fcmp(
348; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
349; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
350; CHECK-NEXT:    ret float [[C]]
351;
352  %A = fcmp oeq float %x, 1.0
353  %B = fdiv nsz float %z, %x
354  %C = select i1 %A, float %B, float %y
355  ret float %C
356}
357
358define i32 @select_sub_icmp(i32 %x, i32 %y, i32 %z) {
359; CHECK-LABEL: @select_sub_icmp(
360; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
361; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
362; CHECK-NEXT:    ret i32 [[C]]
363;
364  %A = icmp eq i32 %x, 0
365  %B = sub i32 %z, %x
366  %C = select i1 %A, i32 %B, i32 %y
367  ret i32 %C
368}
369
370define i32 @select_sub_icmp_2(i32 %x, i32 %y, i32 %z) {
371; CHECK-LABEL: @select_sub_icmp_2(
372; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
373; CHECK-NEXT:    call void @use2(i1 [[A]])
374; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
375; CHECK-NEXT:    ret i32 [[C]]
376;
377  %A = icmp eq i32 %x, 0
378  call void @use2(i1 %A)
379  %B = sub i32 %z, %x
380  %C = select i1 %A, i32 %B, i32 %y
381  ret i32 %C
382}
383
384define i32 @select_sub_icmp_3(i32 %x, i32 %y, i32 %z) {
385; CHECK-LABEL: @select_sub_icmp_3(
386; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
387; CHECK-NEXT:    call void @use2(i1 [[A]])
388; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
389; CHECK-NEXT:    ret i32 [[C]]
390;
391  %A = icmp ne i32 %x, 0
392  call void @use2(i1 %A)
393  %B = sub i32 %z, %x
394  %C = select i1 %A, i32 %y, i32 %B
395  ret i32 %C
396}
397
398define <2 x i8> @select_sub_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
399; CHECK-LABEL: @select_sub_icmp_vec(
400; CHECK-NEXT:    [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer
401; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]]
402; CHECK-NEXT:    ret <2 x i8> [[C]]
403;
404  %A = icmp eq <2 x i8>  %x, <i8 0, i8 0>
405  %B = sub <2 x i8>  %z, %x
406  %C = select <2 x i1>  %A, <2 x i8>  %B, <2 x i8>  %y
407  ret <2 x i8>  %C
408}
409
410define i32 @select_shl_icmp(i32 %x, i32 %y, i32 %z) {
411; CHECK-LABEL: @select_shl_icmp(
412; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
413; CHECK-NEXT:    call void @use2(i1 [[A]])
414; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
415; CHECK-NEXT:    ret i32 [[C]]
416;
417  %A = icmp ne i32 %x, 0
418  call void @use2(i1 %A) ; thwart predicate canonicalization
419  %B = shl i32 %z, %x
420  %C = select i1 %A, i32 %y, i32 %B
421  ret i32 %C
422}
423
424define i32 @select_lshr_icmp(i32 %x, i32 %y, i32 %z) {
425; CHECK-LABEL: @select_lshr_icmp(
426; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
427; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
428; CHECK-NEXT:    ret i32 [[C]]
429;
430  %A = icmp eq i32 %x, 0
431  %B = lshr i32 %z, %x
432  %C = select i1 %A, i32 %B, i32 %y
433  ret i32 %C
434}
435
436define i32 @select_ashr_icmp(i32 %x, i32 %y, i32 %z) {
437; CHECK-LABEL: @select_ashr_icmp(
438; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
439; CHECK-NEXT:    call void @use2(i1 [[A]])
440; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
441; CHECK-NEXT:    ret i32 [[C]]
442;
443  %A = icmp ne i32 %x, 0
444  call void @use2(i1 %A) ; thwart predicate canonicalization
445  %B = ashr i32 %z, %x
446  %C = select i1 %A, i32 %y, i32 %B
447  ret i32 %C
448}
449
450define i32 @select_udiv_icmp(i32 %x, i32 %y, i32 %z) {
451; CHECK-LABEL: @select_udiv_icmp(
452; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
453; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
454; CHECK-NEXT:    ret i32 [[C]]
455;
456  %A = icmp eq i32 %x, 1
457  %B = udiv i32 %z, %x
458  %C = select i1 %A, i32 %B, i32 %y
459  ret i32 %C
460}
461
462define i32 @select_sdiv_icmp(i32 %x, i32 %y, i32 %z) {
463; CHECK-LABEL: @select_sdiv_icmp(
464; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 1
465; CHECK-NEXT:    call void @use2(i1 [[A]])
466; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
467; CHECK-NEXT:    ret i32 [[C]]
468;
469  %A = icmp ne i32 %x, 1
470  call void @use2(i1 %A) ; thwart predicate canonicalization
471  %B = sdiv i32 %z, %x
472  %C = select i1 %A, i32 %y, i32 %B
473  ret i32 %C
474}
475
476; Negative tests
477define i32 @select_xor_icmp_bad_1(i32 %x, i32 %y, i32 %z, i32 %k) {
478; CHECK-LABEL: @select_xor_icmp_bad_1(
479; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]]
480; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]
481; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
482; CHECK-NEXT:    ret i32 [[C]]
483;
484  %A = icmp eq i32 %x, %k
485  %B = xor i32 %x, %z
486  %C = select i1 %A, i32 %B, i32 %y
487  ret i32 %C
488}
489
490define i32 @select_xor_icmp_bad_2(i32 %x, i32 %y, i32 %z, i32 %k) {
491; CHECK-LABEL: @select_xor_icmp_bad_2(
492; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
493; CHECK-NEXT:    [[B:%.*]] = xor i32 [[K:%.*]], [[Z:%.*]]
494; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
495; CHECK-NEXT:    ret i32 [[C]]
496;
497  %A = icmp eq i32 %x, 0
498  %B = xor i32 %k, %z
499  %C = select i1 %A, i32 %B, i32 %y
500  ret i32 %C
501}
502
503define i32 @select_xor_icmp_bad_3(i32 %x, i32 %y, i32 %z) {
504; CHECK-LABEL: @select_xor_icmp_bad_3(
505; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
506; CHECK-NEXT:    [[B:%.*]] = xor i32 [[Z:%.*]], 3
507; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
508; CHECK-NEXT:    ret i32 [[C]]
509;
510  %A = icmp eq i32 %x, 3
511  %B = xor i32 %x, %z
512  %C = select i1 %A, i32 %B, i32 %y
513  ret i32 %C
514}
515
516define i32 @select_xor_fcmp_bad_4(i32 %x, i32 %y, i32 %z, float %k) {
517; CHECK-LABEL: @select_xor_fcmp_bad_4(
518; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[K:%.*]], 0.000000e+00
519; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X:%.*]], [[Z:%.*]]
520; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
521; CHECK-NEXT:    ret i32 [[C]]
522;
523  %A = fcmp oeq float %k, 0.0
524  %B = xor i32 %x, %z
525  %C = select i1 %A, i32 %B, i32 %y
526  ret i32 %C
527}
528
529define i32 @select_xor_icmp_bad_5(i32 %x, i32 %y, i32 %z) {
530; CHECK-LABEL: @select_xor_icmp_bad_5(
531; CHECK-NEXT:    [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0
532; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]
533; CHECK-NEXT:    [[C:%.*]] = select i1 [[A_NOT]], i32 [[Y:%.*]], i32 [[B]]
534; CHECK-NEXT:    ret i32 [[C]]
535;
536  %A = icmp ne i32 %x, 0
537  %B = xor i32 %x, %z
538  %C = select i1 %A, i32 %B, i32 %y
539  ret i32 %C
540}
541
542define i32 @select_xor_icmp_bad_6(i32 %x, i32 %y, i32 %z) {
543; CHECK-LABEL: @select_xor_icmp_bad_6(
544; CHECK-NEXT:    [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 1
545; CHECK-NEXT:    [[B:%.*]] = xor i32 [[Z:%.*]], 1
546; CHECK-NEXT:    [[C:%.*]] = select i1 [[A_NOT]], i32 [[B]], i32 [[Y:%.*]]
547; CHECK-NEXT:    ret i32 [[C]]
548;
549  %A = icmp ne i32 %x, 1
550  %B = xor i32 %x, %z
551  %C = select i1 %A, i32 %y, i32 %B
552  ret i32 %C
553}
554
555; Value equivalence substitution is valid.
556
557define <2 x i8> @select_xor_icmp_vec_equivalence(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
558; CHECK-LABEL: @select_xor_icmp_vec_equivalence(
559; CHECK-NEXT:    [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 5, i8 3>
560; CHECK-NEXT:    [[B:%.*]] = xor <2 x i8> [[Z:%.*]], <i8 5, i8 3>
561; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]]
562; CHECK-NEXT:    ret <2 x i8> [[C]]
563;
564  %A = icmp eq <2 x i8>  %x, <i8 5, i8 3>
565  %B = xor <2 x i8>  %x, %z
566  %C = select <2 x i1>  %A, <2 x i8>  %B, <2 x i8>  %y
567  ret <2 x i8>  %C
568}
569
570; Value equivalence substitution is invalid due to lane-crossing shufflevector.
571
572define <2 x i32> @vec_select_no_equivalence(<2 x i32> %x) {
573; CHECK-LABEL: @vec_select_no_equivalence(
574; CHECK-NEXT:    [[X10:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>
575; CHECK-NEXT:    [[COND:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer
576; CHECK-NEXT:    [[S:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[X10]], <2 x i32> [[X]]
577; CHECK-NEXT:    ret <2 x i32> [[S]]
578;
579  %x10 = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> <i32 1, i32 0>
580  %cond = icmp eq <2 x i32> %x, zeroinitializer
581  %s = select <2 x i1> %cond, <2 x i32> %x10, <2 x i32> %x
582  ret <2 x i32> %s
583}
584
585; Folding this would only be legal if we sanitized undef to 0.
586define <2 x i8> @select_xor_icmp_vec_undef(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
587; CHECK-LABEL: @select_xor_icmp_vec_undef(
588; CHECK-NEXT:    [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 0, i8 undef>
589; CHECK-NEXT:    [[B:%.*]] = xor <2 x i8> [[X]], [[Z:%.*]]
590; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]]
591; CHECK-NEXT:    ret <2 x i8> [[C]]
592;
593  %A = icmp eq <2 x i8>  %x, <i8 0, i8 undef>
594  %B = xor <2 x i8>  %x, %z
595  %C = select <2 x i1>  %A, <2 x i8>  %B, <2 x i8>  %y
596  ret <2 x i8>  %C
597}
598
599define i32 @select_mul_icmp_bad(i32 %x, i32 %y, i32 %z, i32 %k) {
600; CHECK-LABEL: @select_mul_icmp_bad(
601; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
602; CHECK-NEXT:    [[B:%.*]] = mul i32 [[Z:%.*]], 3
603; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
604; CHECK-NEXT:    ret i32 [[C]]
605;
606  %A = icmp eq i32 %x, 3
607  %B = mul i32 %x, %z
608  %C = select i1 %A, i32 %B, i32 %y
609  ret i32 %C
610}
611
612define i32 @select_add_icmp_bad(i32 %x, i32 %y, i32 %z) {
613; CHECK-LABEL: @select_add_icmp_bad(
614; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
615; CHECK-NEXT:    [[B:%.*]] = add i32 [[Z:%.*]], 1
616; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
617; CHECK-NEXT:    ret i32 [[C]]
618;
619  %A = icmp eq i32 %x, 1
620  %B = add i32 %x, %z
621  %C = select i1 %A, i32 %B, i32 %y
622  ret i32 %C
623}
624
625define i32 @select_and_icmp_zero(i32 %x, i32 %y, i32 %z) {
626; CHECK-LABEL: @select_and_icmp_zero(
627; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
628; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 0, i32 [[Y:%.*]]
629; CHECK-NEXT:    ret i32 [[C]]
630;
631  %A = icmp eq i32 %x, 0
632  %B = and i32 %x, %z
633  %C = select i1 %A, i32 %B, i32 %y
634  ret i32 %C
635}
636
637define i32 @select_or_icmp_bad(i32 %x, i32 %y, i32 %z) {
638; CHECK-LABEL: @select_or_icmp_bad(
639; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
640; CHECK-NEXT:    [[B:%.*]] = or i32 [[Z:%.*]], 3
641; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
642; CHECK-NEXT:    ret i32 [[C]]
643;
644  %A = icmp eq i32 %x, 3
645  %B = or i32 %x, %z
646  %C = select i1 %A, i32 %B, i32 %y
647  ret i32 %C
648}
649
650define i32 @select_lshr_icmp_const(i32 %x) {
651; CHECK-LABEL: @select_lshr_icmp_const(
652; CHECK-NEXT:    [[B:%.*]] = lshr i32 [[X:%.*]], 5
653; CHECK-NEXT:    ret i32 [[B]]
654;
655  %A = icmp ugt i32 %x, 31
656  %B = lshr i32 %x, 5
657  %C = select i1 %A, i32 %B, i32 0
658  ret i32 %C
659}
660
661define i32 @select_lshr_icmp_const_reordered(i32 %x) {
662; CHECK-LABEL: @select_lshr_icmp_const_reordered(
663; CHECK-NEXT:    [[B:%.*]] = lshr i32 [[X:%.*]], 5
664; CHECK-NEXT:    ret i32 [[B]]
665;
666  %A = icmp ult i32 %x, 32
667  %B = lshr i32 %x, 5
668  %C = select i1 %A, i32 0, i32 %B
669  ret i32 %C
670}
671
672define i32 @select_exact_lshr_icmp_const(i32 %x) {
673; CHECK-LABEL: @select_exact_lshr_icmp_const(
674; CHECK-NEXT:    [[B:%.*]] = lshr i32 [[X:%.*]], 5
675; CHECK-NEXT:    ret i32 [[B]]
676;
677  %A = icmp ugt i32 %x, 31
678  %B = lshr exact i32 %x, 5
679  %C = select i1 %A, i32 %B, i32 0
680  ret i32 %C
681}
682
683define i32 @select_lshr_icmp_const_large_exact_range(i32 %x) {
684; CHECK-LABEL: @select_lshr_icmp_const_large_exact_range(
685; CHECK-NEXT:    [[A:%.*]] = icmp ugt i32 [[X:%.*]], 63
686; CHECK-NEXT:    [[B:%.*]] = lshr i32 [[X]], 5
687; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 0
688; CHECK-NEXT:    ret i32 [[C]]
689;
690  %A = icmp ugt i32 %x, 63
691  %B = lshr i32 %x, 5
692  %C = select i1 %A, i32 %B, i32 0
693  ret i32 %C
694}
695
696define i32 @select_lshr_icmp_const_different_values(i32 %x, i32 %y) {
697; CHECK-LABEL: @select_lshr_icmp_const_different_values(
698; CHECK-NEXT:    [[A:%.*]] = icmp ugt i32 [[X:%.*]], 31
699; CHECK-NEXT:    [[B:%.*]] = lshr i32 [[Y:%.*]], 5
700; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 0
701; CHECK-NEXT:    ret i32 [[C]]
702;
703  %A = icmp ugt i32 %x, 31
704  %B = lshr i32 %y, 5
705  %C = select i1 %A, i32 %B, i32 0
706  ret i32 %C
707}
708
709define float @select_fadd_fcmp_equiv(float %x, float %y, float %z) {
710; CHECK-LABEL: @select_fadd_fcmp_equiv(
711; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], -1.000000e+00
712; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00
713; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
714; CHECK-NEXT:    ret float [[C]]
715;
716  %A = fcmp oeq float %x, -1.0
717  %B = fadd nsz float %x, %z
718  %C = select i1 %A, float %B, float %y
719  ret float %C
720}
721
722define float @select_fadd_fcmp_equiv2(float %x, float %y, float %z) {
723; CHECK-LABEL: @select_fadd_fcmp_equiv2(
724; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], -1.000000e+00
725; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00
726; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
727; CHECK-NEXT:    ret float [[C]]
728;
729  %A = fcmp une float %x, -1.0
730  %B = fadd nsz float %x, %z
731  %C = select i1 %A, float %y, float %B
732  ret float %C
733}
734
735; Invalid comparison type
736define float @select_fadd_fcmp_bad_2(float %x, float %y, float %z) {
737; CHECK-LABEL: @select_fadd_fcmp_bad_2(
738; CHECK-NEXT:    [[A:%.*]] = fcmp ueq float [[X:%.*]], -1.000000e+00
739; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
740; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
741; CHECK-NEXT:    ret float [[C]]
742;
743  %A = fcmp ueq float %x, -1.0
744  %B = fadd float %x, %z
745  %C = select i1 %A, float %B, float %y
746  ret float %C
747}
748
749; Invalid comparison type
750define float @select_fadd_fcmp_bad_3(float %x, float %y, float %z, float %k) {
751; CHECK-LABEL: @select_fadd_fcmp_bad_3(
752; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], [[K:%.*]]
753; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
754; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
755; CHECK-NEXT:    ret float [[C]]
756;
757  %A = fcmp one float %x, %k
758  %B = fadd float %x, %z
759  %C = select i1 %A, float %y, float %B
760  ret float %C
761}
762
763; Invalid order of operands of select
764define float @select_fadd_fcmp_bad_4(float %x, float %y, float %z) {
765; CHECK-LABEL: @select_fadd_fcmp_bad_4(
766; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
767; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
768; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
769; CHECK-NEXT:    ret float [[C]]
770;
771  %A = fcmp une float %x, -0.0
772  %B = fadd float %x, %z
773  %C = select i1 %A, float %B, float %y
774  ret float %C
775}
776
777; Invalid comparison type
778define float @select_fadd_fcmp_bad_5(float %x, float %y, float %z) {
779; CHECK-LABEL: @select_fadd_fcmp_bad_5(
780; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
781; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
782; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
783; CHECK-NEXT:    ret float [[C]]
784;
785  %A = fcmp one float %x, -0.0
786  %B = fadd nsz float %z, %x
787  %C = select i1 %A, float %y, float %B
788  ret float %C
789}
790
791; Invalid order of operands of select
792define float @select_fadd_fcmp_bad_6(float %x, float %y, float %z) {
793; CHECK-LABEL: @select_fadd_fcmp_bad_6(
794; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
795; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
796; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
797; CHECK-NEXT:    ret float [[C]]
798;
799  %A = fcmp oeq float %x, -0.0
800  %B = fadd nsz float %z, %x
801  %C = select i1 %A, float %y, float %B
802  ret float %C
803}
804
805; Do not transform if we have signed zeros and if Z is possibly negative zero
806define float @select_fadd_fcmp_bad_7(float %x, float %y, float %z) {
807; CHECK-LABEL: @select_fadd_fcmp_bad_7(
808; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
809; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
810; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
811; CHECK-NEXT:    ret float [[C]]
812;
813  %A = fcmp oeq float %x, -0.0
814  %B = fadd float %x, %z
815  %C = select i1 %A, float %B, float %y
816  ret float %C
817}
818
819; Invalid comparison type
820define float @select_fadd_fcmp_bad_8(float %x, float %y, float %v) {
821; CHECK-LABEL: @select_fadd_fcmp_bad_8(
822; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
823; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00
824; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z]], [[X]]
825; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
826; CHECK-NEXT:    ret float [[C]]
827;
828  %A = fcmp one float %x, -0.0
829  %z = fadd float %v, -1.0
830  %B = fadd float %z, %x
831  %C = select i1 %A, float %y, float %B
832  ret float %C
833}
834
835; Invalid comparison type
836define float @select_fadd_fcmp_bad_9(float %x, float %y, float %z) {
837; CHECK-LABEL: @select_fadd_fcmp_bad_9(
838; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
839; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
840; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
841; CHECK-NEXT:    ret float [[C]]
842;
843  %A = fcmp one float %x, -0.0
844  %B = fadd nsz float %z, %x
845  %C = select i1 %A, float %y, float %B
846  ret float %C
847}
848
849; Invalid comparison type
850define float @select_fadd_fcmp_bad_10(float %x, float %y, float %v) {
851; CHECK-LABEL: @select_fadd_fcmp_bad_10(
852; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
853; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
854; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z]], [[X]]
855; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
856; CHECK-NEXT:    ret float [[C]]
857;
858  %A = fcmp one float %x, -0.0
859  %z = fadd float %v, 0.0 ; cannot produce -0.0
860  %B = fadd float %z, %x
861  %C = select i1 %A, float %y, float %B
862  ret float %C
863}
864
865; Do not transform if Z is possibly negative zero
866define float @select_fadd_fcmp_bad_11(float %x, float %y, float %v) {
867; CHECK-LABEL: @select_fadd_fcmp_bad_11(
868; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
869; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00
870; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
871; CHECK-NEXT:    ret float [[C]]
872;
873  %A = fcmp une float %x, -0.0
874  %z = fadd float %v, -1.0
875  %B = fadd nsz float %z, %x
876  %C = select i1 %A, float %y, float %B
877  ret float %C
878}
879
880; Do not transform if we have signed zeros and if Z is possibly negative zero
881define float @select_fadd_fcmp_bad_12(float %x, float %y, float %z) {
882; CHECK-LABEL: @select_fadd_fcmp_bad_12(
883; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
884; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z:%.*]], [[X]]
885; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
886; CHECK-NEXT:    ret float [[C]]
887;
888  %A = fcmp une float %x, -0.0
889  %B = fadd float %z, %x
890  %C = select i1 %A, float %y, float %B
891  ret float %C
892}
893
894; Invalid order of operands of select
895define float @select_fadd_fcmp_bad_13(float %x, float %y, float %z) {
896; CHECK-LABEL: @select_fadd_fcmp_bad_13(
897; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
898; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
899; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
900; CHECK-NEXT:    ret float [[C]]
901;
902  %A = fcmp oeq float %x, -0.0
903  %B = fadd nsz float %x, %z
904  %C = select i1 %A, float %y, float %B
905  ret float %C
906}
907
908define float @select_fmul_fcmp_equiv(float %x, float %y, float %z) {
909; CHECK-LABEL: @select_fmul_fcmp_equiv(
910; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
911; CHECK-NEXT:    [[B:%.*]] = fmul nsz float [[Z:%.*]], 3.000000e+00
912; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
913; CHECK-NEXT:    ret float [[C]]
914;
915  %A = fcmp oeq float %x, 3.0
916  %B = fmul nsz float %x, %z
917  %C = select i1 %A, float %B, float %y
918  ret float %C
919}
920
921define float @select_fmul_fcmp_equiv2(float %x, float %y, float %z) {
922; CHECK-LABEL: @select_fmul_fcmp_equiv2(
923; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
924; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B:%.*]], float [[Y:%.*]]
925; CHECK-NEXT:    ret float [[C]]
926;
927  %A = fcmp oeq float %x, 1.0
928  %B = fmul float %x, %z
929  %C = select i1 %A, float %B, float %y
930  ret float %C
931}
932
933define float @select_fmul_icmp_bad(float %x, float %y, float %z, i32 %k) {
934; CHECK-LABEL: @select_fmul_icmp_bad(
935; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[K:%.*]], 0
936; CHECK-NEXT:    [[B:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]
937; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
938; CHECK-NEXT:    ret float [[C]]
939;
940  %A = icmp eq i32 %k, 0
941  %B = fmul float %x, %z
942  %C = select i1 %A, float %B, float %y
943  ret float %C
944}
945
946define float @select_fmul_icmp_bad_2(float %x, float %y, float %z, i32 %k) {
947; CHECK-LABEL: @select_fmul_icmp_bad_2(
948; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[K:%.*]], 0
949; CHECK-NEXT:    [[B:%.*]] = fmul nsz float [[X:%.*]], [[Z:%.*]]
950; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
951; CHECK-NEXT:    ret float [[C]]
952;
953  %A = icmp eq i32 %k, 0
954  %B = fmul nsz float %x, %z
955  %C = select i1 %A, float %B, float %y
956  ret float %C
957}
958
959define float @select_fdiv_fcmp_equiv(float %x, float %y, float %z) {
960; CHECK-LABEL: @select_fdiv_fcmp_equiv(
961; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
962; CHECK-NEXT:    [[B:%.*]] = fdiv float 1.000000e+00, [[Z:%.*]]
963; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
964; CHECK-NEXT:    ret float [[C]]
965;
966  %A = fcmp oeq float %x, 1.0
967  %B = fdiv float %x, %z
968  %C = select i1 %A, float %B, float %y
969  ret float %C
970}
971
972define float @select_fdiv_fcmp_equiv2(float %x, float %y, float %z) {
973; CHECK-LABEL: @select_fdiv_fcmp_equiv2(
974; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
975; CHECK-NEXT:    [[B:%.*]] = fdiv nsz float 3.000000e+00, [[Z:%.*]]
976; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
977; CHECK-NEXT:    ret float [[C]]
978;
979  %A = fcmp oeq float %x, 3.0
980  %B = fdiv nsz float %x, %z
981  %C = select i1 %A, float %B, float %y
982  ret float %C
983}
984
985; The transform is not valid when x = -0.0 and z = -0.0
986; (optimized code would return -0.0, but this returns +0.0).
987
988define float @select_fsub_fcmp_bad(float %x, float %y, float %z) {
989; CHECK-LABEL: @select_fsub_fcmp_bad(
990; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
991; CHECK-NEXT:    [[B:%.*]] = fsub float [[Z:%.*]], [[X]]
992; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
993; CHECK-NEXT:    ret float [[C]]
994;
995  %A = fcmp oeq float %x, 0.0
996  %B = fsub float %z, %x
997  %C = select i1 %A, float %B, float %y
998  ret float %C
999}
1000
1001define float @select_fsub_fcmp_equiv(float %x, float %y, float %z) {
1002; CHECK-LABEL: @select_fsub_fcmp_equiv(
1003; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
1004; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00
1005; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
1006; CHECK-NEXT:    ret float [[C]]
1007;
1008  %A = fcmp oeq float %x, 1.0
1009  %B = fsub nsz float %z, %x
1010  %C = select i1 %A, float %B, float %y
1011  ret float %C
1012}
1013
1014define i32 @select_sub_icmp_bad(i32 %x, i32 %y, i32 %z) {
1015; CHECK-LABEL: @select_sub_icmp_bad(
1016; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
1017; CHECK-NEXT:    [[B:%.*]] = sub i32 0, [[Z:%.*]]
1018; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1019; CHECK-NEXT:    ret i32 [[C]]
1020;
1021  %A = icmp eq i32 %x, 0
1022  %B = sub i32 %x, %z
1023  %C = select i1 %A, i32 %B, i32 %y
1024  ret i32 %C
1025}
1026
1027define i32 @select_sub_icmp_bad_2(i32 %x, i32 %y, i32 %z) {
1028; CHECK-LABEL: @select_sub_icmp_bad_2(
1029; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1030; CHECK-NEXT:    [[B:%.*]] = add i32 [[Z:%.*]], -1
1031; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1032; CHECK-NEXT:    ret i32 [[C]]
1033;
1034  %A = icmp eq i32 %x, 1
1035  %B = sub i32 %z, %x
1036  %C = select i1 %A, i32 %B, i32 %y
1037  ret i32 %C
1038}
1039
1040define i32 @select_sub_icmp_bad_3(i32 %x, i32 %y, i32 %z) {
1041; CHECK-LABEL: @select_sub_icmp_bad_3(
1042; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
1043; CHECK-NEXT:    call void @use2(i1 [[A]])
1044; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
1045; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1046; CHECK-NEXT:    ret i32 [[C]]
1047;
1048  %A = icmp ne i32 %x, 0
1049  call void @use2(i1 %A)
1050  %B = sub i32 %z, %x
1051  %C = select i1 %A, i32 %B, i32 %y
1052  ret i32 %C
1053}
1054
1055define i32 @select_sub_icmp_4(i32 %x, i32 %y, i32 %z) {
1056; CHECK-LABEL: @select_sub_icmp_4(
1057; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
1058; CHECK-NEXT:    call void @use2(i1 [[A]])
1059; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
1060; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1061; CHECK-NEXT:    ret i32 [[C]]
1062;
1063  %A = icmp ne i32 %x, 0
1064  call void @use2(i1 %A)
1065  %B = sub i32 %z, %x
1066  %C = select i1 %A, i32 %B, i32 %y
1067  ret i32 %C
1068}
1069
1070define i32 @select_sub_icmp_bad_4(i32 %x, i32 %y, i32 %z, i32 %k) {
1071; CHECK-LABEL: @select_sub_icmp_bad_4(
1072; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
1073; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[K:%.*]]
1074; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1075; CHECK-NEXT:    ret i32 [[C]]
1076;
1077  %A = icmp eq i32 %x, 0
1078  %B = sub i32 %z, %k
1079  %C = select i1 %A, i32 %B, i32 %y
1080  ret i32 %C
1081}
1082
1083define i32 @select_sub_icmp_bad_5(i32 %x, i32 %y, i32 %z, i32 %k) {
1084; CHECK-LABEL: @select_sub_icmp_bad_5(
1085; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]]
1086; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
1087; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1088; CHECK-NEXT:    ret i32 [[C]]
1089;
1090  %A = icmp eq i32 %x, %k
1091  %B = sub i32 %z, %x
1092  %C = select i1 %A, i32 %B, i32 %y
1093  ret i32 %C
1094}
1095
1096define i32 @select_shl_icmp_bad(i32 %x, i32 %y, i32 %z) {
1097; CHECK-LABEL: @select_shl_icmp_bad(
1098; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1099; CHECK-NEXT:    [[B:%.*]] = shl i32 [[Z:%.*]], 1
1100; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1101; CHECK-NEXT:    ret i32 [[C]]
1102;
1103  %A = icmp eq i32 %x, 1
1104  %B = shl i32 %z, %x
1105  %C = select i1 %A, i32 %B, i32 %y
1106  ret i32 %C
1107}
1108
1109define i32 @select_lshr_icmp_bad(i32 %x, i32 %y, i32 %z) {
1110; CHECK-LABEL: @select_lshr_icmp_bad(
1111; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1112; CHECK-NEXT:    [[B:%.*]] = lshr i32 [[Z:%.*]], 1
1113; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1114; CHECK-NEXT:    ret i32 [[C]]
1115;
1116  %A = icmp eq i32 %x, 1
1117  %B = lshr i32 %z, %x
1118  %C = select i1 %A, i32 %B, i32 %y
1119  ret i32 %C
1120}
1121
1122define i32 @select_ashr_icmp_bad(i32 %x, i32 %y, i32 %z) {
1123; CHECK-LABEL: @select_ashr_icmp_bad(
1124; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1125; CHECK-NEXT:    [[B:%.*]] = ashr i32 [[Z:%.*]], 1
1126; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1127; CHECK-NEXT:    ret i32 [[C]]
1128;
1129  %A = icmp eq i32 %x, 1
1130  %B = ashr i32 %z, %x
1131  %C = select i1 %A, i32 %B, i32 %y
1132  ret i32 %C
1133}
1134
1135define i32 @select_udiv_icmp_bad(i32 %x, i32 %y, i32 %z) {
1136; CHECK-LABEL: @select_udiv_icmp_bad(
1137; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
1138; CHECK-NEXT:    [[B:%.*]] = udiv i32 [[Z:%.*]], [[X]]
1139; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1140; CHECK-NEXT:    ret i32 [[C]]
1141;
1142  %A = icmp eq i32 %x, 3
1143  %B = udiv i32 %z, %x
1144  %C = select i1 %A, i32 %B, i32 %y
1145  ret i32 %C
1146}
1147
1148define i32 @select_sdiv_icmp_bad(i32 %x, i32 %y, i32 %z) {
1149; CHECK-LABEL: @select_sdiv_icmp_bad(
1150; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
1151; CHECK-NEXT:    [[B:%.*]] = sdiv i32 [[Z:%.*]], [[X]]
1152; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1153; CHECK-NEXT:    ret i32 [[C]]
1154;
1155  %A = icmp eq i32 %x, 3
1156  %B = sdiv i32 %z, %x
1157  %C = select i1 %A, i32 %B, i32 %y
1158  ret i32 %C
1159}
1160
1161; Can replace %x with 0, because sub is only used in the select.
1162define i32 @select_replace_one_use(i32 %x, i32 %y) {
1163; CHECK-LABEL: @select_replace_one_use(
1164; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1165; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[Y:%.*]]
1166; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[SUB]], i32 [[Y]]
1167; CHECK-NEXT:    ret i32 [[S]]
1168;
1169  %c = icmp eq i32 %x, 0
1170  %sub = sub i32 %x, %y
1171  %s = select i1 %c, i32 %sub, i32 %y
1172  ret i32 %s
1173}
1174
1175; Can not replace %x with 0, because %sub has other uses as well.
1176define i32 @select_replace_multi_use(i32 %x, i32 %y) {
1177; CHECK-LABEL: @select_replace_multi_use(
1178; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1179; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X]], [[Y:%.*]]
1180; CHECK-NEXT:    call void @use_i32(i32 [[SUB]])
1181; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[SUB]], i32 [[Y]]
1182; CHECK-NEXT:    ret i32 [[S]]
1183;
1184  %c = icmp eq i32 %x, 0
1185  %sub = sub i32 %x, %y
1186  call void @use_i32(i32 %sub)
1187  %s = select i1 %c, i32 %sub, i32 %y
1188  ret i32 %s
1189}
1190
1191; Case where the replacement allows the instruction to fold away.
1192define i32 @select_replace_fold(i32 %x, i32 %y, i32 %z) {
1193; CHECK-LABEL: @select_replace_fold(
1194; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1195; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 [[Y:%.*]]
1196; CHECK-NEXT:    ret i32 [[S]]
1197;
1198  %c = icmp eq i32 %x, 0
1199  %fshr = call i32 @llvm.fshr.i32(i32 %y, i32 %z, i32 %x)
1200  %s = select i1 %c, i32 %fshr, i32 %y
1201  ret i32 %s
1202}
1203
1204
1205; Case where the use of %x is in a nested instruction.
1206define i32 @select_replace_nested(i32 %x, i32 %y, i32 %z) {
1207; CHECK-LABEL: @select_replace_nested(
1208; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1209; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 0
1210; CHECK-NEXT:    [[S:%.*]] = add i32 [[Y:%.*]], [[ADD]]
1211; CHECK-NEXT:    ret i32 [[S]]
1212;
1213  %c = icmp eq i32 %x, 0
1214  %sub = sub i32 %y, %x
1215  %add = add i32 %sub, %z
1216  %s = select i1 %c, i32 %add, i32 %y
1217  ret i32 %s
1218}
1219
1220define i32 @select_replace_nested_extra_use(i32 %x, i32 %y, i32 %z) {
1221; CHECK-LABEL: @select_replace_nested_extra_use(
1222; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1223; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[Y:%.*]], [[X]]
1224; CHECK-NEXT:    call void @use.i32(i32 [[SUB]])
1225; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SUB]], [[Z:%.*]]
1226; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Y]]
1227; CHECK-NEXT:    ret i32 [[S]]
1228;
1229  %c = icmp eq i32 %x, 0
1230  %sub = sub i32 %y, %x
1231  call void @use.i32(i32 %sub)
1232  %add = add i32 %sub, %z
1233  %s = select i1 %c, i32 %add, i32 %y
1234  ret i32 %s
1235}
1236
1237define i32 @select_replace_nested_no_simplify(i32 %x, i32 %y, i32 %z) {
1238; CHECK-LABEL: @select_replace_nested_no_simplify(
1239; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 1
1240; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[Y:%.*]], -1
1241; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SUB]], [[Z:%.*]]
1242; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Y]]
1243; CHECK-NEXT:    ret i32 [[S]]
1244;
1245  %c = icmp eq i32 %x, 1
1246  %sub = sub i32 %y, %x
1247  %add = add i32 %sub, %z
1248  %s = select i1 %c, i32 %add, i32 %y
1249  ret i32 %s
1250}
1251
1252; FIXME: We only perform replacements two levels up right now.
1253define i32 @select_replace_deeply_nested(i32 %x, i32 %y, i32 %z) {
1254; CHECK-LABEL: @select_replace_deeply_nested(
1255; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1256; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[Y:%.*]], [[X]]
1257; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SUB]], [[Z:%.*]]
1258; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[ADD]], 1
1259; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[SHL]], i32 [[Y]]
1260; CHECK-NEXT:    ret i32 [[S]]
1261;
1262  %c = icmp eq i32 %x, 0
1263  %sub = sub i32 %y, %x
1264  %add = add i32 %sub, %z
1265  %shl = shl i32 %add, 1
1266  %s = select i1 %c, i32 %shl, i32 %y
1267  ret i32 %s
1268}
1269
1270; Do not replace with constant expressions. The profitability in this case is
1271; unclear, and such replacements have historically lead to infinite combine
1272; loops.
1273define i32 @select_replace_constexpr(i32 %x, i32 %y, i32 %z) {
1274; CHECK-LABEL: @select_replace_constexpr(
1275; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], ptrtoint (ptr @g to i32)
1276; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], [[Y:%.*]]
1277; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Z:%.*]]
1278; CHECK-NEXT:    ret i32 [[S]]
1279;
1280  %c = icmp eq i32 %x, ptrtoint (ptr @g to i32)
1281  %add = add i32 %x, %y
1282  %s = select i1 %c, i32 %add, i32 %z
1283  ret i32 %s
1284}
1285
1286; Don't replace with a potentially undef constant, as undef could evaluate
1287; to different values for both uses.
1288define <2 x i32> @select_replace_undef(<2 x i32> %x, <2 x i32> %y) {
1289; CHECK-LABEL: @select_replace_undef(
1290; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 0, i32 undef>
1291; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i32> [[X]], [[Y:%.*]]
1292; CHECK-NEXT:    [[S:%.*]] = select <2 x i1> [[C]], <2 x i32> [[SUB]], <2 x i32> [[Y]]
1293; CHECK-NEXT:    ret <2 x i32> [[S]]
1294;
1295  %c = icmp eq <2 x i32> %x, <i32 0, i32 undef>
1296  %sub = sub <2 x i32> %x, %y
1297  %s = select <2 x i1> %c, <2 x i32> %sub, <2 x i32> %y
1298  ret <2 x i32> %s
1299}
1300
1301; We can replace the call arguments, as the call is speculatable.
1302define i32 @select_replace_call_speculatable(i32 %x, i32 %y) {
1303; CHECK-LABEL: @select_replace_call_speculatable(
1304; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1305; CHECK-NEXT:    [[CALL:%.*]] = call i32 @call_speculatable(i32 0, i32 0)
1306; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y:%.*]]
1307; CHECK-NEXT:    ret i32 [[S]]
1308;
1309  %c = icmp eq i32 %x, 0
1310  %call = call i32 @call_speculatable(i32 %x, i32 %x)
1311  %s = select i1 %c, i32 %call, i32 %y
1312  ret i32 %s
1313}
1314
1315define i32 @select_replace_call_speculatable_intrinsic(i32 %x, i32 %y) {
1316; CHECK-LABEL: @select_replace_call_speculatable_intrinsic(
1317; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1318; CHECK-NEXT:    [[CALL:%.*]] = call i32 @llvm.smax.i32(i32 [[Y:%.*]], i32 0)
1319; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y]]
1320; CHECK-NEXT:    ret i32 [[S]]
1321;
1322  %c = icmp eq i32 %x, 0
1323  %call = call i32 @llvm.smax.i32(i32 %x, i32 %y)
1324  %s = select i1 %c, i32 %call, i32 %y
1325  ret i32 %s
1326}
1327
1328; We can't replace the call arguments, as the call is not speculatable. We
1329; may end up changing side-effects or causing undefined behavior.
1330define i32 @select_replace_call_non_speculatable(i32 %x, i32 %y) {
1331; CHECK-LABEL: @select_replace_call_non_speculatable(
1332; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1333; CHECK-NEXT:    [[CALL:%.*]] = call i32 @call_non_speculatable(i32 [[X]], i32 [[X]])
1334; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y:%.*]]
1335; CHECK-NEXT:    ret i32 [[S]]
1336;
1337  %c = icmp eq i32 %x, 0
1338  %call = call i32 @call_non_speculatable(i32 %x, i32 %x)
1339  %s = select i1 %c, i32 %call, i32 %y
1340  ret i32 %s
1341}
1342
1343; We can replace %x by 2 here, because division by two cannot cause UB.
1344; FIXME: As we check speculation prior to replacement, we don't catch this.
1345define i32 @select_replace_sdiv_speculatable(i32 %x, i32 %y) {
1346; CHECK-LABEL: @select_replace_sdiv_speculatable(
1347; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 2
1348; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[Y:%.*]], [[X]]
1349; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]]
1350; CHECK-NEXT:    ret i32 [[S]]
1351;
1352  %c = icmp eq i32 %x, 2
1353  %div = sdiv i32 %y, %x
1354  %s = select i1 %c, i32 %div, i32 %y
1355  ret i32 %s
1356}
1357
1358; We cannot replace %x by -1, because division by -1 can cause UB.
1359define i32 @select_replace_sdiv_non_speculatable(i32 %x, i32 %y) {
1360; CHECK-LABEL: @select_replace_sdiv_non_speculatable(
1361; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], -1
1362; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[Y:%.*]], [[X]]
1363; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]]
1364; CHECK-NEXT:    ret i32 [[S]]
1365;
1366  %c = icmp eq i32 %x, -1
1367  %div = sdiv i32 %y, %x
1368  %s = select i1 %c, i32 %div, i32 %y
1369  ret i32 %s
1370}
1371
1372; We can replace %x by 2 here, because division by two cannot cause UB.
1373; FIXME: As we check speculation prior to replacement, we don't catch this.
1374define i32 @select_replace_udiv_speculatable(i32 %x, i32 %y) {
1375; CHECK-LABEL: @select_replace_udiv_speculatable(
1376; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], 2
1377; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[Y:%.*]], [[X]]
1378; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]]
1379; CHECK-NEXT:    ret i32 [[S]]
1380;
1381  %c = icmp eq i32 %x, 2
1382  %div = udiv i32 %y, %x
1383  %s = select i1 %c, i32 %div, i32 %y
1384  ret i32 %s
1385}
1386
1387; We can't replace %x by 0 here, because that would cause UB. However,
1388; replacing the udiv result by poison is fine.
1389define i32 @select_replace_udiv_non_speculatable(i32 %x, i32 %y) {
1390; CHECK-LABEL: @select_replace_udiv_non_speculatable(
1391; CHECK-NEXT:    ret i32 [[Y:%.*]]
1392;
1393  %c = icmp eq i32 %x, 0
1394  %div = udiv i32 %y, %x
1395  %s = select i1 %c, i32 %div, i32 %y
1396  ret i32 %s
1397}
1398
1399; We can't replace %i in the phi node here, because it refers to %i from
1400; the previous loop iteration, not the current one.
1401define void @select_replace_phi(i32 %x) {
1402; CHECK-LABEL: @select_replace_phi(
1403; CHECK-NEXT:  entry:
1404; CHECK-NEXT:    br label [[LOOP:%.*]]
1405; CHECK:       loop:
1406; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
1407; CHECK-NEXT:    [[I_PREV:%.*]] = phi i32 [ -1, [[ENTRY]] ], [ [[I]], [[LOOP]] ]
1408; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1409; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[I]], 0
1410; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[I_PREV]], i32 2
1411; CHECK-NEXT:    call void @use_i32(i32 [[S]])
1412; CHECK-NEXT:    br label [[LOOP]]
1413;
1414entry:
1415  br label %loop
1416
1417loop:
1418  %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
1419  %i.prev = phi i32 [ -1, %entry], [ %i, %loop ]
1420  %i.next = add i32 %i, 1
1421  %c = icmp eq i32 %i, 0
1422  %s = select i1 %c, i32 %i.prev, i32 2
1423  call void @use_i32(i32 %s)
1424  br label %loop
1425}
1426
1427@g = global i32 0
1428declare i32 @llvm.fshr.i32(i32, i32, i32)
1429declare i32 @call_speculatable(i32, i32) speculatable
1430declare i32 @call_non_speculatable(i32, i32)
1431declare void @use_i32(i32)
1432
1433!0 = !{!"branch_weights", i32 2, i32 10}
1434