[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / select-binop-cmp.ll
bloba473acd73049369f33b74479250e430f3d0e1766
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare void @use(<2 x i1>)
5 declare void @use2(i1)
7 define 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]]
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
19 define i32 @select_xor_icmp2(i32 %x, i32 %y, i32 %z) {
20 ; CHECK-LABEL: @select_xor_icmp2(
21 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
22 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
23 ; CHECK-NEXT:    ret i32 [[C]]
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
31 define 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]]
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
43 define 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]]
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
55 define 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]]
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
67 define 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]]
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
79 define 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]]
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
91 define <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]]
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
103 define <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]]
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
117 define 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]]
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
129 define 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]]
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
143 define 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]]
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
155 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
157 define 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]]
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
169 define 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]]
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
183 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
185 define 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]]
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
199 define 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]]
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
211 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
213 define 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]]
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
225 define 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]]
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
237 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
239 define 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]]
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
251 define 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]]
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
265 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
267 define 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]]
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
281 define 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]]
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
293 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
295 define 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]]
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
307 define 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]]
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
319 define 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]]
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
331 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
333 define 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]]
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
345 define 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]]
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
357 define 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]]
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
369 define 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]]
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
383 define 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]]
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
397 define <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]]
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
409 define 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]]
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
423 define 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]]
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
435 define 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]]
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
449 define 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]]
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
461 define 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]]
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
475 ; Negative tests
476 define 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]]
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
489 define 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]]
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
502 define 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]]
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
515 define 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]]
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
528 define i32 @select_xor_icmp_bad_5(i32 %x, i32 %y, i32 %z) {
529 ; CHECK-LABEL: @select_xor_icmp_bad_5(
530 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
531 ; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]
532 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[B]]
533 ; CHECK-NEXT:    ret i32 [[C]]
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
541 define i32 @select_xor_icmp_bad_6(i32 %x, i32 %y, i32 %z) {
542 ; CHECK-LABEL: @select_xor_icmp_bad_6(
543 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
544 ; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]
545 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
546 ; CHECK-NEXT:    ret i32 [[C]]
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
554 define <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]]
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
567 ; TODO: support for undefs, check for an identity constant does not handle them yet
568 define <2 x i8> @select_xor_icmp_vec_bad_2(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
569 ; CHECK-LABEL: @select_xor_icmp_vec_bad_2(
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]]
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
581 define 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]]
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
594 define 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]]
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
607 define i32 @select_and_icmp_bad(i32 %x, i32 %y, i32 %z) {
608 ; CHECK-LABEL: @select_and_icmp_bad(
609 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
610 ; CHECK-NEXT:    [[B:%.*]] = and i32 [[X]], [[Z:%.*]]
611 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
612 ; CHECK-NEXT:    ret i32 [[C]]
614   %A = icmp eq i32 %x, 0
615   %B = and i32 %x, %z
616   %C = select i1 %A, i32 %B, i32 %y
617   ret i32 %C
620 define i32 @select_or_icmp_bad(i32 %x, i32 %y, i32 %z) {
621 ; CHECK-LABEL: @select_or_icmp_bad(
622 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
623 ; CHECK-NEXT:    [[B:%.*]] = or i32 [[X]], [[Z:%.*]]
624 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
625 ; CHECK-NEXT:    ret i32 [[C]]
627   %A = icmp eq i32 %x, 3
628   %B = or i32 %x, %z
629   %C = select i1 %A, i32 %B, i32 %y
630   ret i32 %C
633 ; Invalid identity constant for FP op
634 define float @select_fadd_fcmp_bad(float %x, float %y, float %z) {
635 ; CHECK-LABEL: @select_fadd_fcmp_bad(
636 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], -1.000000e+00
637 ; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
638 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
639 ; CHECK-NEXT:    ret float [[C]]
641   %A = fcmp oeq float %x, -1.0
642   %B = fadd nsz float %x, %z
643   %C = select i1 %A, float %B, float %y
644   ret float %C
647 ; Invalid comparison type
648 define float @select_fadd_fcmp_bad_2(float %x, float %y, float %z) {
649 ; CHECK-LABEL: @select_fadd_fcmp_bad_2(
650 ; CHECK-NEXT:    [[A:%.*]] = fcmp ueq float [[X:%.*]], -1.000000e+00
651 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
652 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
653 ; CHECK-NEXT:    ret float [[C]]
655   %A = fcmp ueq float %x, -1.0
656   %B = fadd float %x, %z
657   %C = select i1 %A, float %B, float %y
658   ret float %C
661 ; Invalid comparison type
662 define float @select_fadd_fcmp_bad_3(float %x, float %y, float %z, float %k) {
663 ; CHECK-LABEL: @select_fadd_fcmp_bad_3(
664 ; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], [[K:%.*]]
665 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
666 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
667 ; CHECK-NEXT:    ret float [[C]]
669   %A = fcmp one float %x, %k
670   %B = fadd float %x, %z
671   %C = select i1 %A, float %y, float %B
672   ret float %C
675 ; Invalid order of operands of select
676 define float @select_fadd_fcmp_bad_4(float %x, float %y, float %z) {
677 ; CHECK-LABEL: @select_fadd_fcmp_bad_4(
678 ; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
679 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
680 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
681 ; CHECK-NEXT:    ret float [[C]]
683   %A = fcmp une float %x, -0.0
684   %B = fadd float %x, %z
685   %C = select i1 %A, float %B, float %y
686   ret float %C
689 ; Invalid comparison type
690 define float @select_fadd_fcmp_bad_5(float %x, float %y, float %z) {
691 ; CHECK-LABEL: @select_fadd_fcmp_bad_5(
692 ; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
693 ; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
694 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
695 ; CHECK-NEXT:    ret float [[C]]
697   %A = fcmp one float %x, -0.0
698   %B = fadd nsz float %z, %x
699   %C = select i1 %A, float %y, float %B
700   ret float %C
703 ; Invalid order of operands of select
704 define float @select_fadd_fcmp_bad_6(float %x, float %y, float %z) {
705 ; CHECK-LABEL: @select_fadd_fcmp_bad_6(
706 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
707 ; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
708 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
709 ; CHECK-NEXT:    ret float [[C]]
711   %A = fcmp oeq float %x, -0.0
712   %B = fadd nsz float %z, %x
713   %C = select i1 %A, float %y, float %B
714   ret float %C
717 ; Do not transform if we have signed zeros and if Z is possibly negative zero
718 define float @select_fadd_fcmp_bad_7(float %x, float %y, float %z) {
719 ; CHECK-LABEL: @select_fadd_fcmp_bad_7(
720 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
721 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
722 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
723 ; CHECK-NEXT:    ret float [[C]]
725   %A = fcmp oeq float %x, -0.0
726   %B = fadd float %x, %z
727   %C = select i1 %A, float %B, float %y
728   ret float %C
731 ; Invalid comparison type
732 define float @select_fadd_fcmp_bad_8(float %x, float %y, float %v) {
733 ; CHECK-LABEL: @select_fadd_fcmp_bad_8(
734 ; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
735 ; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00
736 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z]], [[X]]
737 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
738 ; CHECK-NEXT:    ret float [[C]]
740   %A = fcmp one float %x, -0.0
741   %z = fadd float %v, -1.0
742   %B = fadd float %z, %x
743   %C = select i1 %A, float %y, float %B
744   ret float %C
747 ; Invalid comparison type
748 define float @select_fadd_fcmp_bad_9(float %x, float %y, float %z) {
749 ; CHECK-LABEL: @select_fadd_fcmp_bad_9(
750 ; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
751 ; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
752 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
753 ; CHECK-NEXT:    ret float [[C]]
755   %A = fcmp one float %x, -0.0
756   %B = fadd nsz float %z, %x
757   %C = select i1 %A, float %y, float %B
758   ret float %C
761 ; Invalid comparison type
762 define float @select_fadd_fcmp_bad_10(float %x, float %y, float %v) {
763 ; CHECK-LABEL: @select_fadd_fcmp_bad_10(
764 ; CHECK-NEXT:    [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
765 ; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
766 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z]], [[X]]
767 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
768 ; CHECK-NEXT:    ret float [[C]]
770   %A = fcmp one float %x, -0.0
771   %z = fadd float %v, 0.0 ; cannot produce -0.0
772   %B = fadd float %z, %x
773   %C = select i1 %A, float %y, float %B
774   ret float %C
777 ; Do not transform if Z is possibly negative zero
778 define float @select_fadd_fcmp_bad_11(float %x, float %y, float %v) {
779 ; CHECK-LABEL: @select_fadd_fcmp_bad_11(
780 ; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
781 ; CHECK-NEXT:    [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00
782 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
783 ; CHECK-NEXT:    ret float [[C]]
785   %A = fcmp une float %x, -0.0
786   %z = fadd float %v, -1.0
787   %B = fadd nsz float %z, %x
788   %C = select i1 %A, float %y, float %B
789   ret float %C
792 ; Do not transform if we have signed zeros and if Z is possibly negative zero
793 define float @select_fadd_fcmp_bad_12(float %x, float %y, float %z) {
794 ; CHECK-LABEL: @select_fadd_fcmp_bad_12(
795 ; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
796 ; CHECK-NEXT:    [[B:%.*]] = fadd float [[Z:%.*]], [[X]]
797 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
798 ; CHECK-NEXT:    ret float [[C]]
800   %A = fcmp une float %x, -0.0
801   %B = fadd float %z, %x
802   %C = select i1 %A, float %y, float %B
803   ret float %C
806 ; Invalid order of operands of select
807 define float @select_fadd_fcmp_bad_13(float %x, float %y, float %z) {
808 ; CHECK-LABEL: @select_fadd_fcmp_bad_13(
809 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
810 ; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
811 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
812 ; CHECK-NEXT:    ret float [[C]]
814   %A = fcmp oeq float %x, -0.0
815   %B = fadd nsz float %x, %z
816   %C = select i1 %A, float %y, float %B
817   ret float %C
820 ; Invalid identity constant for FP op
821 define float @select_fadd_fcmp_bad_14(float %x, float %y, float %z) {
822 ; CHECK-LABEL: @select_fadd_fcmp_bad_14(
823 ; CHECK-NEXT:    [[A:%.*]] = fcmp une float [[X:%.*]], -1.000000e+00
824 ; CHECK-NEXT:    [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
825 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
826 ; CHECK-NEXT:    ret float [[C]]
828   %A = fcmp une float %x, -1.0
829   %B = fadd nsz float %x, %z
830   %C = select i1 %A, float %y, float %B
831   ret float %C
834 define float @select_fmul_fcmp_bad(float %x, float %y, float %z) {
835 ; CHECK-LABEL: @select_fmul_fcmp_bad(
836 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
837 ; CHECK-NEXT:    [[B:%.*]] = fmul nsz float [[X]], [[Z:%.*]]
838 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
839 ; CHECK-NEXT:    ret float [[C]]
841   %A = fcmp oeq float %x, 3.0
842   %B = fmul nsz float %x, %z
843   %C = select i1 %A, float %B, float %y
844   ret float %C
847 define float @select_fmul_fcmp_bad_2(float %x, float %y, float %z) {
848 ; CHECK-LABEL: @select_fmul_fcmp_bad_2(
849 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
850 ; CHECK-NEXT:    [[B:%.*]] = fmul float [[X]], [[Z:%.*]]
851 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
852 ; CHECK-NEXT:    ret float [[C]]
854   %A = fcmp oeq float %x, 1.0
855   %B = fmul float %x, %z
856   %C = select i1 %A, float %B, float %y
857   ret float %C
860 define float @select_fmul_icmp_bad(float %x, float %y, float %z, i32 %k) {
861 ; CHECK-LABEL: @select_fmul_icmp_bad(
862 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[K:%.*]], 0
863 ; CHECK-NEXT:    [[B:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]
864 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
865 ; CHECK-NEXT:    ret float [[C]]
867   %A = icmp eq i32 %k, 0
868   %B = fmul float %x, %z
869   %C = select i1 %A, float %B, float %y
870   ret float %C
873 define float @select_fmul_icmp_bad_2(float %x, float %y, float %z, i32 %k) {
874 ; CHECK-LABEL: @select_fmul_icmp_bad_2(
875 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[K:%.*]], 0
876 ; CHECK-NEXT:    [[B:%.*]] = fmul nsz float [[X:%.*]], [[Z:%.*]]
877 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
878 ; CHECK-NEXT:    ret float [[C]]
880   %A = icmp eq i32 %k, 0
881   %B = fmul nsz float %x, %z
882   %C = select i1 %A, float %B, float %y
883   ret float %C
886 define float @select_fdiv_fcmp_bad(float %x, float %y, float %z) {
887 ; CHECK-LABEL: @select_fdiv_fcmp_bad(
888 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
889 ; CHECK-NEXT:    [[B:%.*]] = fdiv float [[X]], [[Z:%.*]]
890 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
891 ; CHECK-NEXT:    ret float [[C]]
893   %A = fcmp oeq float %x, 1.0
894   %B = fdiv float %x, %z
895   %C = select i1 %A, float %B, float %y
896   ret float %C
899 define float @select_fdiv_fcmp_bad_2(float %x, float %y, float %z) {
900 ; CHECK-LABEL: @select_fdiv_fcmp_bad_2(
901 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
902 ; CHECK-NEXT:    [[B:%.*]] = fdiv nsz float [[X]], [[Z:%.*]]
903 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
904 ; CHECK-NEXT:    ret float [[C]]
906   %A = fcmp oeq float %x, 3.0
907   %B = fdiv nsz float %x, %z
908   %C = select i1 %A, float %B, float %y
909   ret float %C
912 ; The transform is not valid when x = -0.0 and z = -0.0
913 ; (optimized code would return -0.0, but this returns +0.0).
915 define float @select_fsub_fcmp_bad(float %x, float %y, float %z) {
916 ; CHECK-LABEL: @select_fsub_fcmp_bad(
917 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
918 ; CHECK-NEXT:    [[B:%.*]] = fsub float [[Z:%.*]], [[X]]
919 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
920 ; CHECK-NEXT:    ret float [[C]]
922   %A = fcmp oeq float %x, 0.0
923   %B = fsub float %z, %x
924   %C = select i1 %A, float %B, float %y
925   ret float %C
928 define float @select_fsub_fcmp_bad_2(float %x, float %y, float %z) {
929 ; CHECK-LABEL: @select_fsub_fcmp_bad_2(
930 ; CHECK-NEXT:    [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
931 ; CHECK-NEXT:    [[B:%.*]] = fsub nsz float [[Z:%.*]], [[X]]
932 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
933 ; CHECK-NEXT:    ret float [[C]]
935   %A = fcmp oeq float %x, 1.0
936   %B = fsub nsz float %z, %x
937   %C = select i1 %A, float %B, float %y
938   ret float %C
941 define i32 @select_sub_icmp_bad(i32 %x, i32 %y, i32 %z) {
942 ; CHECK-LABEL: @select_sub_icmp_bad(
943 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
944 ; CHECK-NEXT:    [[B:%.*]] = sub i32 [[X]], [[Z:%.*]]
945 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
946 ; CHECK-NEXT:    ret i32 [[C]]
948   %A = icmp eq i32 %x, 0
949   %B = sub i32 %x, %z
950   %C = select i1 %A, i32 %B, i32 %y
951   ret i32 %C
954 define i32 @select_sub_icmp_bad_2(i32 %x, i32 %y, i32 %z) {
955 ; CHECK-LABEL: @select_sub_icmp_bad_2(
956 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
957 ; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
958 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
959 ; CHECK-NEXT:    ret i32 [[C]]
961   %A = icmp eq i32 %x, 1
962   %B = sub i32 %z, %x
963   %C = select i1 %A, i32 %B, i32 %y
964   ret i32 %C
967 define i32 @select_sub_icmp_bad_3(i32 %x, i32 %y, i32 %z) {
968 ; CHECK-LABEL: @select_sub_icmp_bad_3(
969 ; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
970 ; CHECK-NEXT:    call void @use2(i1 [[A]])
971 ; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
972 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
973 ; CHECK-NEXT:    ret i32 [[C]]
975   %A = icmp ne i32 %x, 0
976   call void @use2(i1 %A)
977   %B = sub i32 %z, %x
978   %C = select i1 %A, i32 %B, i32 %y
979   ret i32 %C
982 define i32 @select_sub_icmp_4(i32 %x, i32 %y, i32 %z) {
983 ; CHECK-LABEL: @select_sub_icmp_4(
984 ; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
985 ; CHECK-NEXT:    call void @use2(i1 [[A]])
986 ; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
987 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
988 ; CHECK-NEXT:    ret i32 [[C]]
990   %A = icmp ne i32 %x, 0
991   call void @use2(i1 %A)
992   %B = sub i32 %z, %x
993   %C = select i1 %A, i32 %B, i32 %y
994   ret i32 %C
997 define i32 @select_sub_icmp_bad_4(i32 %x, i32 %y, i32 %z, i32 %k) {
998 ; CHECK-LABEL: @select_sub_icmp_bad_4(
999 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
1000 ; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[K:%.*]]
1001 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1002 ; CHECK-NEXT:    ret i32 [[C]]
1004   %A = icmp eq i32 %x, 0
1005   %B = sub i32 %z, %k
1006   %C = select i1 %A, i32 %B, i32 %y
1007   ret i32 %C
1010 define i32 @select_sub_icmp_bad_5(i32 %x, i32 %y, i32 %z, i32 %k) {
1011 ; CHECK-LABEL: @select_sub_icmp_bad_5(
1012 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]]
1013 ; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
1014 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1015 ; CHECK-NEXT:    ret i32 [[C]]
1017   %A = icmp eq i32 %x, %k
1018   %B = sub i32 %z, %x
1019   %C = select i1 %A, i32 %B, i32 %y
1020   ret i32 %C
1023 define i32 @select_shl_icmp_bad(i32 %x, i32 %y, i32 %z) {
1024 ; CHECK-LABEL: @select_shl_icmp_bad(
1025 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1026 ; CHECK-NEXT:    [[B:%.*]] = shl i32 [[Z:%.*]], [[X]]
1027 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1028 ; CHECK-NEXT:    ret i32 [[C]]
1030   %A = icmp eq i32 %x, 1
1031   %B = shl i32 %z, %x
1032   %C = select i1 %A, i32 %B, i32 %y
1033   ret i32 %C
1036 define i32 @select_lshr_icmp_bad(i32 %x, i32 %y, i32 %z) {
1037 ; CHECK-LABEL: @select_lshr_icmp_bad(
1038 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1039 ; CHECK-NEXT:    [[B:%.*]] = lshr i32 [[Z:%.*]], [[X]]
1040 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1041 ; CHECK-NEXT:    ret i32 [[C]]
1043   %A = icmp eq i32 %x, 1
1044   %B = lshr i32 %z, %x
1045   %C = select i1 %A, i32 %B, i32 %y
1046   ret i32 %C
1049 define i32 @select_ashr_icmp_bad(i32 %x, i32 %y, i32 %z) {
1050 ; CHECK-LABEL: @select_ashr_icmp_bad(
1051 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1052 ; CHECK-NEXT:    [[B:%.*]] = ashr i32 [[Z:%.*]], [[X]]
1053 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1054 ; CHECK-NEXT:    ret i32 [[C]]
1056   %A = icmp eq i32 %x, 1
1057   %B = ashr i32 %z, %x
1058   %C = select i1 %A, i32 %B, i32 %y
1059   ret i32 %C
1062 define i32 @select_udiv_icmp_bad(i32 %x, i32 %y, i32 %z) {
1063 ; CHECK-LABEL: @select_udiv_icmp_bad(
1064 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
1065 ; CHECK-NEXT:    [[B:%.*]] = udiv i32 [[Z:%.*]], [[X]]
1066 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1067 ; CHECK-NEXT:    ret i32 [[C]]
1069   %A = icmp eq i32 %x, 3
1070   %B = udiv i32 %z, %x
1071   %C = select i1 %A, i32 %B, i32 %y
1072   ret i32 %C
1075 define i32 @select_sdiv_icmp_bad(i32 %x, i32 %y, i32 %z) {
1076 ; CHECK-LABEL: @select_sdiv_icmp_bad(
1077 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
1078 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 [[Z:%.*]], [[X]]
1079 ; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1080 ; CHECK-NEXT:    ret i32 [[C]]
1082   %A = icmp eq i32 %x, 3
1083   %B = sdiv i32 %z, %x
1084   %C = select i1 %A, i32 %B, i32 %y
1085   ret i32 %C
1088 !0 = !{!"branch_weights", i32 2, i32 10}