1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4declare void @use(<2 x i1>)
5declare void @use2(i1)
6
7define i32 @select_xor_icmp(i32 %x, i32 %y, i32 %z) {
8; CHECK-LABEL: @select_xor_icmp(
9; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
10; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
11; CHECK-NEXT:    ret i32 [[C]]
12;
13  %A = icmp eq i32 %x, 0
14  %B = xor i32 %x, %z
15  %C = select i1 %A, i32 %B, i32 %y
16  ret i32 %C
17}
18
19define i32 @select_xor_icmp2(i32 %x, i32 %y, i32 %z) {
20; CHECK-LABEL: @select_xor_icmp2(
21; CHECK-NEXT:    [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0
22; CHECK-NEXT:    [[C:%.*]] = select i1 [[A_NOT]], i32 [[Z:%.*]], i32 [[Y:%.*]]
23; CHECK-NEXT:    ret i32 [[C]]
24;
25  %A = icmp ne i32 %x, 0
26  %B = xor i32 %x, %z
27  %C = select i1 %A, i32 %y, i32 %B
28  ret i32 %C
29}
30
31define i32 @select_xor_icmp_meta(i32 %x, i32 %y, i32 %z) {
32; CHECK-LABEL: @select_xor_icmp_meta(
33; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
34; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]], !prof !0
35; CHECK-NEXT:    ret i32 [[C]]
36;
37  %A = icmp eq i32 %x, 0
38  %B = xor i32 %x, %z
39  %C = select i1 %A, i32 %B, i32 %y, !prof !0
40  ret i32 %C
41}
42
43define i32 @select_mul_icmp(i32 %x, i32 %y, i32 %z) {
44; CHECK-LABEL: @select_mul_icmp(
45; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
46; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
47; CHECK-NEXT:    ret i32 [[C]]
48;
49  %A = icmp eq i32 %x, 1
50  %B = mul i32 %x, %z
51  %C = select i1 %A, i32 %B, i32 %y
52  ret i32 %C
53}
54
55define i32 @select_add_icmp(i32 %x, i32 %y, i32 %z) {
56; CHECK-LABEL: @select_add_icmp(
57; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
58; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
59; CHECK-NEXT:    ret i32 [[C]]
60;
61  %A = icmp eq i32 %x, 0
62  %B = add i32 %x, %z
63  %C = select i1 %A, i32 %B, i32 %y
64  ret i32 %C
65}
66
67define i32 @select_or_icmp(i32 %x, i32 %y, i32 %z) {
68; CHECK-LABEL: @select_or_icmp(
69; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
70; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
71; CHECK-NEXT:    ret i32 [[C]]
72;
73  %A = icmp eq i32 %x, 0
74  %B = or i32 %x, %z
75  %C = select i1 %A, i32 %B, i32 %y
76  ret i32 %C
77}
78
79define i32 @select_and_icmp(i32 %x, i32 %y, i32 %z) {
80; CHECK-LABEL: @select_and_icmp(
81; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], -1
82; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
83; CHECK-NEXT:    ret i32 [[C]]
84;
85  %A = icmp eq i32 %x, -1
86  %B = and i32 %x, %z
87  %C = select i1 %A, i32 %B, i32 %y
88  ret i32 %C
89}
90
91define <2 x i8> @select_xor_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
92; CHECK-LABEL: @select_xor_icmp_vec(
93; CHECK-NEXT:    [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer
94; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]]
95; CHECK-NEXT:    ret <2 x i8> [[C]]
96;
97  %A = icmp eq <2 x i8>  %x, <i8 0, i8 0>
98  %B = xor <2 x i8>  %x, %z
99  %C = select <2 x i1>  %A, <2 x i8>  %B, <2 x i8>  %y
100  ret <2 x i8>  %C
101}
102
103define <2 x i8> @select_xor_icmp_vec_use(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
104; CHECK-LABEL: @select_xor_icmp_vec_use(
105; CHECK-NEXT:    [[A:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer
106; CHECK-NEXT:    call void @use(<2 x i1> [[A]])
107; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]]
108; CHECK-NEXT:    ret <2 x i8> [[C]]
109;
110  %A = icmp ne <2 x i8>  %x, <i8 0, i8 0>
111  call void @use(<2 x i1> %A)
112  %B = xor <2 x i8>  %x, %z
113  %C = select <2 x i1>  %A, <2 x i8>  %y, <2 x i8>  %B
114  ret <2 x i8>  %C
115}
116
117define i32 @select_xor_inv_icmp(i32 %x, i32 %y, i32 %z) {
118; CHECK-LABEL: @select_xor_inv_icmp(
119; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
120; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
121; CHECK-NEXT:    ret i32 [[C]]
122;
123  %A = icmp eq i32 %x, 0
124  %B = xor i32 %z, %x
125  %C = select i1 %A, i32 %B, i32 %y
126  ret i32 %C
127}
128
129define i32 @select_xor_inv_icmp2(i32 %x, i32 %y, i32 %z) {
130; CHECK-LABEL: @select_xor_inv_icmp2(
131; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
132; CHECK-NEXT:    call void @use2(i1 [[A]])
133; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
134; CHECK-NEXT:    ret i32 [[C]]
135;
136  %A = icmp ne i32 %x, 0
137  call void @use2(i1 %A) ; thwart predicate canonicalization
138  %B = xor i32 %x, %z
139  %C = select i1 %A, i32 %y, i32 %B
140  ret i32 %C
141}
142
143define float @select_fadd_fcmp(float %x, float %y, float %z) {
144; CHECK-LABEL: @select_fadd_fcmp(
145; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
146; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
147; CHECK-NEXT:    ret float [[C]]
148;
149  %A = fcmp oeq float %x, -0.0
150  %B = fadd nsz float %x, %z
151  %C = select i1 %A, float %B, float %y
152  ret float %C
153}
154
155; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
156
157define float @select_fadd_fcmp_poszero(float %x, float %y, float %z) {
158; CHECK-LABEL: @select_fadd_fcmp_poszero(
159; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
160; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
161; CHECK-NEXT:    ret float [[C]]
162;
163  %A = fcmp oeq float %x, 0.0
164  %B = fadd nsz float %z, %x
165  %C = select i1 %A, float %B, float %y
166  ret float %C
167}
168
169define float @select_fadd_fcmp_2(float %x, float %y, float %v) {
170; CHECK-LABEL: @select_fadd_fcmp_2(
171; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
172; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
173; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
174; CHECK-NEXT:    ret float [[C]]
175;
176  %A = fcmp une float %x, -0.0
177  %z = fadd float %v, 0.0 ; cannot produce -0.0
178  %B = fadd float %z, %x
179  %C = select i1 %A, float %y, float %B
180  ret float %C
181}
182
183; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
184
185define float @select_fadd_fcmp_2_poszero(float %x, float %y, float %v) {
186; CHECK-LABEL: @select_fadd_fcmp_2_poszero(
187; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
188; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
189; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
190; CHECK-NEXT:    ret float [[C]]
191;
192  %A = fcmp une float %x, 0.0
193  %z = fadd float %v, 0.0 ; cannot produce -0.0
194  %B = fadd float %z, %x
195  %C = select i1 %A, float %y, float %B
196  ret float %C
197}
198
199define float @select_fadd_fcmp_3(float %x, float %y) {
200; CHECK-LABEL: @select_fadd_fcmp_3(
201; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
202; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00
203; CHECK-NEXT:    ret float [[C]]
204;
205  %A = fcmp une float %x, -0.0
206  %B = fadd float 6.0, %x
207  %C = select i1 %A, float %y, float %B
208  ret float %C
209}
210
211; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
212
213define float @select_fadd_fcmp_3_poszero(float %x, float %y) {
214; CHECK-LABEL: @select_fadd_fcmp_3_poszero(
215; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
216; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00
217; CHECK-NEXT:    ret float [[C]]
218;
219  %A = fcmp une float %x, 0.0
220  %B = fadd float 6.0, %x
221  %C = select i1 %A, float %y, float %B
222  ret float %C
223}
224
225define float @select_fadd_fcmp_4(float %x, float %y, float %z) {
226; CHECK-LABEL: @select_fadd_fcmp_4(
227; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
228; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]
229; CHECK-NEXT:    ret float [[C]]
230;
231  %A = fcmp une float %x, -0.0
232  %B = fadd nsz float %z, %x
233  %C = select i1 %A, float %y, float %B
234  ret float %C
235}
236
237; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
238
239define float @select_fadd_fcmp_4_poszero(float %x, float %y, float %z) {
240; CHECK-LABEL: @select_fadd_fcmp_4_poszero(
241; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
242; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]
243; CHECK-NEXT:    ret float [[C]]
244;
245  %A = fcmp une float %x, 0.0
246  %B = fadd nsz float %z, %x
247  %C = select i1 %A, float %y, float %B
248  ret float %C
249}
250
251define float @select_fadd_fcmp_5(float %x, float %y, float %v) {
252; CHECK-LABEL: @select_fadd_fcmp_5(
253; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
254; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
255; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]
256; CHECK-NEXT:    ret float [[C]]
257;
258  %A = fcmp oeq float %x, -0.0
259  %z = fadd float %v, 0.0 ; cannot produce -0.0
260  %B = fadd float %z, %x
261  %C = select i1 %A, float %B, float %y
262  ret float %C
263}
264
265; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
266
267define float @select_fadd_fcmp_5_poszero(float %x, float %y, float %v) {
268; CHECK-LABEL: @select_fadd_fcmp_5_poszero(
269; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
270; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
271; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]
272; CHECK-NEXT:    ret float [[C]]
273;
274  %A = fcmp oeq float %x, 0.0
275  %z = fadd float %v, 0.0 ; cannot produce -0.0
276  %B = fadd float %z, %x
277  %C = select i1 %A, float %B, float %y
278  ret float %C
279}
280
281define float @select_fadd_fcmp_6(float %x, float %y, float %z) {
282; CHECK-LABEL: @select_fadd_fcmp_6(
283; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
284; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]
285; CHECK-NEXT:    ret float [[C]]
286;
287  %A = fcmp oeq float %x, -0.0
288  %B = fadd float %x, 6.0
289  %C = select i1 %A, float %B, float %y
290  ret float %C
291}
292
293; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
294
295define float @select_fadd_fcmp_6_poszero(float %x, float %y, float %z) {
296; CHECK-LABEL: @select_fadd_fcmp_6_poszero(
297; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
298; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]
299; CHECK-NEXT:    ret float [[C]]
300;
301  %A = fcmp oeq float %x, 0.0
302  %B = fadd float %x, 6.0
303  %C = select i1 %A, float %B, float %y
304  ret float %C
305}
306
307define float @select_fmul_fcmp(float %x, float %y, float %z) {
308; CHECK-LABEL: @select_fmul_fcmp(
309; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
310; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
311; CHECK-NEXT:    ret float [[C]]
312;
313  %A = fcmp oeq float %x, 1.0
314  %B = fmul nsz float %x, %z
315  %C = select i1 %A, float %B, float %y
316  ret float %C
317}
318
319define float @select_fsub_fcmp(float %x, float %y, float %z) {
320; CHECK-LABEL: @select_fsub_fcmp(
321; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
322; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
323; CHECK-NEXT:    ret float [[C]]
324;
325  %A = fcmp oeq float %x, 0.0
326  %B = fsub nsz float %z, %x
327  %C = select i1 %A, float %B, float %y
328  ret float %C
329}
330
331; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
332
333define float @select_fsub_fcmp_negzero(float %x, float %y, float %z) {
334; CHECK-LABEL: @select_fsub_fcmp_negzero(
335; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
336; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
337; CHECK-NEXT:    ret float [[C]]
338;
339  %A = fcmp oeq float %x, -0.0
340  %B = fsub nsz float %z, %x
341  %C = select i1 %A, float %B, float %y
342  ret float %C
343}
344
345define float @select_fdiv_fcmp(float %x, float %y, float %z) {
346; CHECK-LABEL: @select_fdiv_fcmp(
347; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
348; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
349; CHECK-NEXT:    ret float [[C]]
350;
351  %A = fcmp oeq float %x, 1.0
352  %B = fdiv nsz float %z, %x
353  %C = select i1 %A, float %B, float %y
354  ret float %C
355}
356
357define i32 @select_sub_icmp(i32 %x, i32 %y, i32 %z) {
358; CHECK-LABEL: @select_sub_icmp(
359; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
360; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
361; CHECK-NEXT:    ret i32 [[C]]
362;
363  %A = icmp eq i32 %x, 0
364  %B = sub i32 %z, %x
365  %C = select i1 %A, i32 %B, i32 %y
366  ret i32 %C
367}
368
369define i32 @select_sub_icmp_2(i32 %x, i32 %y, i32 %z) {
370; CHECK-LABEL: @select_sub_icmp_2(
371; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
372; CHECK-NEXT:    call void @use2(i1 [[A]])
373; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
374; CHECK-NEXT:    ret i32 [[C]]
375;
376  %A = icmp eq i32 %x, 0
377  call void @use2(i1 %A)
378  %B = sub i32 %z, %x
379  %C = select i1 %A, i32 %B, i32 %y
380  ret i32 %C
381}
382
383define i32 @select_sub_icmp_3(i32 %x, i32 %y, i32 %z) {
384; CHECK-LABEL: @select_sub_icmp_3(
385; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
386; CHECK-NEXT:    call void @use2(i1 [[A]])
387; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
388; CHECK-NEXT:    ret i32 [[C]]
389;
390  %A = icmp ne i32 %x, 0
391  call void @use2(i1 %A)
392  %B = sub i32 %z, %x
393  %C = select i1 %A, i32 %y, i32 %B
394  ret i32 %C
395}
396
397define <2 x i8> @select_sub_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
398; CHECK-LABEL: @select_sub_icmp_vec(
399; CHECK-NEXT:    [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer
400; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]]
401; CHECK-NEXT:    ret <2 x i8> [[C]]
402;
403  %A = icmp eq <2 x i8>  %x, <i8 0, i8 0>
404  %B = sub <2 x i8>  %z, %x
405  %C = select <2 x i1>  %A, <2 x i8>  %B, <2 x i8>  %y
406  ret <2 x i8>  %C
407}
408
409define i32 @select_shl_icmp(i32 %x, i32 %y, i32 %z) {
410; CHECK-LABEL: @select_shl_icmp(
411; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
412; CHECK-NEXT:    call void @use2(i1 [[A]])
413; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
414; CHECK-NEXT:    ret i32 [[C]]
415;
416  %A = icmp ne i32 %x, 0
417  call void @use2(i1 %A) ; thwart predicate canonicalization
418  %B = shl i32 %z, %x
419  %C = select i1 %A, i32 %y, i32 %B
420  ret i32 %C
421}
422
423define i32 @select_lshr_icmp(i32 %x, i32 %y, i32 %z) {
424; CHECK-LABEL: @select_lshr_icmp(
425; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
426; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
427; CHECK-NEXT:    ret i32 [[C]]
428;
429  %A = icmp eq i32 %x, 0
430  %B = lshr i32 %z, %x
431  %C = select i1 %A, i32 %B, i32 %y
432  ret i32 %C
433}
434
435define i32 @select_ashr_icmp(i32 %x, i32 %y, i32 %z) {
436; CHECK-LABEL: @select_ashr_icmp(
437; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
438; CHECK-NEXT:    call void @use2(i1 [[A]])
439; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
440; CHECK-NEXT:    ret i32 [[C]]
441;
442  %A = icmp ne i32 %x, 0
443  call void @use2(i1 %A) ; thwart predicate canonicalization
444  %B = ashr i32 %z, %x
445  %C = select i1 %A, i32 %y, i32 %B
446  ret i32 %C
447}
448
449define i32 @select_udiv_icmp(i32 %x, i32 %y, i32 %z) {
450; CHECK-LABEL: @select_udiv_icmp(
451; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
452; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
453; CHECK-NEXT:    ret i32 [[C]]
454;
455  %A = icmp eq i32 %x, 1
456  %B = udiv i32 %z, %x
457  %C = select i1 %A, i32 %B, i32 %y
458  ret i32 %C
459}
460
461define i32 @select_sdiv_icmp(i32 %x, i32 %y, i32 %z) {
462; CHECK-LABEL: @select_sdiv_icmp(
463; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 1
464; CHECK-NEXT:    call void @use2(i1 [[A]])
465; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
466; CHECK-NEXT:    ret i32 [[C]]
467;
468  %A = icmp ne i32 %x, 1
469  call void @use2(i1 %A) ; thwart predicate canonicalization
470  %B = sdiv i32 %z, %x
471  %C = select i1 %A, i32 %y, i32 %B
472  ret i32 %C
473}
474
475; Negative tests
476define i32 @select_xor_icmp_bad_1(i32 %x, i32 %y, i32 %z, i32 %k) {
477; CHECK-LABEL: @select_xor_icmp_bad_1(
478; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]]
479; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]
480; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
481; CHECK-NEXT:    ret i32 [[C]]
482;
483  %A = icmp eq i32 %x, %k
484  %B = xor i32 %x, %z
485  %C = select i1 %A, i32 %B, i32 %y
486  ret i32 %C
487}
488
489define i32 @select_xor_icmp_bad_2(i32 %x, i32 %y, i32 %z, i32 %k) {
490; CHECK-LABEL: @select_xor_icmp_bad_2(
491; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
492; CHECK-NEXT:    [[B:%.*]] = xor i32 [[K:%.*]], [[Z:%.*]]
493; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
494; CHECK-NEXT:    ret i32 [[C]]
495;
496  %A = icmp eq i32 %x, 0
497  %B = xor i32 %k, %z
498  %C = select i1 %A, i32 %B, i32 %y
499  ret i32 %C
500}
501
502define i32 @select_xor_icmp_bad_3(i32 %x, i32 %y, i32 %z) {
503; CHECK-LABEL: @select_xor_icmp_bad_3(
504; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
505; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]
506; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
507; CHECK-NEXT:    ret i32 [[C]]
508;
509  %A = icmp eq i32 %x, 3
510  %B = xor i32 %x, %z
511  %C = select i1 %A, i32 %B, i32 %y
512  ret i32 %C
513}
514
515define i32 @select_xor_fcmp_bad_4(i32 %x, i32 %y, i32 %z, float %k) {
516; CHECK-LABEL: @select_xor_fcmp_bad_4(
517; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[K:%.*]], 0.000000e+00
518; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X:%.*]], [[Z:%.*]]
519; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
520; CHECK-NEXT:    ret i32 [[C]]
521;
522  %A = fcmp oeq float %k, 0.0
523  %B = xor i32 %x, %z
524  %C = select i1 %A, i32 %B, i32 %y
525  ret i32 %C
526}
527
528define i32 @select_xor_icmp_bad_5(i32 %x, i32 %y, i32 %z) {
529; CHECK-LABEL: @select_xor_icmp_bad_5(
530; CHECK-NEXT:    [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0
531; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]
532; CHECK-NEXT:    [[C:%.*]] = select i1 [[A_NOT]], i32 [[Y:%.*]], i32 [[B]]
533; CHECK-NEXT:    ret i32 [[C]]
534;
535  %A = icmp ne i32 %x, 0
536  %B = xor i32 %x, %z
537  %C = select i1 %A, i32 %B, i32 %y
538  ret i32 %C
539}
540
541define i32 @select_xor_icmp_bad_6(i32 %x, i32 %y, i32 %z) {
542; CHECK-LABEL: @select_xor_icmp_bad_6(
543; CHECK-NEXT:    [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 1
544; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]
545; CHECK-NEXT:    [[C:%.*]] = select i1 [[A_NOT]], i32 [[B]], i32 [[Y:%.*]]
546; CHECK-NEXT:    ret i32 [[C]]
547;
548  %A = icmp ne i32 %x, 1
549  %B = xor i32 %x, %z
550  %C = select i1 %A, i32 %y, i32 %B
551  ret i32 %C
552}
553
554define <2 x i8> @select_xor_icmp_vec_bad(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
555; CHECK-LABEL: @select_xor_icmp_vec_bad(
556; CHECK-NEXT:    [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 5, i8 3>
557; CHECK-NEXT:    [[B:%.*]] = xor <2 x i8> [[X]], [[Z:%.*]]
558; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]]
559; CHECK-NEXT:    ret <2 x i8> [[C]]
560;
561  %A = icmp eq <2 x i8>  %x, <i8 5, i8 3>
562  %B = xor <2 x i8>  %x, %z
563  %C = select <2 x i1>  %A, <2 x i8>  %B, <2 x i8>  %y
564  ret <2 x i8>  %C
565}
566
567; Folding this would only be legal if we sanitized undef to 0.
568define <2 x i8> @select_xor_icmp_vec_undef(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
569; CHECK-LABEL: @select_xor_icmp_vec_undef(
570; CHECK-NEXT:    [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 0, i8 undef>
571; CHECK-NEXT:    [[B:%.*]] = xor <2 x i8> [[X]], [[Z:%.*]]
572; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]]
573; CHECK-NEXT:    ret <2 x i8> [[C]]
574;
575  %A = icmp eq <2 x i8>  %x, <i8 0, i8 undef>
576  %B = xor <2 x i8>  %x, %z
577  %C = select <2 x i1>  %A, <2 x i8>  %B, <2 x i8>  %y
578  ret <2 x i8>  %C
579}
580
581define i32 @select_mul_icmp_bad(i32 %x, i32 %y, i32 %z, i32 %k) {
582; CHECK-LABEL: @select_mul_icmp_bad(
583; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
584; CHECK-NEXT:    [[B:%.*]] = mul i32 [[X]], [[Z:%.*]]
585; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
586; CHECK-NEXT:    ret i32 [[C]]
587;
588  %A = icmp eq i32 %x, 3
589  %B = mul i32 %x, %z
590  %C = select i1 %A, i32 %B, i32 %y
591  ret i32 %C
592}
593
594define i32 @select_add_icmp_bad(i32 %x, i32 %y, i32 %z) {
595; CHECK-LABEL: @select_add_icmp_bad(
596; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
597; CHECK-NEXT:    [[B:%.*]] = add i32 [[X]], [[Z:%.*]]
598; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
599; CHECK-NEXT:    ret i32 [[C]]
600;
601  %A = icmp eq i32 %x, 1
602  %B = add i32 %x, %z
603  %C = select i1 %A, i32 %B, i32 %y
604  ret i32 %C
605}
606
607define i32 @select_and_icmp_zero(i32 %x, i32 %y, i32 %z) {
608; CHECK-LABEL: @select_and_icmp_zero(
609; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
610; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 0, i32 [[Y:%.*]]
611; CHECK-NEXT:    ret i32 [[C]]
612;
613  %A = icmp eq i32 %x, 0
614  %B = and i32 %x, %z
615  %C = select i1 %A, i32 %B, i32 %y
616  ret i32 %C
617}
618
619define i32 @select_or_icmp_bad(i32 %x, i32 %y, i32 %z) {
620; CHECK-LABEL: @select_or_icmp_bad(
621; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
622; CHECK-NEXT:    [[B:%.*]] = or i32 [[X]], [[Z:%.*]]
623; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
624; CHECK-NEXT:    ret i32 [[C]]
625;
626  %A = icmp eq i32 %x, 3
627  %B = or i32 %x, %z
628  %C = select i1 %A, i32 %B, i32 %y
629  ret i32 %C
630}
631
632; Invalid identity constant for FP op
633define float @select_fadd_fcmp_bad(float %x, float %y, float %z) {
634; CHECK-LABEL: @select_fadd_fcmp_bad(
635; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], -1.000000e+00
636; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
637; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
638; CHECK-NEXT:    ret float [[C]]
639;
640  %A = fcmp oeq float %x, -1.0
641  %B = fadd nsz float %x, %z
642  %C = select i1 %A, float %B, float %y
643  ret float %C
644}
645
646; Invalid comparison type
647define float @select_fadd_fcmp_bad_2(float %x, float %y, float %z) {
648; CHECK-LABEL: @select_fadd_fcmp_bad_2(
649; CHECK-NEXT:    [[A:%.*]] = fcmp ueq float [[X:%.*]], -1.000000e+00
650; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
651; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
652; CHECK-NEXT:    ret float [[C]]
653;
654  %A = fcmp ueq float %x, -1.0
655  %B = fadd float %x, %z
656  %C = select i1 %A, float %B, float %y
657  ret float %C
658}
659
660; Invalid comparison type
661define float @select_fadd_fcmp_bad_3(float %x, float %y, float %z, float %k) {
662; CHECK-LABEL: @select_fadd_fcmp_bad_3(
663; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], [[K:%.*]]
664; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
665; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
666; CHECK-NEXT:    ret float [[C]]
667;
668  %A = fcmp one float %x, %k
669  %B = fadd float %x, %z
670  %C = select i1 %A, float %y, float %B
671  ret float %C
672}
673
674; Invalid order of operands of select
675define float @select_fadd_fcmp_bad_4(float %x, float %y, float %z) {
676; CHECK-LABEL: @select_fadd_fcmp_bad_4(
677; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
678; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
679; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
680; CHECK-NEXT:    ret float [[C]]
681;
682  %A = fcmp une float %x, -0.0
683  %B = fadd float %x, %z
684  %C = select i1 %A, float %B, float %y
685  ret float %C
686}
687
688; Invalid comparison type
689define float @select_fadd_fcmp_bad_5(float %x, float %y, float %z) {
690; CHECK-LABEL: @select_fadd_fcmp_bad_5(
691; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
692; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
693; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
694; CHECK-NEXT:    ret float [[C]]
695;
696  %A = fcmp one float %x, -0.0
697  %B = fadd nsz float %z, %x
698  %C = select i1 %A, float %y, float %B
699  ret float %C
700}
701
702; Invalid order of operands of select
703define float @select_fadd_fcmp_bad_6(float %x, float %y, float %z) {
704; CHECK-LABEL: @select_fadd_fcmp_bad_6(
705; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
706; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
707; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
708; CHECK-NEXT:    ret float [[C]]
709;
710  %A = fcmp oeq float %x, -0.0
711  %B = fadd nsz float %z, %x
712  %C = select i1 %A, float %y, float %B
713  ret float %C
714}
715
716; Do not transform if we have signed zeros and if Z is possibly negative zero
717define float @select_fadd_fcmp_bad_7(float %x, float %y, float %z) {
718; CHECK-LABEL: @select_fadd_fcmp_bad_7(
719; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
720; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
721; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
722; CHECK-NEXT:    ret float [[C]]
723;
724  %A = fcmp oeq float %x, -0.0
725  %B = fadd float %x, %z
726  %C = select i1 %A, float %B, float %y
727  ret float %C
728}
729
730; Invalid comparison type
731define float @select_fadd_fcmp_bad_8(float %x, float %y, float %v) {
732; CHECK-LABEL: @select_fadd_fcmp_bad_8(
733; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
734; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00
735; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z]], [[X]]
736; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
737; CHECK-NEXT:    ret float [[C]]
738;
739  %A = fcmp one float %x, -0.0
740  %z = fadd float %v, -1.0
741  %B = fadd float %z, %x
742  %C = select i1 %A, float %y, float %B
743  ret float %C
744}
745
746; Invalid comparison type
747define float @select_fadd_fcmp_bad_9(float %x, float %y, float %z) {
748; CHECK-LABEL: @select_fadd_fcmp_bad_9(
749; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
750; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
751; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
752; CHECK-NEXT:    ret float [[C]]
753;
754  %A = fcmp one float %x, -0.0
755  %B = fadd nsz float %z, %x
756  %C = select i1 %A, float %y, float %B
757  ret float %C
758}
759
760; Invalid comparison type
761define float @select_fadd_fcmp_bad_10(float %x, float %y, float %v) {
762; CHECK-LABEL: @select_fadd_fcmp_bad_10(
763; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
764; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
765; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z]], [[X]]
766; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
767; CHECK-NEXT:    ret float [[C]]
768;
769  %A = fcmp one float %x, -0.0
770  %z = fadd float %v, 0.0 ; cannot produce -0.0
771  %B = fadd float %z, %x
772  %C = select i1 %A, float %y, float %B
773  ret float %C
774}
775
776; Do not transform if Z is possibly negative zero
777define float @select_fadd_fcmp_bad_11(float %x, float %y, float %v) {
778; CHECK-LABEL: @select_fadd_fcmp_bad_11(
779; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
780; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00
781; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
782; CHECK-NEXT:    ret float [[C]]
783;
784  %A = fcmp une float %x, -0.0
785  %z = fadd float %v, -1.0
786  %B = fadd nsz float %z, %x
787  %C = select i1 %A, float %y, float %B
788  ret float %C
789}
790
791; Do not transform if we have signed zeros and if Z is possibly negative zero
792define float @select_fadd_fcmp_bad_12(float %x, float %y, float %z) {
793; CHECK-LABEL: @select_fadd_fcmp_bad_12(
794; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
795; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z:%.*]], [[X]]
796; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
797; CHECK-NEXT:    ret float [[C]]
798;
799  %A = fcmp une float %x, -0.0
800  %B = fadd float %z, %x
801  %C = select i1 %A, float %y, float %B
802  ret float %C
803}
804
805; Invalid order of operands of select
806define float @select_fadd_fcmp_bad_13(float %x, float %y, float %z) {
807; CHECK-LABEL: @select_fadd_fcmp_bad_13(
808; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
809; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
810; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
811; CHECK-NEXT:    ret float [[C]]
812;
813  %A = fcmp oeq float %x, -0.0
814  %B = fadd nsz float %x, %z
815  %C = select i1 %A, float %y, float %B
816  ret float %C
817}
818
819; Invalid identity constant for FP op
820define float @select_fadd_fcmp_bad_14(float %x, float %y, float %z) {
821; CHECK-LABEL: @select_fadd_fcmp_bad_14(
822; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], -1.000000e+00
823; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
824; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
825; CHECK-NEXT:    ret float [[C]]
826;
827  %A = fcmp une float %x, -1.0
828  %B = fadd nsz float %x, %z
829  %C = select i1 %A, float %y, float %B
830  ret float %C
831}
832
833define float @select_fmul_fcmp_bad(float %x, float %y, float %z) {
834; CHECK-LABEL: @select_fmul_fcmp_bad(
835; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
836; CHECK-NEXT:    [[B:%.*]] = fmul nsz float [[X]], [[Z:%.*]]
837; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
838; CHECK-NEXT:    ret float [[C]]
839;
840  %A = fcmp oeq float %x, 3.0
841  %B = fmul nsz float %x, %z
842  %C = select i1 %A, float %B, float %y
843  ret float %C
844}
845
846define float @select_fmul_fcmp_bad_2(float %x, float %y, float %z) {
847; CHECK-LABEL: @select_fmul_fcmp_bad_2(
848; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
849; CHECK-NEXT:    [[B:%.*]] = fmul float [[X]], [[Z:%.*]]
850; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
851; CHECK-NEXT:    ret float [[C]]
852;
853  %A = fcmp oeq float %x, 1.0
854  %B = fmul float %x, %z
855  %C = select i1 %A, float %B, float %y
856  ret float %C
857}
858
859define float @select_fmul_icmp_bad(float %x, float %y, float %z, i32 %k) {
860; CHECK-LABEL: @select_fmul_icmp_bad(
861; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[K:%.*]], 0
862; CHECK-NEXT:    [[B:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]
863; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
864; CHECK-NEXT:    ret float [[C]]
865;
866  %A = icmp eq i32 %k, 0
867  %B = fmul float %x, %z
868  %C = select i1 %A, float %B, float %y
869  ret float %C
870}
871
872define float @select_fmul_icmp_bad_2(float %x, float %y, float %z, i32 %k) {
873; CHECK-LABEL: @select_fmul_icmp_bad_2(
874; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[K:%.*]], 0
875; CHECK-NEXT:    [[B:%.*]] = fmul nsz float [[X:%.*]], [[Z:%.*]]
876; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
877; CHECK-NEXT:    ret float [[C]]
878;
879  %A = icmp eq i32 %k, 0
880  %B = fmul nsz float %x, %z
881  %C = select i1 %A, float %B, float %y
882  ret float %C
883}
884
885define float @select_fdiv_fcmp_bad(float %x, float %y, float %z) {
886; CHECK-LABEL: @select_fdiv_fcmp_bad(
887; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
888; CHECK-NEXT:    [[B:%.*]] = fdiv float [[X]], [[Z:%.*]]
889; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
890; CHECK-NEXT:    ret float [[C]]
891;
892  %A = fcmp oeq float %x, 1.0
893  %B = fdiv float %x, %z
894  %C = select i1 %A, float %B, float %y
895  ret float %C
896}
897
898define float @select_fdiv_fcmp_bad_2(float %x, float %y, float %z) {
899; CHECK-LABEL: @select_fdiv_fcmp_bad_2(
900; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
901; CHECK-NEXT:    [[B:%.*]] = fdiv nsz float [[X]], [[Z:%.*]]
902; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
903; CHECK-NEXT:    ret float [[C]]
904;
905  %A = fcmp oeq float %x, 3.0
906  %B = fdiv nsz float %x, %z
907  %C = select i1 %A, float %B, float %y
908  ret float %C
909}
910
911; The transform is not valid when x = -0.0 and z = -0.0
912; (optimized code would return -0.0, but this returns +0.0).
913
914define float @select_fsub_fcmp_bad(float %x, float %y, float %z) {
915; CHECK-LABEL: @select_fsub_fcmp_bad(
916; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
917; CHECK-NEXT:    [[B:%.*]] = fsub float [[Z:%.*]], [[X]]
918; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
919; CHECK-NEXT:    ret float [[C]]
920;
921  %A = fcmp oeq float %x, 0.0
922  %B = fsub float %z, %x
923  %C = select i1 %A, float %B, float %y
924  ret float %C
925}
926
927define float @select_fsub_fcmp_bad_2(float %x, float %y, float %z) {
928; CHECK-LABEL: @select_fsub_fcmp_bad_2(
929; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
930; CHECK-NEXT:    [[B:%.*]] = fsub nsz float [[Z:%.*]], [[X]]
931; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
932; CHECK-NEXT:    ret float [[C]]
933;
934  %A = fcmp oeq float %x, 1.0
935  %B = fsub nsz float %z, %x
936  %C = select i1 %A, float %B, float %y
937  ret float %C
938}
939
940define i32 @select_sub_icmp_bad(i32 %x, i32 %y, i32 %z) {
941; CHECK-LABEL: @select_sub_icmp_bad(
942; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
943; CHECK-NEXT:    [[B:%.*]] = sub i32 [[X]], [[Z:%.*]]
944; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
945; CHECK-NEXT:    ret i32 [[C]]
946;
947  %A = icmp eq i32 %x, 0
948  %B = sub i32 %x, %z
949  %C = select i1 %A, i32 %B, i32 %y
950  ret i32 %C
951}
952
953define i32 @select_sub_icmp_bad_2(i32 %x, i32 %y, i32 %z) {
954; CHECK-LABEL: @select_sub_icmp_bad_2(
955; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
956; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
957; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
958; CHECK-NEXT:    ret i32 [[C]]
959;
960  %A = icmp eq i32 %x, 1
961  %B = sub i32 %z, %x
962  %C = select i1 %A, i32 %B, i32 %y
963  ret i32 %C
964}
965
966define i32 @select_sub_icmp_bad_3(i32 %x, i32 %y, i32 %z) {
967; CHECK-LABEL: @select_sub_icmp_bad_3(
968; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
969; CHECK-NEXT:    call void @use2(i1 [[A]])
970; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
971; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
972; CHECK-NEXT:    ret i32 [[C]]
973;
974  %A = icmp ne i32 %x, 0
975  call void @use2(i1 %A)
976  %B = sub i32 %z, %x
977  %C = select i1 %A, i32 %B, i32 %y
978  ret i32 %C
979}
980
981define i32 @select_sub_icmp_4(i32 %x, i32 %y, i32 %z) {
982; CHECK-LABEL: @select_sub_icmp_4(
983; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
984; CHECK-NEXT:    call void @use2(i1 [[A]])
985; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
986; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
987; CHECK-NEXT:    ret i32 [[C]]
988;
989  %A = icmp ne i32 %x, 0
990  call void @use2(i1 %A)
991  %B = sub i32 %z, %x
992  %C = select i1 %A, i32 %B, i32 %y
993  ret i32 %C
994}
995
996define i32 @select_sub_icmp_bad_4(i32 %x, i32 %y, i32 %z, i32 %k) {
997; CHECK-LABEL: @select_sub_icmp_bad_4(
998; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
999; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[K:%.*]]
1000; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1001; CHECK-NEXT:    ret i32 [[C]]
1002;
1003  %A = icmp eq i32 %x, 0
1004  %B = sub i32 %z, %k
1005  %C = select i1 %A, i32 %B, i32 %y
1006  ret i32 %C
1007}
1008
1009define i32 @select_sub_icmp_bad_5(i32 %x, i32 %y, i32 %z, i32 %k) {
1010; CHECK-LABEL: @select_sub_icmp_bad_5(
1011; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]]
1012; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
1013; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1014; CHECK-NEXT:    ret i32 [[C]]
1015;
1016  %A = icmp eq i32 %x, %k
1017  %B = sub i32 %z, %x
1018  %C = select i1 %A, i32 %B, i32 %y
1019  ret i32 %C
1020}
1021
1022define i32 @select_shl_icmp_bad(i32 %x, i32 %y, i32 %z) {
1023; CHECK-LABEL: @select_shl_icmp_bad(
1024; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1025; CHECK-NEXT:    [[B:%.*]] = shl i32 [[Z:%.*]], [[X]]
1026; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1027; CHECK-NEXT:    ret i32 [[C]]
1028;
1029  %A = icmp eq i32 %x, 1
1030  %B = shl i32 %z, %x
1031  %C = select i1 %A, i32 %B, i32 %y
1032  ret i32 %C
1033}
1034
1035define i32 @select_lshr_icmp_bad(i32 %x, i32 %y, i32 %z) {
1036; CHECK-LABEL: @select_lshr_icmp_bad(
1037; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1038; CHECK-NEXT:    [[B:%.*]] = lshr i32 [[Z:%.*]], [[X]]
1039; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1040; CHECK-NEXT:    ret i32 [[C]]
1041;
1042  %A = icmp eq i32 %x, 1
1043  %B = lshr i32 %z, %x
1044  %C = select i1 %A, i32 %B, i32 %y
1045  ret i32 %C
1046}
1047
1048define i32 @select_ashr_icmp_bad(i32 %x, i32 %y, i32 %z) {
1049; CHECK-LABEL: @select_ashr_icmp_bad(
1050; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1051; CHECK-NEXT:    [[B:%.*]] = ashr i32 [[Z:%.*]], [[X]]
1052; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1053; CHECK-NEXT:    ret i32 [[C]]
1054;
1055  %A = icmp eq i32 %x, 1
1056  %B = ashr i32 %z, %x
1057  %C = select i1 %A, i32 %B, i32 %y
1058  ret i32 %C
1059}
1060
1061define i32 @select_udiv_icmp_bad(i32 %x, i32 %y, i32 %z) {
1062; CHECK-LABEL: @select_udiv_icmp_bad(
1063; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
1064; CHECK-NEXT:    [[B:%.*]] = udiv i32 [[Z:%.*]], [[X]]
1065; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1066; CHECK-NEXT:    ret i32 [[C]]
1067;
1068  %A = icmp eq i32 %x, 3
1069  %B = udiv i32 %z, %x
1070  %C = select i1 %A, i32 %B, i32 %y
1071  ret i32 %C
1072}
1073
1074define i32 @select_sdiv_icmp_bad(i32 %x, i32 %y, i32 %z) {
1075; CHECK-LABEL: @select_sdiv_icmp_bad(
1076; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
1077; CHECK-NEXT:    [[B:%.*]] = sdiv i32 [[Z:%.*]], [[X]]
1078; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1079; CHECK-NEXT:    ret i32 [[C]]
1080;
1081  %A = icmp eq i32 %x, 3
1082  %B = sdiv i32 %z, %x
1083  %C = select i1 %A, i32 %B, i32 %y
1084  ret i32 %C
1085}
1086
1087!0 = !{!"branch_weights", i32 2, i32 10}
1088