[clang] Document the return value of __builtin_COLUMN (#118360)
[llvm-project.git] / llvm / test / Transforms / InstCombine / select-binop-cmp.ll
blobe563cafbc7e4f2e43c5fe7fcf4fb60d37d85b6bf
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use(<2 x i1>)
5 declare void @use2(i1)
6 declare void @use.i32(i32)
8 define 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]]
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
20 define 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]]
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
32 define 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]]
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
44 define 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]]
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
56 define 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]]
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
68 define 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]]
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
80 define 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]]
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
92 define <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]]
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
104 define <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]]
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
118 define 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]]
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
130 define 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]]
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
144 define 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]]
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
156 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
158 define 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]]
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
170 define 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]]
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
184 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
186 define 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]]
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
200 define 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]]
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
212 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
214 define 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]]
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
226 define 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]]
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
238 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
240 define 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]]
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
252 define 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]]
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
266 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
268 define 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]]
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
282 define 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]]
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
294 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
296 define 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]]
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
308 define 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]]
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
320 define 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]]
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
332 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
334 define 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]]
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
346 define 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]]
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
358 define 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]]
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
370 define 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]]
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
384 define 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]]
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
398 define <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]]
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
410 define 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]]
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
424 define 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]]
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
436 define 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]]
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
450 define 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]]
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
462 define 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]]
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
476 ; Negative tests
477 define 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]]
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
490 define 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]]
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
503 define 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]]
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
516 define 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]]
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
529 define 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]]
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
542 define 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]]
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
555 ; Value equivalence substitution is valid.
557 define <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]]
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
570 ; Value equivalence substitution is invalid due to lane-crossing shufflevector.
572 define <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]]
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
585 ; Folding this would only be legal if we sanitized undef to 0.
586 define <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]]
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
599 define 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]]
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
612 define 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]]
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
625 define 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]]
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
637 define 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]]
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
650 define 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]]
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
661 define 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]]
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
672 define 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]]
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
683 define 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]]
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
696 define 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]]
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
709 define 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]]
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
722 define 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]]
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
735 ; Invalid comparison type
736 define 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]]
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
749 ; Invalid comparison type
750 define 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]]
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
763 ; Invalid order of operands of select
764 define 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]]
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
777 ; Invalid comparison type
778 define 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]]
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
791 ; Invalid order of operands of select
792 define 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]]
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
805 ; Do not transform if we have signed zeros and if Z is possibly negative zero
806 define 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]]
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
819 ; Invalid comparison type
820 define 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]]
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
835 ; Invalid comparison type
836 define 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]]
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
849 ; Invalid comparison type
850 define 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]]
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
865 ; Do not transform if Z is possibly negative zero
866 define 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]]
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
880 ; Do not transform if we have signed zeros and if Z is possibly negative zero
881 define 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]]
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
894 ; Invalid order of operands of select
895 define 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]]
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
908 define 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]]
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
921 define 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]]
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
933 define 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]]
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
946 define 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]]
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
959 define 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]]
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
972 define 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]]
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
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).
988 define 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]]
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
1001 define 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]]
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
1014 define 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]]
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
1027 define 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]]
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
1040 define 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]]
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
1055 define 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]]
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
1070 define 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]]
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
1083 define 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]]
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
1096 define 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]]
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
1109 define 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]]
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
1122 define 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]]
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
1135 define 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]]
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
1148 define 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]]
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
1161 ; Can replace %x with 0, because sub is only used in the select.
1162 define 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]]
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
1175 ; Can not replace %x with 0, because %sub has other uses as well.
1176 define 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]]
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
1191 ; Case where the replacement allows the instruction to fold away.
1192 define 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]]
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
1205 ; Case where the use of %x is in a nested instruction.
1206 define 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]]
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
1220 define 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]]
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
1237 define 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]]
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
1252 ; FIXME: We only perform replacements two levels up right now.
1253 define 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]]
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
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.
1273 define 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]]
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
1286 ; Don't replace with a potentially undef constant, as undef could evaluate
1287 ; to different values for both uses.
1288 define <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]]
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
1301 ; We can replace the call arguments, as the call is speculatable.
1302 define 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]]
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
1315 define 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]]
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
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.
1330 define 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]]
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
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.
1345 define 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]]
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
1358 ; We cannot replace %x by -1, because division by -1 can cause UB.
1359 define 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]]
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
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.
1374 define 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]]
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
1387 ; We can't replace %x by 0 here, because that would cause UB. However,
1388 ; replacing the udiv result by poison is fine.
1389 define i32 @select_replace_udiv_non_speculatable(i32 %x, i32 %y) {
1390 ; CHECK-LABEL: @select_replace_udiv_non_speculatable(
1391 ; CHECK-NEXT:    ret i32 [[Y:%.*]]
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
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.
1401 define 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]]
1414 entry:
1415   br label %loop
1417 loop:
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
1427 @g = global i32 0
1428 declare i32 @llvm.fshr.i32(i32, i32, i32)
1429 declare i32 @call_speculatable(i32, i32) speculatable
1430 declare i32 @call_non_speculatable(i32, i32)
1431 declare void @use_i32(i32)
1433 !0 = !{!"branch_weights", i32 2, i32 10}