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>)
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
16 %C = select i1 %A, i32 %B, i32 %y
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
28 %C = select i1 %A, i32 %y, i32 %B
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
40 %C = select i1 %A, i32 %B, i32 %y, !prof !0
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
52 %C = select i1 %A, i32 %B, i32 %y
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
64 %C = select i1 %A, i32 %B, i32 %y
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
76 %C = select i1 %A, i32 %B, i32 %y
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
88 %C = select i1 %A, i32 %B, i32 %y
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
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
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
126 %C = select i1 %A, i32 %B, i32 %y
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
140 %C = select i1 %A, i32 %y, i32 %B
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
366 %C = select i1 %A, i32 %B, i32 %y
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)
380 %C = select i1 %A, i32 %B, i32 %y
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)
394 %C = select i1 %A, i32 %y, i32 %B
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
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
420 %C = select i1 %A, i32 %y, i32 %B
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
432 %C = select i1 %A, i32 %B, i32 %y
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
446 %C = select i1 %A, i32 %y, i32 %B
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
458 %C = select i1 %A, i32 %B, i32 %y
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
472 %C = select i1 %A, i32 %y, i32 %B
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
486 %C = select i1 %A, i32 %B, i32 %y
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
499 %C = select i1 %A, i32 %B, i32 %y
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
512 %C = select i1 %A, i32 %B, i32 %y
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
525 %C = select i1 %A, i32 %B, i32 %y
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
538 %C = select i1 %A, i32 %B, i32 %y
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
551 %C = select i1 %A, i32 %y, i32 %B
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
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
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
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
608 %C = select i1 %A, i32 %B, i32 %y
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
621 %C = select i1 %A, i32 %B, i32 %y
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
633 %C = select i1 %A, i32 %B, i32 %y
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
646 %C = select i1 %A, i32 %B, i32 %y
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
657 %C = select i1 %A, i32 %B, i32 0
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
668 %C = select i1 %A, i32 0, i32 %B
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
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
692 %C = select i1 %A, i32 %B, i32 0
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
705 %C = select i1 %A, i32 %B, i32 0
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1023 %C = select i1 %A, i32 %B, i32 %y
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
1036 %C = select i1 %A, i32 %B, i32 %y
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)
1051 %C = select i1 %A, i32 %B, i32 %y
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)
1066 %C = select i1 %A, i32 %B, i32 %y
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
1079 %C = select i1 %A, i32 %B, i32 %y
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
1092 %C = select i1 %A, i32 %B, i32 %y
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
1105 %C = select i1 %A, i32 %B, i32 %y
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
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
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
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
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
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
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
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
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
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
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
1270 ; Do not replace with constant expressions. The profitability in this case is
1271 ; unclear, and such replacements have historically lead to infinite combine
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
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
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
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
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
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
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
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
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
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:%.*]]
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]]
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)
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}