1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare void @use(<2 x i1>)
7 define i32 @select_xor_icmp(i32 %x, i32 %y, i32 %z) {
8 ; CHECK-LABEL: @select_xor_icmp(
9 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
10 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
11 ; CHECK-NEXT: ret i32 [[C]]
13 %A = icmp eq i32 %x, 0
15 %C = select i1 %A, i32 %B, i32 %y
19 define i32 @select_xor_icmp2(i32 %x, i32 %y, i32 %z) {
20 ; CHECK-LABEL: @select_xor_icmp2(
21 ; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0
22 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[Z:%.*]], i32 [[Y:%.*]]
23 ; CHECK-NEXT: ret i32 [[C]]
25 %A = icmp ne i32 %x, 0
27 %C = select i1 %A, i32 %y, i32 %B
31 define i32 @select_xor_icmp_meta(i32 %x, i32 %y, i32 %z) {
32 ; CHECK-LABEL: @select_xor_icmp_meta(
33 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
34 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]], !prof [[PROF0:![0-9]+]]
35 ; CHECK-NEXT: ret i32 [[C]]
37 %A = icmp eq i32 %x, 0
39 %C = select i1 %A, i32 %B, i32 %y, !prof !0
43 define i32 @select_mul_icmp(i32 %x, i32 %y, i32 %z) {
44 ; CHECK-LABEL: @select_mul_icmp(
45 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
46 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
47 ; CHECK-NEXT: ret i32 [[C]]
49 %A = icmp eq i32 %x, 1
51 %C = select i1 %A, i32 %B, i32 %y
55 define i32 @select_add_icmp(i32 %x, i32 %y, i32 %z) {
56 ; CHECK-LABEL: @select_add_icmp(
57 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
58 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
59 ; CHECK-NEXT: ret i32 [[C]]
61 %A = icmp eq i32 %x, 0
63 %C = select i1 %A, i32 %B, i32 %y
67 define i32 @select_or_icmp(i32 %x, i32 %y, i32 %z) {
68 ; CHECK-LABEL: @select_or_icmp(
69 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
70 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
71 ; CHECK-NEXT: ret i32 [[C]]
73 %A = icmp eq i32 %x, 0
75 %C = select i1 %A, i32 %B, i32 %y
79 define i32 @select_and_icmp(i32 %x, i32 %y, i32 %z) {
80 ; CHECK-LABEL: @select_and_icmp(
81 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], -1
82 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
83 ; CHECK-NEXT: ret i32 [[C]]
85 %A = icmp eq i32 %x, -1
87 %C = select i1 %A, i32 %B, i32 %y
91 define <2 x i8> @select_xor_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
92 ; CHECK-LABEL: @select_xor_icmp_vec(
93 ; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer
94 ; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]]
95 ; CHECK-NEXT: ret <2 x i8> [[C]]
97 %A = icmp eq <2 x i8> %x, <i8 0, i8 0>
98 %B = xor <2 x i8> %x, %z
99 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y
103 define <2 x i8> @select_xor_icmp_vec_use(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
104 ; CHECK-LABEL: @select_xor_icmp_vec_use(
105 ; CHECK-NEXT: [[A:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer
106 ; CHECK-NEXT: call void @use(<2 x i1> [[A]])
107 ; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]]
108 ; CHECK-NEXT: ret <2 x i8> [[C]]
110 %A = icmp ne <2 x i8> %x, <i8 0, i8 0>
111 call void @use(<2 x i1> %A)
112 %B = xor <2 x i8> %x, %z
113 %C = select <2 x i1> %A, <2 x i8> %y, <2 x i8> %B
117 define i32 @select_xor_inv_icmp(i32 %x, i32 %y, i32 %z) {
118 ; CHECK-LABEL: @select_xor_inv_icmp(
119 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
120 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
121 ; CHECK-NEXT: ret i32 [[C]]
123 %A = icmp eq i32 %x, 0
125 %C = select i1 %A, i32 %B, i32 %y
129 define i32 @select_xor_inv_icmp2(i32 %x, i32 %y, i32 %z) {
130 ; CHECK-LABEL: @select_xor_inv_icmp2(
131 ; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
132 ; CHECK-NEXT: call void @use2(i1 [[A]])
133 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
134 ; CHECK-NEXT: ret i32 [[C]]
136 %A = icmp ne i32 %x, 0
137 call void @use2(i1 %A) ; thwart predicate canonicalization
139 %C = select i1 %A, i32 %y, i32 %B
143 define float @select_fadd_fcmp(float %x, float %y, float %z) {
144 ; CHECK-LABEL: @select_fadd_fcmp(
145 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
146 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
147 ; CHECK-NEXT: ret float [[C]]
149 %A = fcmp oeq float %x, -0.0
150 %B = fadd nsz float %x, %z
151 %C = select i1 %A, float %B, float %y
155 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
157 define float @select_fadd_fcmp_poszero(float %x, float %y, float %z) {
158 ; CHECK-LABEL: @select_fadd_fcmp_poszero(
159 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
160 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
161 ; CHECK-NEXT: ret float [[C]]
163 %A = fcmp oeq float %x, 0.0
164 %B = fadd nsz float %z, %x
165 %C = select i1 %A, float %B, float %y
169 define float @select_fadd_fcmp_2(float %x, float %y, float %v) {
170 ; CHECK-LABEL: @select_fadd_fcmp_2(
171 ; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
172 ; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
173 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
174 ; CHECK-NEXT: ret float [[C]]
176 %A = fcmp une float %x, -0.0
177 %z = fadd float %v, 0.0 ; cannot produce -0.0
178 %B = fadd float %z, %x
179 %C = select i1 %A, float %y, float %B
183 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
185 define float @select_fadd_fcmp_2_poszero(float %x, float %y, float %v) {
186 ; CHECK-LABEL: @select_fadd_fcmp_2_poszero(
187 ; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
188 ; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
189 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
190 ; CHECK-NEXT: ret float [[C]]
192 %A = fcmp une float %x, 0.0
193 %z = fadd float %v, 0.0 ; cannot produce -0.0
194 %B = fadd float %z, %x
195 %C = select i1 %A, float %y, float %B
199 define float @select_fadd_fcmp_3(float %x, float %y) {
200 ; CHECK-LABEL: @select_fadd_fcmp_3(
201 ; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
202 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00
203 ; CHECK-NEXT: ret float [[C]]
205 %A = fcmp une float %x, -0.0
206 %B = fadd float 6.0, %x
207 %C = select i1 %A, float %y, float %B
211 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
213 define float @select_fadd_fcmp_3_poszero(float %x, float %y) {
214 ; CHECK-LABEL: @select_fadd_fcmp_3_poszero(
215 ; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
216 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00
217 ; CHECK-NEXT: ret float [[C]]
219 %A = fcmp une float %x, 0.0
220 %B = fadd float 6.0, %x
221 %C = select i1 %A, float %y, float %B
225 define float @select_fadd_fcmp_4(float %x, float %y, float %z) {
226 ; CHECK-LABEL: @select_fadd_fcmp_4(
227 ; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
228 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]
229 ; CHECK-NEXT: ret float [[C]]
231 %A = fcmp une float %x, -0.0
232 %B = fadd nsz float %z, %x
233 %C = select i1 %A, float %y, float %B
237 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
239 define float @select_fadd_fcmp_4_poszero(float %x, float %y, float %z) {
240 ; CHECK-LABEL: @select_fadd_fcmp_4_poszero(
241 ; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
242 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]
243 ; CHECK-NEXT: ret float [[C]]
245 %A = fcmp une float %x, 0.0
246 %B = fadd nsz float %z, %x
247 %C = select i1 %A, float %y, float %B
251 define float @select_fadd_fcmp_5(float %x, float %y, float %v) {
252 ; CHECK-LABEL: @select_fadd_fcmp_5(
253 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
254 ; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
255 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]
256 ; CHECK-NEXT: ret float [[C]]
258 %A = fcmp oeq float %x, -0.0
259 %z = fadd float %v, 0.0 ; cannot produce -0.0
260 %B = fadd float %z, %x
261 %C = select i1 %A, float %B, float %y
265 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
267 define float @select_fadd_fcmp_5_poszero(float %x, float %y, float %v) {
268 ; CHECK-LABEL: @select_fadd_fcmp_5_poszero(
269 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
270 ; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
271 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]
272 ; CHECK-NEXT: ret float [[C]]
274 %A = fcmp oeq float %x, 0.0
275 %z = fadd float %v, 0.0 ; cannot produce -0.0
276 %B = fadd float %z, %x
277 %C = select i1 %A, float %B, float %y
281 define float @select_fadd_fcmp_6(float %x, float %y, float %z) {
282 ; CHECK-LABEL: @select_fadd_fcmp_6(
283 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
284 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]
285 ; CHECK-NEXT: ret float [[C]]
287 %A = fcmp oeq float %x, -0.0
288 %B = fadd float %x, 6.0
289 %C = select i1 %A, float %B, float %y
293 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
295 define float @select_fadd_fcmp_6_poszero(float %x, float %y, float %z) {
296 ; CHECK-LABEL: @select_fadd_fcmp_6_poszero(
297 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
298 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]
299 ; CHECK-NEXT: ret float [[C]]
301 %A = fcmp oeq float %x, 0.0
302 %B = fadd float %x, 6.0
303 %C = select i1 %A, float %B, float %y
307 define float @select_fmul_fcmp(float %x, float %y, float %z) {
308 ; CHECK-LABEL: @select_fmul_fcmp(
309 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
310 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
311 ; CHECK-NEXT: ret float [[C]]
313 %A = fcmp oeq float %x, 1.0
314 %B = fmul nsz float %x, %z
315 %C = select i1 %A, float %B, float %y
319 define float @select_fsub_fcmp(float %x, float %y, float %z) {
320 ; CHECK-LABEL: @select_fsub_fcmp(
321 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
322 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
323 ; CHECK-NEXT: ret float [[C]]
325 %A = fcmp oeq float %x, 0.0
326 %B = fsub nsz float %z, %x
327 %C = select i1 %A, float %B, float %y
331 ; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
333 define float @select_fsub_fcmp_negzero(float %x, float %y, float %z) {
334 ; CHECK-LABEL: @select_fsub_fcmp_negzero(
335 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
336 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
337 ; CHECK-NEXT: ret float [[C]]
339 %A = fcmp oeq float %x, -0.0
340 %B = fsub nsz float %z, %x
341 %C = select i1 %A, float %B, float %y
345 define float @select_fdiv_fcmp(float %x, float %y, float %z) {
346 ; CHECK-LABEL: @select_fdiv_fcmp(
347 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
348 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
349 ; CHECK-NEXT: ret float [[C]]
351 %A = fcmp oeq float %x, 1.0
352 %B = fdiv nsz float %z, %x
353 %C = select i1 %A, float %B, float %y
357 define i32 @select_sub_icmp(i32 %x, i32 %y, i32 %z) {
358 ; CHECK-LABEL: @select_sub_icmp(
359 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
360 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
361 ; CHECK-NEXT: ret i32 [[C]]
363 %A = icmp eq i32 %x, 0
365 %C = select i1 %A, i32 %B, i32 %y
369 define i32 @select_sub_icmp_2(i32 %x, i32 %y, i32 %z) {
370 ; CHECK-LABEL: @select_sub_icmp_2(
371 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
372 ; CHECK-NEXT: call void @use2(i1 [[A]])
373 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
374 ; CHECK-NEXT: ret i32 [[C]]
376 %A = icmp eq i32 %x, 0
377 call void @use2(i1 %A)
379 %C = select i1 %A, i32 %B, i32 %y
383 define i32 @select_sub_icmp_3(i32 %x, i32 %y, i32 %z) {
384 ; CHECK-LABEL: @select_sub_icmp_3(
385 ; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
386 ; CHECK-NEXT: call void @use2(i1 [[A]])
387 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
388 ; CHECK-NEXT: ret i32 [[C]]
390 %A = icmp ne i32 %x, 0
391 call void @use2(i1 %A)
393 %C = select i1 %A, i32 %y, i32 %B
397 define <2 x i8> @select_sub_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
398 ; CHECK-LABEL: @select_sub_icmp_vec(
399 ; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer
400 ; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]]
401 ; CHECK-NEXT: ret <2 x i8> [[C]]
403 %A = icmp eq <2 x i8> %x, <i8 0, i8 0>
404 %B = sub <2 x i8> %z, %x
405 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y
409 define i32 @select_shl_icmp(i32 %x, i32 %y, i32 %z) {
410 ; CHECK-LABEL: @select_shl_icmp(
411 ; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
412 ; CHECK-NEXT: call void @use2(i1 [[A]])
413 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
414 ; CHECK-NEXT: ret i32 [[C]]
416 %A = icmp ne i32 %x, 0
417 call void @use2(i1 %A) ; thwart predicate canonicalization
419 %C = select i1 %A, i32 %y, i32 %B
423 define i32 @select_lshr_icmp(i32 %x, i32 %y, i32 %z) {
424 ; CHECK-LABEL: @select_lshr_icmp(
425 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
426 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
427 ; CHECK-NEXT: ret i32 [[C]]
429 %A = icmp eq i32 %x, 0
431 %C = select i1 %A, i32 %B, i32 %y
435 define i32 @select_ashr_icmp(i32 %x, i32 %y, i32 %z) {
436 ; CHECK-LABEL: @select_ashr_icmp(
437 ; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
438 ; CHECK-NEXT: call void @use2(i1 [[A]])
439 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
440 ; CHECK-NEXT: ret i32 [[C]]
442 %A = icmp ne i32 %x, 0
443 call void @use2(i1 %A) ; thwart predicate canonicalization
445 %C = select i1 %A, i32 %y, i32 %B
449 define i32 @select_udiv_icmp(i32 %x, i32 %y, i32 %z) {
450 ; CHECK-LABEL: @select_udiv_icmp(
451 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
452 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
453 ; CHECK-NEXT: ret i32 [[C]]
455 %A = icmp eq i32 %x, 1
457 %C = select i1 %A, i32 %B, i32 %y
461 define i32 @select_sdiv_icmp(i32 %x, i32 %y, i32 %z) {
462 ; CHECK-LABEL: @select_sdiv_icmp(
463 ; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 1
464 ; CHECK-NEXT: call void @use2(i1 [[A]])
465 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
466 ; CHECK-NEXT: ret i32 [[C]]
468 %A = icmp ne i32 %x, 1
469 call void @use2(i1 %A) ; thwart predicate canonicalization
471 %C = select i1 %A, i32 %y, i32 %B
476 define i32 @select_xor_icmp_bad_1(i32 %x, i32 %y, i32 %z, i32 %k) {
477 ; CHECK-LABEL: @select_xor_icmp_bad_1(
478 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]]
479 ; CHECK-NEXT: [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]
480 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
481 ; CHECK-NEXT: ret i32 [[C]]
483 %A = icmp eq i32 %x, %k
485 %C = select i1 %A, i32 %B, i32 %y
489 define i32 @select_xor_icmp_bad_2(i32 %x, i32 %y, i32 %z, i32 %k) {
490 ; CHECK-LABEL: @select_xor_icmp_bad_2(
491 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
492 ; CHECK-NEXT: [[B:%.*]] = xor i32 [[K:%.*]], [[Z:%.*]]
493 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
494 ; CHECK-NEXT: ret i32 [[C]]
496 %A = icmp eq i32 %x, 0
498 %C = select i1 %A, i32 %B, i32 %y
502 define i32 @select_xor_icmp_bad_3(i32 %x, i32 %y, i32 %z) {
503 ; CHECK-LABEL: @select_xor_icmp_bad_3(
504 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
505 ; CHECK-NEXT: [[B:%.*]] = xor i32 [[Z:%.*]], 3
506 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
507 ; CHECK-NEXT: ret i32 [[C]]
509 %A = icmp eq i32 %x, 3
511 %C = select i1 %A, i32 %B, i32 %y
515 define i32 @select_xor_fcmp_bad_4(i32 %x, i32 %y, i32 %z, float %k) {
516 ; CHECK-LABEL: @select_xor_fcmp_bad_4(
517 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[K:%.*]], 0.000000e+00
518 ; CHECK-NEXT: [[B:%.*]] = xor i32 [[X:%.*]], [[Z:%.*]]
519 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
520 ; CHECK-NEXT: ret i32 [[C]]
522 %A = fcmp oeq float %k, 0.0
524 %C = select i1 %A, i32 %B, i32 %y
528 define i32 @select_xor_icmp_bad_5(i32 %x, i32 %y, i32 %z) {
529 ; CHECK-LABEL: @select_xor_icmp_bad_5(
530 ; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0
531 ; CHECK-NEXT: [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]
532 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[Y:%.*]], i32 [[B]]
533 ; CHECK-NEXT: ret i32 [[C]]
535 %A = icmp ne i32 %x, 0
537 %C = select i1 %A, i32 %B, i32 %y
541 define i32 @select_xor_icmp_bad_6(i32 %x, i32 %y, i32 %z) {
542 ; CHECK-LABEL: @select_xor_icmp_bad_6(
543 ; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 1
544 ; CHECK-NEXT: [[B:%.*]] = xor i32 [[Z:%.*]], 1
545 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[B]], i32 [[Y:%.*]]
546 ; CHECK-NEXT: ret i32 [[C]]
548 %A = icmp ne i32 %x, 1
550 %C = select i1 %A, i32 %y, i32 %B
554 ; Value equivalence substitution is all-or-nothing, so needs a scalar compare.
556 define <2 x i8> @select_xor_icmp_vec_bad(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
557 ; CHECK-LABEL: @select_xor_icmp_vec_bad(
558 ; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 5, i8 3>
559 ; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> [[X]], [[Z:%.*]]
560 ; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]]
561 ; CHECK-NEXT: ret <2 x i8> [[C]]
563 %A = icmp eq <2 x i8> %x, <i8 5, i8 3>
564 %B = xor <2 x i8> %x, %z
565 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y
569 ; Value equivalence substitution is all-or-nothing, so needs a scalar compare.
571 define <2 x i32> @vec_select_no_equivalence(<2 x i32> %x) {
572 ; CHECK-LABEL: @vec_select_no_equivalence(
573 ; CHECK-NEXT: [[X10:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> undef, <2 x i32> <i32 1, i32 0>
574 ; CHECK-NEXT: [[COND:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer
575 ; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[X10]], <2 x i32> [[X]]
576 ; CHECK-NEXT: ret <2 x i32> [[S]]
578 %x10 = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> <i32 1, i32 0>
579 %cond = icmp eq <2 x i32> %x, zeroinitializer
580 %s = select <2 x i1> %cond, <2 x i32> %x10, <2 x i32> %x
584 ; Folding this would only be legal if we sanitized undef to 0.
585 define <2 x i8> @select_xor_icmp_vec_undef(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
586 ; CHECK-LABEL: @select_xor_icmp_vec_undef(
587 ; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 0, i8 undef>
588 ; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> [[X]], [[Z:%.*]]
589 ; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]]
590 ; CHECK-NEXT: ret <2 x i8> [[C]]
592 %A = icmp eq <2 x i8> %x, <i8 0, i8 undef>
593 %B = xor <2 x i8> %x, %z
594 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y
598 define i32 @select_mul_icmp_bad(i32 %x, i32 %y, i32 %z, i32 %k) {
599 ; CHECK-LABEL: @select_mul_icmp_bad(
600 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
601 ; CHECK-NEXT: [[B:%.*]] = mul i32 [[Z:%.*]], 3
602 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
603 ; CHECK-NEXT: ret i32 [[C]]
605 %A = icmp eq i32 %x, 3
607 %C = select i1 %A, i32 %B, i32 %y
611 define i32 @select_add_icmp_bad(i32 %x, i32 %y, i32 %z) {
612 ; CHECK-LABEL: @select_add_icmp_bad(
613 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
614 ; CHECK-NEXT: [[B:%.*]] = add i32 [[Z:%.*]], 1
615 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
616 ; CHECK-NEXT: ret i32 [[C]]
618 %A = icmp eq i32 %x, 1
620 %C = select i1 %A, i32 %B, i32 %y
624 define i32 @select_and_icmp_zero(i32 %x, i32 %y, i32 %z) {
625 ; CHECK-LABEL: @select_and_icmp_zero(
626 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
627 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 0, i32 [[Y:%.*]]
628 ; CHECK-NEXT: ret i32 [[C]]
630 %A = icmp eq i32 %x, 0
632 %C = select i1 %A, i32 %B, i32 %y
636 define i32 @select_or_icmp_bad(i32 %x, i32 %y, i32 %z) {
637 ; CHECK-LABEL: @select_or_icmp_bad(
638 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
639 ; CHECK-NEXT: [[B:%.*]] = or i32 [[Z:%.*]], 3
640 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
641 ; CHECK-NEXT: ret i32 [[C]]
643 %A = icmp eq i32 %x, 3
645 %C = select i1 %A, i32 %B, i32 %y
649 ; Invalid identity constant for FP op
650 define float @select_fadd_fcmp_bad(float %x, float %y, float %z) {
651 ; CHECK-LABEL: @select_fadd_fcmp_bad(
652 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], -1.000000e+00
653 ; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
654 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
655 ; CHECK-NEXT: ret float [[C]]
657 %A = fcmp oeq float %x, -1.0
658 %B = fadd nsz float %x, %z
659 %C = select i1 %A, float %B, float %y
663 ; Invalid comparison type
664 define float @select_fadd_fcmp_bad_2(float %x, float %y, float %z) {
665 ; CHECK-LABEL: @select_fadd_fcmp_bad_2(
666 ; CHECK-NEXT: [[A:%.*]] = fcmp ueq float [[X:%.*]], -1.000000e+00
667 ; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
668 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
669 ; CHECK-NEXT: ret float [[C]]
671 %A = fcmp ueq float %x, -1.0
672 %B = fadd float %x, %z
673 %C = select i1 %A, float %B, float %y
677 ; Invalid comparison type
678 define float @select_fadd_fcmp_bad_3(float %x, float %y, float %z, float %k) {
679 ; CHECK-LABEL: @select_fadd_fcmp_bad_3(
680 ; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], [[K:%.*]]
681 ; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
682 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
683 ; CHECK-NEXT: ret float [[C]]
685 %A = fcmp one float %x, %k
686 %B = fadd float %x, %z
687 %C = select i1 %A, float %y, float %B
691 ; Invalid order of operands of select
692 define float @select_fadd_fcmp_bad_4(float %x, float %y, float %z) {
693 ; CHECK-LABEL: @select_fadd_fcmp_bad_4(
694 ; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
695 ; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
696 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
697 ; CHECK-NEXT: ret float [[C]]
699 %A = fcmp une float %x, -0.0
700 %B = fadd float %x, %z
701 %C = select i1 %A, float %B, float %y
705 ; Invalid comparison type
706 define float @select_fadd_fcmp_bad_5(float %x, float %y, float %z) {
707 ; CHECK-LABEL: @select_fadd_fcmp_bad_5(
708 ; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
709 ; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
710 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
711 ; CHECK-NEXT: ret float [[C]]
713 %A = fcmp one float %x, -0.0
714 %B = fadd nsz float %z, %x
715 %C = select i1 %A, float %y, float %B
719 ; Invalid order of operands of select
720 define float @select_fadd_fcmp_bad_6(float %x, float %y, float %z) {
721 ; CHECK-LABEL: @select_fadd_fcmp_bad_6(
722 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
723 ; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
724 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
725 ; CHECK-NEXT: ret float [[C]]
727 %A = fcmp oeq float %x, -0.0
728 %B = fadd nsz float %z, %x
729 %C = select i1 %A, float %y, float %B
733 ; Do not transform if we have signed zeros and if Z is possibly negative zero
734 define float @select_fadd_fcmp_bad_7(float %x, float %y, float %z) {
735 ; CHECK-LABEL: @select_fadd_fcmp_bad_7(
736 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
737 ; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]]
738 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
739 ; CHECK-NEXT: ret float [[C]]
741 %A = fcmp oeq float %x, -0.0
742 %B = fadd float %x, %z
743 %C = select i1 %A, float %B, float %y
747 ; Invalid comparison type
748 define float @select_fadd_fcmp_bad_8(float %x, float %y, float %v) {
749 ; CHECK-LABEL: @select_fadd_fcmp_bad_8(
750 ; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
751 ; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00
752 ; CHECK-NEXT: [[B:%.*]] = fadd float [[Z]], [[X]]
753 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
754 ; CHECK-NEXT: ret float [[C]]
756 %A = fcmp one float %x, -0.0
757 %z = fadd float %v, -1.0
758 %B = fadd float %z, %x
759 %C = select i1 %A, float %y, float %B
763 ; Invalid comparison type
764 define float @select_fadd_fcmp_bad_9(float %x, float %y, float %z) {
765 ; CHECK-LABEL: @select_fadd_fcmp_bad_9(
766 ; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
767 ; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
768 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
769 ; CHECK-NEXT: ret float [[C]]
771 %A = fcmp one float %x, -0.0
772 %B = fadd nsz float %z, %x
773 %C = select i1 %A, float %y, float %B
777 ; Invalid comparison type
778 define float @select_fadd_fcmp_bad_10(float %x, float %y, float %v) {
779 ; CHECK-LABEL: @select_fadd_fcmp_bad_10(
780 ; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
781 ; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
782 ; CHECK-NEXT: [[B:%.*]] = fadd float [[Z]], [[X]]
783 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
784 ; CHECK-NEXT: ret float [[C]]
786 %A = fcmp one float %x, -0.0
787 %z = fadd float %v, 0.0 ; cannot produce -0.0
788 %B = fadd float %z, %x
789 %C = select i1 %A, float %y, float %B
793 ; Do not transform if Z is possibly negative zero
794 define float @select_fadd_fcmp_bad_11(float %x, float %y, float %v) {
795 ; CHECK-LABEL: @select_fadd_fcmp_bad_11(
796 ; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
797 ; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00
798 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
799 ; CHECK-NEXT: ret float [[C]]
801 %A = fcmp une float %x, -0.0
802 %z = fadd float %v, -1.0
803 %B = fadd nsz float %z, %x
804 %C = select i1 %A, float %y, float %B
808 ; Do not transform if we have signed zeros and if Z is possibly negative zero
809 define float @select_fadd_fcmp_bad_12(float %x, float %y, float %z) {
810 ; CHECK-LABEL: @select_fadd_fcmp_bad_12(
811 ; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
812 ; CHECK-NEXT: [[B:%.*]] = fadd float [[Z:%.*]], [[X]]
813 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
814 ; CHECK-NEXT: ret float [[C]]
816 %A = fcmp une float %x, -0.0
817 %B = fadd float %z, %x
818 %C = select i1 %A, float %y, float %B
822 ; Invalid order of operands of select
823 define float @select_fadd_fcmp_bad_13(float %x, float %y, float %z) {
824 ; CHECK-LABEL: @select_fadd_fcmp_bad_13(
825 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
826 ; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
827 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
828 ; CHECK-NEXT: ret float [[C]]
830 %A = fcmp oeq float %x, -0.0
831 %B = fadd nsz float %x, %z
832 %C = select i1 %A, float %y, float %B
836 ; Invalid identity constant for FP op
837 define float @select_fadd_fcmp_bad_14(float %x, float %y, float %z) {
838 ; CHECK-LABEL: @select_fadd_fcmp_bad_14(
839 ; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], -1.000000e+00
840 ; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
841 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
842 ; CHECK-NEXT: ret float [[C]]
844 %A = fcmp une float %x, -1.0
845 %B = fadd nsz float %x, %z
846 %C = select i1 %A, float %y, float %B
850 define float @select_fmul_fcmp_bad(float %x, float %y, float %z) {
851 ; CHECK-LABEL: @select_fmul_fcmp_bad(
852 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
853 ; CHECK-NEXT: [[B:%.*]] = fmul nsz float [[X]], [[Z:%.*]]
854 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
855 ; CHECK-NEXT: ret float [[C]]
857 %A = fcmp oeq float %x, 3.0
858 %B = fmul nsz float %x, %z
859 %C = select i1 %A, float %B, float %y
863 define float @select_fmul_fcmp_bad_2(float %x, float %y, float %z) {
864 ; CHECK-LABEL: @select_fmul_fcmp_bad_2(
865 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
866 ; CHECK-NEXT: [[B:%.*]] = fmul float [[X]], [[Z:%.*]]
867 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
868 ; CHECK-NEXT: ret float [[C]]
870 %A = fcmp oeq float %x, 1.0
871 %B = fmul float %x, %z
872 %C = select i1 %A, float %B, float %y
876 define float @select_fmul_icmp_bad(float %x, float %y, float %z, i32 %k) {
877 ; CHECK-LABEL: @select_fmul_icmp_bad(
878 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[K:%.*]], 0
879 ; CHECK-NEXT: [[B:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]
880 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
881 ; CHECK-NEXT: ret float [[C]]
883 %A = icmp eq i32 %k, 0
884 %B = fmul float %x, %z
885 %C = select i1 %A, float %B, float %y
889 define float @select_fmul_icmp_bad_2(float %x, float %y, float %z, i32 %k) {
890 ; CHECK-LABEL: @select_fmul_icmp_bad_2(
891 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[K:%.*]], 0
892 ; CHECK-NEXT: [[B:%.*]] = fmul nsz float [[X:%.*]], [[Z:%.*]]
893 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
894 ; CHECK-NEXT: ret float [[C]]
896 %A = icmp eq i32 %k, 0
897 %B = fmul nsz float %x, %z
898 %C = select i1 %A, float %B, float %y
902 define float @select_fdiv_fcmp_bad(float %x, float %y, float %z) {
903 ; CHECK-LABEL: @select_fdiv_fcmp_bad(
904 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
905 ; CHECK-NEXT: [[B:%.*]] = fdiv float [[X]], [[Z:%.*]]
906 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
907 ; CHECK-NEXT: ret float [[C]]
909 %A = fcmp oeq float %x, 1.0
910 %B = fdiv float %x, %z
911 %C = select i1 %A, float %B, float %y
915 define float @select_fdiv_fcmp_bad_2(float %x, float %y, float %z) {
916 ; CHECK-LABEL: @select_fdiv_fcmp_bad_2(
917 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
918 ; CHECK-NEXT: [[B:%.*]] = fdiv nsz float [[X]], [[Z:%.*]]
919 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
920 ; CHECK-NEXT: ret float [[C]]
922 %A = fcmp oeq float %x, 3.0
923 %B = fdiv nsz float %x, %z
924 %C = select i1 %A, float %B, float %y
928 ; The transform is not valid when x = -0.0 and z = -0.0
929 ; (optimized code would return -0.0, but this returns +0.0).
931 define float @select_fsub_fcmp_bad(float %x, float %y, float %z) {
932 ; CHECK-LABEL: @select_fsub_fcmp_bad(
933 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
934 ; CHECK-NEXT: [[B:%.*]] = fsub float [[Z:%.*]], [[X]]
935 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
936 ; CHECK-NEXT: ret float [[C]]
938 %A = fcmp oeq float %x, 0.0
939 %B = fsub float %z, %x
940 %C = select i1 %A, float %B, float %y
944 define float @select_fsub_fcmp_bad_2(float %x, float %y, float %z) {
945 ; CHECK-LABEL: @select_fsub_fcmp_bad_2(
946 ; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
947 ; CHECK-NEXT: [[B:%.*]] = fsub nsz float [[Z:%.*]], [[X]]
948 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
949 ; CHECK-NEXT: ret float [[C]]
951 %A = fcmp oeq float %x, 1.0
952 %B = fsub nsz float %z, %x
953 %C = select i1 %A, float %B, float %y
957 define i32 @select_sub_icmp_bad(i32 %x, i32 %y, i32 %z) {
958 ; CHECK-LABEL: @select_sub_icmp_bad(
959 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
960 ; CHECK-NEXT: [[B:%.*]] = sub i32 0, [[Z:%.*]]
961 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
962 ; CHECK-NEXT: ret i32 [[C]]
964 %A = icmp eq i32 %x, 0
966 %C = select i1 %A, i32 %B, i32 %y
970 define i32 @select_sub_icmp_bad_2(i32 %x, i32 %y, i32 %z) {
971 ; CHECK-LABEL: @select_sub_icmp_bad_2(
972 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
973 ; CHECK-NEXT: [[B:%.*]] = add i32 [[Z:%.*]], -1
974 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
975 ; CHECK-NEXT: ret i32 [[C]]
977 %A = icmp eq i32 %x, 1
979 %C = select i1 %A, i32 %B, i32 %y
983 define i32 @select_sub_icmp_bad_3(i32 %x, i32 %y, i32 %z) {
984 ; CHECK-LABEL: @select_sub_icmp_bad_3(
985 ; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
986 ; CHECK-NEXT: call void @use2(i1 [[A]])
987 ; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
988 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
989 ; CHECK-NEXT: ret i32 [[C]]
991 %A = icmp ne i32 %x, 0
992 call void @use2(i1 %A)
994 %C = select i1 %A, i32 %B, i32 %y
998 define i32 @select_sub_icmp_4(i32 %x, i32 %y, i32 %z) {
999 ; CHECK-LABEL: @select_sub_icmp_4(
1000 ; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
1001 ; CHECK-NEXT: call void @use2(i1 [[A]])
1002 ; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
1003 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1004 ; CHECK-NEXT: ret i32 [[C]]
1006 %A = icmp ne i32 %x, 0
1007 call void @use2(i1 %A)
1009 %C = select i1 %A, i32 %B, i32 %y
1013 define i32 @select_sub_icmp_bad_4(i32 %x, i32 %y, i32 %z, i32 %k) {
1014 ; CHECK-LABEL: @select_sub_icmp_bad_4(
1015 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
1016 ; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[K:%.*]]
1017 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1018 ; CHECK-NEXT: ret i32 [[C]]
1020 %A = icmp eq i32 %x, 0
1022 %C = select i1 %A, i32 %B, i32 %y
1026 define i32 @select_sub_icmp_bad_5(i32 %x, i32 %y, i32 %z, i32 %k) {
1027 ; CHECK-LABEL: @select_sub_icmp_bad_5(
1028 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]]
1029 ; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
1030 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1031 ; CHECK-NEXT: ret i32 [[C]]
1033 %A = icmp eq i32 %x, %k
1035 %C = select i1 %A, i32 %B, i32 %y
1039 define i32 @select_shl_icmp_bad(i32 %x, i32 %y, i32 %z) {
1040 ; CHECK-LABEL: @select_shl_icmp_bad(
1041 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1042 ; CHECK-NEXT: [[B:%.*]] = shl i32 [[Z:%.*]], 1
1043 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1044 ; CHECK-NEXT: ret i32 [[C]]
1046 %A = icmp eq i32 %x, 1
1048 %C = select i1 %A, i32 %B, i32 %y
1052 define i32 @select_lshr_icmp_bad(i32 %x, i32 %y, i32 %z) {
1053 ; CHECK-LABEL: @select_lshr_icmp_bad(
1054 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1055 ; CHECK-NEXT: [[B:%.*]] = lshr i32 [[Z:%.*]], 1
1056 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1057 ; CHECK-NEXT: ret i32 [[C]]
1059 %A = icmp eq i32 %x, 1
1060 %B = lshr i32 %z, %x
1061 %C = select i1 %A, i32 %B, i32 %y
1065 define i32 @select_ashr_icmp_bad(i32 %x, i32 %y, i32 %z) {
1066 ; CHECK-LABEL: @select_ashr_icmp_bad(
1067 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
1068 ; CHECK-NEXT: [[B:%.*]] = ashr i32 [[Z:%.*]], 1
1069 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1070 ; CHECK-NEXT: ret i32 [[C]]
1072 %A = icmp eq i32 %x, 1
1073 %B = ashr i32 %z, %x
1074 %C = select i1 %A, i32 %B, i32 %y
1078 define i32 @select_udiv_icmp_bad(i32 %x, i32 %y, i32 %z) {
1079 ; CHECK-LABEL: @select_udiv_icmp_bad(
1080 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
1081 ; CHECK-NEXT: [[B:%.*]] = udiv i32 [[Z:%.*]], [[X]]
1082 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1083 ; CHECK-NEXT: ret i32 [[C]]
1085 %A = icmp eq i32 %x, 3
1086 %B = udiv i32 %z, %x
1087 %C = select i1 %A, i32 %B, i32 %y
1091 define i32 @select_sdiv_icmp_bad(i32 %x, i32 %y, i32 %z) {
1092 ; CHECK-LABEL: @select_sdiv_icmp_bad(
1093 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3
1094 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 [[Z:%.*]], [[X]]
1095 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
1096 ; CHECK-NEXT: ret i32 [[C]]
1098 %A = icmp eq i32 %x, 3
1099 %B = sdiv i32 %z, %x
1100 %C = select i1 %A, i32 %B, i32 %y
1104 ; Can replace %x with 0, because sub is only used in the select.
1105 define i32 @select_replace_one_use(i32 %x, i32 %y) {
1106 ; CHECK-LABEL: @select_replace_one_use(
1107 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1108 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[Y:%.*]]
1109 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[SUB]], i32 [[Y]]
1110 ; CHECK-NEXT: ret i32 [[S]]
1112 %c = icmp eq i32 %x, 0
1113 %sub = sub i32 %x, %y
1114 %s = select i1 %c, i32 %sub, i32 %y
1118 ; Can not replace %x with 0, because %sub has other uses as well.
1119 define i32 @select_replace_multi_use(i32 %x, i32 %y) {
1120 ; CHECK-LABEL: @select_replace_multi_use(
1121 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1122 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y:%.*]]
1123 ; CHECK-NEXT: call void @use_i32(i32 [[SUB]])
1124 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[SUB]], i32 [[Y]]
1125 ; CHECK-NEXT: ret i32 [[S]]
1127 %c = icmp eq i32 %x, 0
1128 %sub = sub i32 %x, %y
1129 call void @use_i32(i32 %sub)
1130 %s = select i1 %c, i32 %sub, i32 %y
1134 ; Case where the replacement allows the instruction to fold away.
1135 define i32 @select_replace_fold(i32 %x, i32 %y, i32 %z) {
1136 ; CHECK-LABEL: @select_replace_fold(
1137 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1138 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 [[Y:%.*]]
1139 ; CHECK-NEXT: ret i32 [[S]]
1141 %c = icmp eq i32 %x, 0
1142 %fshr = call i32 @llvm.fshr.i32(i32 %y, i32 %z, i32 %x)
1143 %s = select i1 %c, i32 %fshr, i32 %y
1148 ; Case where the use of %x is in a nested instruction.
1149 ; FIXME: We only perform replacements one level up right now.
1150 define i32 @select_replace_nested(i32 %x, i32 %y, i32 %z) {
1151 ; CHECK-LABEL: @select_replace_nested(
1152 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1153 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y:%.*]], [[X]]
1154 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[Z:%.*]]
1155 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Y]]
1156 ; CHECK-NEXT: ret i32 [[S]]
1158 %c = icmp eq i32 %x, 0
1159 %sub = sub i32 %y, %x
1160 %add = add i32 %sub, %z
1161 %s = select i1 %c, i32 %add, i32 %y
1165 ; Do not replace with constant expressions. The profitability in this case is
1166 ; unclear, and such replacements have historically lead to infinite combine
1168 define i32 @select_replace_constexpr(i32 %x, i32 %y, i32 %z) {
1169 ; CHECK-LABEL: @select_replace_constexpr(
1170 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], ptrtoint (i32* @g to i32)
1171 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X]], [[Y:%.*]]
1172 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Z:%.*]]
1173 ; CHECK-NEXT: ret i32 [[S]]
1175 %c = icmp eq i32 %x, ptrtoint (i32* @g to i32)
1176 %add = add i32 %x, %y
1177 %s = select i1 %c, i32 %add, i32 %z
1181 ; Don't replace with a potentially undef constant, as undef could evaluate
1182 ; to different values for both uses.
1183 define <2 x i32> @select_replace_undef(<2 x i32> %x, <2 x i32> %y) {
1184 ; CHECK-LABEL: @select_replace_undef(
1185 ; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 0, i32 undef>
1186 ; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> [[X]], [[Y:%.*]]
1187 ; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[C]], <2 x i32> [[SUB]], <2 x i32> [[Y]]
1188 ; CHECK-NEXT: ret <2 x i32> [[S]]
1190 %c = icmp eq <2 x i32> %x, <i32 0, i32 undef>
1191 %sub = sub <2 x i32> %x, %y
1192 %s = select <2 x i1> %c, <2 x i32> %sub, <2 x i32> %y
1196 ; We can replace the call arguments, as the call is speculatable.
1197 define i32 @select_replace_call_speculatable(i32 %x, i32 %y) {
1198 ; CHECK-LABEL: @select_replace_call_speculatable(
1199 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1200 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @call_speculatable(i32 0, i32 0)
1201 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y:%.*]]
1202 ; CHECK-NEXT: ret i32 [[S]]
1204 %c = icmp eq i32 %x, 0
1205 %call = call i32 @call_speculatable(i32 %x, i32 %x)
1206 %s = select i1 %c, i32 %call, i32 %y
1210 ; We can't replace the call arguments, as the call is not speculatable. We
1211 ; may end up changing side-effects or causing undefined behavior.
1212 define i32 @select_replace_call_non_speculatable(i32 %x, i32 %y) {
1213 ; CHECK-LABEL: @select_replace_call_non_speculatable(
1214 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
1215 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @call_non_speculatable(i32 [[X]], i32 [[X]])
1216 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y:%.*]]
1217 ; CHECK-NEXT: ret i32 [[S]]
1219 %c = icmp eq i32 %x, 0
1220 %call = call i32 @call_non_speculatable(i32 %x, i32 %x)
1221 %s = select i1 %c, i32 %call, i32 %y
1225 ; We can replace %x by 2 here, because division by two cannot cause UB.
1226 ; FIXME: As we check speculation prior to replacement, we don't catch this.
1227 define i32 @select_replace_sdiv_speculatable(i32 %x, i32 %y) {
1228 ; CHECK-LABEL: @select_replace_sdiv_speculatable(
1229 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 2
1230 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[Y:%.*]], [[X]]
1231 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]]
1232 ; CHECK-NEXT: ret i32 [[S]]
1234 %c = icmp eq i32 %x, 2
1235 %div = sdiv i32 %y, %x
1236 %s = select i1 %c, i32 %div, i32 %y
1240 ; We cannot replace %x by -1, because division by -1 can cause UB.
1241 define i32 @select_replace_sdiv_non_speculatable(i32 %x, i32 %y) {
1242 ; CHECK-LABEL: @select_replace_sdiv_non_speculatable(
1243 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], -1
1244 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[Y:%.*]], [[X]]
1245 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]]
1246 ; CHECK-NEXT: ret i32 [[S]]
1248 %c = icmp eq i32 %x, -1
1249 %div = sdiv i32 %y, %x
1250 %s = select i1 %c, i32 %div, i32 %y
1254 ; We can replace %x by 2 here, because division by two cannot cause UB.
1255 ; FIXME: As we check speculation prior to replacement, we don't catch this.
1256 define i32 @select_replace_udiv_speculatable(i32 %x, i32 %y) {
1257 ; CHECK-LABEL: @select_replace_udiv_speculatable(
1258 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 2
1259 ; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[Y:%.*]], [[X]]
1260 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]]
1261 ; CHECK-NEXT: ret i32 [[S]]
1263 %c = icmp eq i32 %x, 2
1264 %div = udiv i32 %y, %x
1265 %s = select i1 %c, i32 %div, i32 %y
1269 ; We can't replace %x by 0 here, because that would cause UB. However,
1270 ; replacing the udiv result by poison is fine.
1271 define i32 @select_replace_udiv_non_speculatable(i32 %x, i32 %y) {
1272 ; CHECK-LABEL: @select_replace_udiv_non_speculatable(
1273 ; CHECK-NEXT: ret i32 [[Y:%.*]]
1275 %c = icmp eq i32 %x, 0
1276 %div = udiv i32 %y, %x
1277 %s = select i1 %c, i32 %div, i32 %y
1281 ; We can't replace %i in the phi node here, because it refers to %i from
1282 ; the previous loop iteration, not the current one.
1283 define void @select_replace_phi(i32 %x) {
1284 ; CHECK-LABEL: @select_replace_phi(
1285 ; CHECK-NEXT: entry:
1286 ; CHECK-NEXT: br label [[LOOP:%.*]]
1288 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
1289 ; CHECK-NEXT: [[I_PREV:%.*]] = phi i32 [ -1, [[ENTRY]] ], [ [[I]], [[LOOP]] ]
1290 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
1291 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[I]], 0
1292 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[I_PREV]], i32 2
1293 ; CHECK-NEXT: call void @use_i32(i32 [[S]])
1294 ; CHECK-NEXT: br label [[LOOP]]
1300 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
1301 %i.prev = phi i32 [ -1, %entry], [ %i, %loop ]
1302 %i.next = add i32 %i, 1
1303 %c = icmp eq i32 %i, 0
1304 %s = select i1 %c, i32 %i.prev, i32 2
1305 call void @use_i32(i32 %s)
1310 declare i32 @llvm.fshr.i32(i32, i32, i32)
1311 declare i32 @call_speculatable(i32, i32) speculatable
1312 declare i32 @call_non_speculatable(i32, i32)
1313 declare void @use_i32(i32)
1315 !0 = !{!"branch_weights", i32 2, i32 10}