1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
6 target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64"
8 define i1 @test5(i1 %C) {
10 ; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
11 ; CHECK-NEXT: ret i1 [[NOT_C]]
13 %V = select i1 %C, i1 false, i1 true
17 define i32 @test6(i1 %C) {
18 ; CHECK-LABEL: @test6(
19 ; CHECK-NEXT: [[V:%.*]] = zext i1 [[C:%.*]] to i32
20 ; CHECK-NEXT: ret i32 [[V]]
22 %V = select i1 %C, i32 1, i32 0
26 define i1 @trueval_is_true(i1 %C, i1 %X) {
27 ; CHECK-LABEL: @trueval_is_true(
28 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[X:%.*]]
29 ; CHECK-NEXT: ret i1 [[R]]
31 %R = select i1 %C, i1 true, i1 %X
35 define <2 x i1> @trueval_is_true_vec(<2 x i1> %C, <2 x i1> %X) {
36 ; CHECK-LABEL: @trueval_is_true_vec(
37 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[X:%.*]]
38 ; CHECK-NEXT: ret <2 x i1> [[R]]
40 %R = select <2 x i1> %C, <2 x i1> <i1 true, i1 true>, <2 x i1> %X
44 define <2 x i1> @trueval_is_true_vec_poison_elt(<2 x i1> %C, <2 x i1> %X) {
45 ; CHECK-LABEL: @trueval_is_true_vec_poison_elt(
46 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 poison, i1 true>, <2 x i1> [[X:%.*]]
47 ; CHECK-NEXT: ret <2 x i1> [[R]]
49 %R = select <2 x i1> %C, <2 x i1> <i1 poison, i1 true>, <2 x i1> %X
53 define i1 @test8(i1 %C, i1 %X) {
54 ; CHECK-LABEL: @test8(
55 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 false
56 ; CHECK-NEXT: ret i1 [[R]]
58 %R = select i1 %C, i1 %X, i1 false
62 define <2 x i1> @test8vec(<2 x i1> %C, <2 x i1> %X) {
63 ; CHECK-LABEL: @test8vec(
64 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]], <2 x i1> zeroinitializer
65 ; CHECK-NEXT: ret <2 x i1> [[R]]
67 %R = select <2 x i1> %C, <2 x i1> %X, <2 x i1> <i1 false, i1 false>
71 define <vscale x 2 x i1> @test8vvec(<vscale x 2 x i1> %C, <vscale x 2 x i1> %X) {
72 ; CHECK-LABEL: @test8vvec(
73 ; CHECK-NEXT: [[R:%.*]] = select <vscale x 2 x i1> [[C:%.*]], <vscale x 2 x i1> [[X:%.*]], <vscale x 2 x i1> zeroinitializer
74 ; CHECK-NEXT: ret <vscale x 2 x i1> [[R]]
76 %R = select <vscale x 2 x i1> %C, <vscale x 2 x i1> %X, <vscale x 2 x i1> zeroinitializer
77 ret <vscale x 2 x i1> %R
80 define i1 @test9(i1 %C, i1 %X) {
81 ; CHECK-LABEL: @test9(
82 ; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
83 ; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_C]], i1 [[X:%.*]], i1 false
84 ; CHECK-NEXT: ret i1 [[R]]
86 %R = select i1 %C, i1 false, i1 %X
90 define <2 x i1> @test9vec(<2 x i1> %C, <2 x i1> %X) {
91 ; CHECK-LABEL: @test9vec(
92 ; CHECK-NEXT: [[NOT_C:%.*]] = xor <2 x i1> [[C:%.*]], splat (i1 true)
93 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT_C]], <2 x i1> [[X:%.*]], <2 x i1> zeroinitializer
94 ; CHECK-NEXT: ret <2 x i1> [[R]]
96 %R = select <2 x i1> %C, <2 x i1> <i1 false, i1 false>, <2 x i1> %X
100 define <vscale x 2 x i1> @test9vvec(<vscale x 2 x i1> %C, <vscale x 2 x i1> %X) {
101 ; CHECK-LABEL: @test9vvec(
102 ; CHECK-NEXT: [[NOT_C:%.*]] = xor <vscale x 2 x i1> [[C:%.*]], splat (i1 true)
103 ; CHECK-NEXT: [[R:%.*]] = select <vscale x 2 x i1> [[NOT_C]], <vscale x 2 x i1> [[X:%.*]], <vscale x 2 x i1> zeroinitializer
104 ; CHECK-NEXT: ret <vscale x 2 x i1> [[R]]
106 %R = select <vscale x 2 x i1> %C, <vscale x 2 x i1> zeroinitializer, <vscale x 2 x i1> %X
107 ret <vscale x 2 x i1> %R
110 define i1 @test10(i1 %C, i1 %X) {
111 ; CHECK-LABEL: @test10(
112 ; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
113 ; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[X:%.*]]
114 ; CHECK-NEXT: ret i1 [[R]]
116 %R = select i1 %C, i1 %X, i1 true
120 define <2 x i1> @test10vec(<2 x i1> %C, <2 x i1> %X) {
121 ; CHECK-LABEL: @test10vec(
122 ; CHECK-NEXT: [[NOT_C:%.*]] = xor <2 x i1> [[C:%.*]], splat (i1 true)
123 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT_C]], <2 x i1> splat (i1 true), <2 x i1> [[X:%.*]]
124 ; CHECK-NEXT: ret <2 x i1> [[R]]
126 %R = select <2 x i1> %C, <2 x i1> %X, <2 x i1> <i1 true, i1 true>
130 define i1 @test23(i1 %a, i1 %b) {
131 ; CHECK-LABEL: @test23(
132 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
133 ; CHECK-NEXT: ret i1 [[C]]
135 %c = select i1 %a, i1 %b, i1 %a
139 define <2 x i1> @test23vec(<2 x i1> %a, <2 x i1> %b) {
140 ; CHECK-LABEL: @test23vec(
141 ; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
142 ; CHECK-NEXT: ret <2 x i1> [[C]]
144 %c = select <2 x i1> %a, <2 x i1> %b, <2 x i1> %a
148 define i1 @test24(i1 %a, i1 %b) {
149 ; CHECK-LABEL: @test24(
150 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
151 ; CHECK-NEXT: ret i1 [[C]]
153 %c = select i1 %a, i1 %a, i1 %b
157 define <2 x i1> @test24vec(<2 x i1> %a, <2 x i1> %b) {
158 ; CHECK-LABEL: @test24vec(
159 ; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]]
160 ; CHECK-NEXT: ret <2 x i1> [[C]]
162 %c = select <2 x i1> %a, <2 x i1> %a, <2 x i1> %b
166 define i1 @test62(i1 %A, i1 %B) {
167 ; CHECK-LABEL: @test62(
168 ; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
169 ; CHECK-NEXT: [[C:%.*]] = select i1 [[NOT_A]], i1 [[B:%.*]], i1 false
170 ; CHECK-NEXT: ret i1 [[C]]
172 %not = xor i1 %A, true
173 %C = select i1 %A, i1 %not, i1 %B
177 define <2 x i1> @test62vec(<2 x i1> %A, <2 x i1> %B) {
178 ; CHECK-LABEL: @test62vec(
179 ; CHECK-NEXT: [[NOT_A:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true)
180 ; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[NOT_A]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
181 ; CHECK-NEXT: ret <2 x i1> [[C]]
183 %not = xor <2 x i1> %A, <i1 true, i1 true>
184 %C = select <2 x i1> %A, <2 x i1> %not, <2 x i1> %B
188 define i1 @test63(i1 %A, i1 %B) {
189 ; CHECK-LABEL: @test63(
190 ; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
191 ; CHECK-NEXT: [[C:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[B:%.*]]
192 ; CHECK-NEXT: ret i1 [[C]]
194 %not = xor i1 %A, true
195 %C = select i1 %A, i1 %B, i1 %not
199 define <2 x i1> @test63vec(<2 x i1> %A, <2 x i1> %B) {
200 ; CHECK-LABEL: @test63vec(
201 ; CHECK-NEXT: [[NOT_A:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true)
202 ; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[NOT_A]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]]
203 ; CHECK-NEXT: ret <2 x i1> [[C]]
205 %not = xor <2 x i1> %A, <i1 true, i1 true>
206 %C = select <2 x i1> %A, <2 x i1> %B, <2 x i1> %not
210 define i32 @test11(i32 %a) {
211 ; CHECK-LABEL: @test11(
212 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
213 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[C]] to i32
214 ; CHECK-NEXT: ret i32 [[R]]
216 %C = icmp eq i32 %a, 0
217 %R = select i1 %C, i32 0, i32 1
221 define i32 @test12(i1 %cond, i32 %a) {
222 ; CHECK-LABEL: @test12(
223 ; CHECK-NEXT: [[B:%.*]] = zext i1 [[COND:%.*]] to i32
224 ; CHECK-NEXT: [[C:%.*]] = or i32 [[A:%.*]], [[B]]
225 ; CHECK-NEXT: ret i32 [[C]]
228 %c = select i1 %cond, i32 %b, i32 %a
232 define <2 x i32> @test12vec(<2 x i1> %cond, <2 x i32> %a) {
233 ; CHECK-LABEL: @test12vec(
234 ; CHECK-NEXT: [[B:%.*]] = zext <2 x i1> [[COND:%.*]] to <2 x i32>
235 ; CHECK-NEXT: [[C:%.*]] = or <2 x i32> [[A:%.*]], [[B]]
236 ; CHECK-NEXT: ret <2 x i32> [[C]]
238 %b = or <2 x i32> %a, <i32 1, i32 1>
239 %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %a
243 define i32 @test12a(i1 %cond, i32 %a) {
244 ; CHECK-LABEL: @test12a(
245 ; CHECK-NEXT: [[B:%.*]] = zext i1 [[COND:%.*]] to i32
246 ; CHECK-NEXT: [[C:%.*]] = ashr i32 [[A:%.*]], [[B]]
247 ; CHECK-NEXT: ret i32 [[C]]
250 %c = select i1 %cond, i32 %b, i32 %a
254 define <2 x i32> @test12avec(<2 x i1> %cond, <2 x i32> %a) {
255 ; CHECK-LABEL: @test12avec(
256 ; CHECK-NEXT: [[B:%.*]] = zext <2 x i1> [[COND:%.*]] to <2 x i32>
257 ; CHECK-NEXT: [[C:%.*]] = ashr <2 x i32> [[A:%.*]], [[B]]
258 ; CHECK-NEXT: ret <2 x i32> [[C]]
260 %b = ashr <2 x i32> %a, <i32 1, i32 1>
261 %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %a
265 define i32 @test12b(i1 %cond, i32 %a) {
266 ; CHECK-LABEL: @test12b(
267 ; CHECK-NEXT: [[NOT_COND:%.*]] = xor i1 [[COND:%.*]], true
268 ; CHECK-NEXT: [[B:%.*]] = zext i1 [[NOT_COND]] to i32
269 ; CHECK-NEXT: [[D:%.*]] = ashr i32 [[A:%.*]], [[B]]
270 ; CHECK-NEXT: ret i32 [[D]]
273 %d = select i1 %cond, i32 %a, i32 %b
277 define <2 x i32> @test12bvec(<2 x i1> %cond, <2 x i32> %a) {
278 ; CHECK-LABEL: @test12bvec(
279 ; CHECK-NEXT: [[NOT_COND:%.*]] = xor <2 x i1> [[COND:%.*]], splat (i1 true)
280 ; CHECK-NEXT: [[B:%.*]] = zext <2 x i1> [[NOT_COND]] to <2 x i32>
281 ; CHECK-NEXT: [[D:%.*]] = ashr <2 x i32> [[A:%.*]], [[B]]
282 ; CHECK-NEXT: ret <2 x i32> [[D]]
284 %b = ashr <2 x i32> %a, <i32 1, i32 1>
285 %d = select <2 x i1> %cond, <2 x i32> %a, <2 x i32> %b
289 define i32 @test13(i32 %a, i32 %b) {
290 ; CHECK-LABEL: @test13(
291 ; CHECK-NEXT: ret i32 [[B:%.*]]
293 %C = icmp eq i32 %a, %b
294 %V = select i1 %C, i32 %a, i32 %b
298 define i32 @test13a(i32 %a, i32 %b) {
299 ; CHECK-LABEL: @test13a(
300 ; CHECK-NEXT: ret i32 [[A:%.*]]
302 %C = icmp ne i32 %a, %b
303 %V = select i1 %C, i32 %a, i32 %b
307 define i32 @test13b(i32 %a, i32 %b) {
308 ; CHECK-LABEL: @test13b(
309 ; CHECK-NEXT: ret i32 [[A:%.*]]
311 %C = icmp eq i32 %a, %b
312 %V = select i1 %C, i32 %b, i32 %a
316 define i1 @test14a(i1 %C, i32 %X) {
317 ; CHECK-LABEL: @test14a(
318 ; CHECK-NEXT: [[R1:%.*]] = icmp slt i32 [[X:%.*]], 1
319 ; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
320 ; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[R1]]
321 ; CHECK-NEXT: ret i1 [[R]]
323 %V = select i1 %C, i32 %X, i32 0
325 %R = icmp slt i32 %V, 1
329 define i1 @test14b(i1 %C, i32 %X) {
330 ; CHECK-LABEL: @test14b(
331 ; CHECK-NEXT: [[R1:%.*]] = icmp slt i32 [[X:%.*]], 1
332 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[R1]]
333 ; CHECK-NEXT: ret i1 [[R]]
335 %V = select i1 %C, i32 0, i32 %X
337 %R = icmp slt i32 %V, 1
341 define i32 @test16(i1 %C, ptr %P) {
342 ; CHECK-LABEL: @test16(
343 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
344 ; CHECK-NEXT: ret i32 [[V]]
346 %P2 = select i1 %C, ptr %P, ptr null
347 %V = load i32, ptr %P2
351 ;; It may be legal to load from a null address in a non-zero address space
352 define i32 @test16_neg(i1 %C, ptr addrspace(1) %P) {
353 ; CHECK-LABEL: @test16_neg(
354 ; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], ptr addrspace(1) [[P:%.*]], ptr addrspace(1) null
355 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr addrspace(1) [[P2]], align 4
356 ; CHECK-NEXT: ret i32 [[V]]
358 %P2 = select i1 %C, ptr addrspace(1) %P, ptr addrspace(1) null
359 %V = load i32, ptr addrspace(1) %P2
363 define i32 @test16_neg2(i1 %C, ptr addrspace(1) %P) {
364 ; CHECK-LABEL: @test16_neg2(
365 ; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], ptr addrspace(1) null, ptr addrspace(1) [[P:%.*]]
366 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr addrspace(1) [[P2]], align 4
367 ; CHECK-NEXT: ret i32 [[V]]
369 %P2 = select i1 %C, ptr addrspace(1) null, ptr addrspace(1) %P
370 %V = load i32, ptr addrspace(1) %P2
374 ;; It may be legal to load from a null address with null pointer valid attribute.
375 define i32 @test16_no_null_opt(i1 %C, ptr %P) #0 {
376 ; CHECK-LABEL: @test16_no_null_opt(
377 ; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], ptr [[P:%.*]], ptr null
378 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P2]], align 4
379 ; CHECK-NEXT: ret i32 [[V]]
381 %P2 = select i1 %C, ptr %P, ptr null
382 %V = load i32, ptr %P2
386 define i32 @test16_no_null_opt_2(i1 %C, ptr %P) #0 {
387 ; CHECK-LABEL: @test16_no_null_opt_2(
388 ; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], ptr null, ptr [[P:%.*]]
389 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P2]], align 4
390 ; CHECK-NEXT: ret i32 [[V]]
392 %P2 = select i1 %C, ptr null, ptr %P
393 %V = load i32, ptr %P2
397 attributes #0 = { null_pointer_is_valid }
399 define i1 @test17(ptr %X, i1 %C) {
400 ; CHECK-LABEL: @test17(
401 ; CHECK-NEXT: [[RV1:%.*]] = icmp eq ptr [[X:%.*]], null
402 ; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
403 ; CHECK-NEXT: [[RV:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[RV1]]
404 ; CHECK-NEXT: ret i1 [[RV]]
406 %R = select i1 %C, ptr %X, ptr null
407 %RV = icmp eq ptr %R, null
411 define i32 @test18(i32 %X, i32 %Y, i1 %C) {
412 ; CHECK-LABEL: @test18(
413 ; CHECK-NEXT: [[V:%.*]] = sdiv i32 [[Y:%.*]], [[X:%.*]]
414 ; CHECK-NEXT: ret i32 [[V]]
416 %R = select i1 %C, i32 %X, i32 0
421 define i32 @test19(i32 %x) {
422 ; CHECK-LABEL: @test19(
423 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
424 ; CHECK-NEXT: ret i32 [[X_LOBIT]]
426 %t = icmp ugt i32 %x, 2147483647
427 %retval = select i1 %t, i32 -1, i32 0
431 define i32 @test20(i32 %x) {
432 ; CHECK-LABEL: @test20(
433 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
434 ; CHECK-NEXT: ret i32 [[X_LOBIT]]
436 %t = icmp slt i32 %x, 0
437 %retval = select i1 %t, i32 -1, i32 0
441 define i64 @test21(i32 %x) {
442 ; CHECK-LABEL: @test21(
443 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
444 ; CHECK-NEXT: [[RETVAL:%.*]] = sext i32 [[X_LOBIT]] to i64
445 ; CHECK-NEXT: ret i64 [[RETVAL]]
447 %t = icmp slt i32 %x, 0
448 %retval = select i1 %t, i64 -1, i64 0
452 define i16 @test22(i32 %x) {
453 ; CHECK-LABEL: @test22(
454 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
455 ; CHECK-NEXT: [[RETVAL:%.*]] = trunc nsw i32 [[X_LOBIT]] to i16
456 ; CHECK-NEXT: ret i16 [[RETVAL]]
458 %t = icmp slt i32 %x, 0
459 %retval = select i1 %t, i16 -1, i16 0
463 define i32 @test25(i1 %c) {
464 ; CHECK-LABEL: @test25(
466 ; CHECK-NEXT: br i1 [[C:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
468 ; CHECK-NEXT: br label [[RET]]
470 ; CHECK-NEXT: [[B:%.*]] = phi i32 [ 10, [[JUMP]] ], [ 20, [[ENTRY:%.*]] ]
471 ; CHECK-NEXT: ret i32 [[B]]
474 br i1 %c, label %jump, label %ret
478 %a = phi i1 [true, %jump], [false, %entry]
479 %b = select i1 %a, i32 10, i32 20
483 define i32 @test26(i1 %cond) {
484 ; CHECK-LABEL: @test26(
486 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
488 ; CHECK-NEXT: br label [[RET]]
490 ; CHECK-NEXT: [[B:%.*]] = phi i32 [ 20, [[ENTRY:%.*]] ], [ 10, [[JUMP]] ]
491 ; CHECK-NEXT: ret i32 [[B]]
494 br i1 %cond, label %jump, label %ret
496 %c = or i1 false, false
499 %a = phi i1 [true, %entry], [%c, %jump]
500 %b = select i1 %a, i32 20, i32 10
504 define i32 @test26_logical(i1 %cond) {
505 ; CHECK-LABEL: @test26_logical(
507 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
509 ; CHECK-NEXT: br label [[RET]]
511 ; CHECK-NEXT: [[B:%.*]] = phi i32 [ 20, [[ENTRY:%.*]] ], [ 10, [[JUMP]] ]
512 ; CHECK-NEXT: ret i32 [[B]]
515 br i1 %cond, label %jump, label %ret
517 %c = select i1 false, i1 true, i1 false
520 %a = phi i1 [true, %entry], [%c, %jump]
521 %b = select i1 %a, i32 20, i32 10
525 define i32 @test27(i1 %c, i32 %A, i32 %B) {
526 ; CHECK-LABEL: @test27(
528 ; CHECK-NEXT: br i1 [[C:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
530 ; CHECK-NEXT: br label [[RET]]
532 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
533 ; CHECK-NEXT: ret i32 [[S]]
536 br i1 %c, label %jump, label %ret
540 %p = phi i1 [true, %jump], [false, %entry]
541 %s = select i1 %p, i32 %A, i32 %B
545 define i32 @test28(i1 %cond, i32 %A, i32 %B) {
546 ; CHECK-LABEL: @test28(
548 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
550 ; CHECK-NEXT: br label [[RET]]
552 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
553 ; CHECK-NEXT: ret i32 [[S]]
556 br i1 %cond, label %jump, label %ret
560 %c = phi i32 [%A, %jump], [%B, %entry]
561 %p = phi i1 [true, %jump], [false, %entry]
562 %s = select i1 %p, i32 %A, i32 %c
566 define i32 @test29(i1 %cond, i32 %A, i32 %B) {
567 ; CHECK-LABEL: @test29(
569 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
571 ; CHECK-NEXT: br label [[RET]]
573 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
574 ; CHECK-NEXT: br label [[NEXT:%.*]]
576 ; CHECK-NEXT: ret i32 [[S]]
579 br i1 %cond, label %jump, label %ret
583 %c = phi i32 [%A, %jump], [%B, %entry]
584 %p = phi i1 [true, %jump], [false, %entry]
588 %s = select i1 %p, i32 %A, i32 %c
592 ; SMAX(SMAX(x, y), x) -> SMAX(x, y)
593 define i32 @test30(i32 %x, i32 %y) {
594 ; CHECK-LABEL: @test30(
595 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
596 ; CHECK-NEXT: ret i32 [[COND]]
598 %cmp = icmp sgt i32 %x, %y
599 %cond = select i1 %cmp, i32 %x, i32 %y
600 %cmp5 = icmp sgt i32 %cond, %x
601 %retval = select i1 %cmp5, i32 %cond, i32 %x
605 ; UMAX(UMAX(x, y), x) -> UMAX(x, y)
606 define i32 @test31(i32 %x, i32 %y) {
607 ; CHECK-LABEL: @test31(
608 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
609 ; CHECK-NEXT: ret i32 [[COND]]
611 %cmp = icmp ugt i32 %x, %y
612 %cond = select i1 %cmp, i32 %x, i32 %y
613 %cmp5 = icmp ugt i32 %cond, %x
614 %retval = select i1 %cmp5, i32 %cond, i32 %x
618 ; SMIN(SMIN(x, y), x) -> SMIN(x, y)
619 define i32 @test32(i32 %x, i32 %y) {
620 ; CHECK-LABEL: @test32(
621 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
622 ; CHECK-NEXT: ret i32 [[COND]]
624 %cmp = icmp sgt i32 %x, %y
625 %cond = select i1 %cmp, i32 %y, i32 %x
626 %cmp5 = icmp sgt i32 %cond, %x
627 %retval = select i1 %cmp5, i32 %x, i32 %cond
631 ; MAX(MIN(x, y), x) -> x
632 define i32 @test33(i32 %x, i32 %y) {
633 ; CHECK-LABEL: @test33(
634 ; CHECK-NEXT: ret i32 [[X:%.*]]
636 %cmp = icmp sgt i32 %x, %y
637 %cond = select i1 %cmp, i32 %y, i32 %x
638 %cmp5 = icmp sgt i32 %cond, %x
639 %retval = select i1 %cmp5, i32 %cond, i32 %x
643 ; MIN(MAX(x, y), x) -> x
644 define i32 @test34(i32 %x, i32 %y) {
645 ; CHECK-LABEL: @test34(
646 ; CHECK-NEXT: ret i32 [[X:%.*]]
648 %cmp = icmp sgt i32 %x, %y
649 %cond = select i1 %cmp, i32 %x, i32 %y
650 %cmp5 = icmp sgt i32 %cond, %x
651 %retval = select i1 %cmp5, i32 %x, i32 %cond
655 define i1 @test38(i1 %cond) {
656 ; CHECK-LABEL: @test38(
657 ; CHECK-NEXT: ret i1 false
661 %ptr = select i1 %cond, ptr %zero, ptr %one
662 %isnull = icmp eq ptr %ptr, null
666 define i1 @test39(i1 %cond, double %x) {
667 ; CHECK-LABEL: @test39(
668 ; CHECK-NEXT: ret i1 true
670 %s = select i1 %cond, double %x, double 0x7FF0000000000000 ; RHS = +infty
671 %cmp = fcmp ule double %x, %s
675 define i1 @test40(i1 %cond) {
676 ; CHECK-LABEL: @test40(
677 ; CHECK-NEXT: ret i1 false
682 %s = select i1 %cond, ptr %a, ptr %b
683 %r = icmp eq ptr %s, %c
687 define i32 @test41(i1 %cond, i32 %x, i32 %y) {
688 ; CHECK-LABEL: @test41(
689 ; CHECK-NEXT: [[R:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
690 ; CHECK-NEXT: ret i32 [[R]]
693 %s = select i1 %cond, i32 %y, i32 %z
698 define i32 @test42(i32 %x, i32 %y) {
699 ; CHECK-LABEL: @test42(
700 ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[X:%.*]], 0
701 ; CHECK-NEXT: [[B:%.*]] = sext i1 [[COND]] to i32
702 ; CHECK-NEXT: [[C:%.*]] = add i32 [[Y:%.*]], [[B]]
703 ; CHECK-NEXT: ret i32 [[C]]
706 %cond = icmp eq i32 %x, 0
707 %c = select i1 %cond, i32 %b, i32 %y
711 define <2 x i32> @test42vec(<2 x i32> %x, <2 x i32> %y) {
712 ; CHECK-LABEL: @test42vec(
713 ; CHECK-NEXT: [[COND:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer
714 ; CHECK-NEXT: [[B:%.*]] = sext <2 x i1> [[COND]] to <2 x i32>
715 ; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[Y:%.*]], [[B]]
716 ; CHECK-NEXT: ret <2 x i32> [[C]]
718 %b = add <2 x i32> %y, <i32 -1, i32 -1>
719 %cond = icmp eq <2 x i32> %x, zeroinitializer
720 %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %y
726 ; This select instruction can't be eliminated because trying to do so would
727 ; change the number of vector elements. This used to assert.
728 define i48 @test51(<3 x i1> %icmp, <3 x i16> %t) {
729 ; CHECK-LABEL: @test51(
730 ; CHECK-NEXT: [[SELECT:%.*]] = select <3 x i1> [[ICMP:%.*]], <3 x i16> zeroinitializer, <3 x i16> [[T:%.*]]
731 ; CHECK-NEXT: [[T2:%.*]] = bitcast <3 x i16> [[SELECT]] to i48
732 ; CHECK-NEXT: ret i48 [[T2]]
734 %select = select <3 x i1> %icmp, <3 x i16> zeroinitializer, <3 x i16> %t
735 %t2 = bitcast <3 x i16> %select to i48
739 define <vscale x 4 x float> @bitcast_select_bitcast(<vscale x 4 x i1> %icmp, <vscale x 4 x i32> %a, <vscale x 4 x float> %b) {
740 ; CHECK-LABEL: @bitcast_select_bitcast(
741 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x i32> [[A:%.*]] to <vscale x 4 x float>
742 ; CHECK-NEXT: [[BC2:%.*]] = select <vscale x 4 x i1> [[ICMP:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> [[TMP1]]
743 ; CHECK-NEXT: ret <vscale x 4 x float> [[BC2]]
745 %bc1 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32>
746 %select = select <vscale x 4 x i1> %icmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %a
747 %bc2 = bitcast <vscale x 4 x i32> %select to <vscale x 4 x float>
748 ret <vscale x 4 x float> %bc2
751 define void @select_oneuse_bitcast(<vscale x 4 x float> %a, <vscale x 4 x float> %b, <vscale x 4 x i32> %c, <vscale x 4 x i32> %d, ptr %ptr1) {
752 ; CHECK-LABEL: @select_oneuse_bitcast(
753 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <vscale x 4 x i32> [[C:%.*]], [[D:%.*]]
754 ; CHECK-NEXT: [[SEL1_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[A:%.*]], <vscale x 4 x float> [[B:%.*]]
755 ; CHECK-NEXT: store <vscale x 4 x float> [[SEL1_V]], ptr [[PTR1:%.*]], align 16
756 ; CHECK-NEXT: ret void
758 %cmp = icmp ult <vscale x 4 x i32> %c, %d
759 %bc1 = bitcast <vscale x 4 x float> %a to <vscale x 4 x i32>
760 %bc2 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32>
761 %sel1 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %bc2
762 store <vscale x 4 x i32> %sel1, ptr %ptr1
766 ; Allow select promotion even if there are multiple uses of bitcasted ops.
767 ; Hoisting the selects allows later pattern matching to see that these are min/max ops.
769 define void @min_max_bitcast(<4 x float> %a, <4 x float> %b, ptr %ptr1, ptr %ptr2) {
770 ; CHECK-LABEL: @min_max_bitcast(
771 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <4 x float> [[A:%.*]], [[B:%.*]]
772 ; CHECK-NEXT: [[SEL1_V:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[A]], <4 x float> [[B]]
773 ; CHECK-NEXT: [[SEL2_V:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[B]], <4 x float> [[A]]
774 ; CHECK-NEXT: store <4 x float> [[SEL1_V]], ptr [[PTR1:%.*]], align 16
775 ; CHECK-NEXT: store <4 x float> [[SEL2_V]], ptr [[PTR2:%.*]], align 16
776 ; CHECK-NEXT: ret void
778 %cmp = fcmp olt <4 x float> %a, %b
779 %bc1 = bitcast <4 x float> %a to <4 x i32>
780 %bc2 = bitcast <4 x float> %b to <4 x i32>
781 %sel1 = select <4 x i1> %cmp, <4 x i32> %bc1, <4 x i32> %bc2
782 %sel2 = select <4 x i1> %cmp, <4 x i32> %bc2, <4 x i32> %bc1
783 store <4 x i32> %sel1, ptr %ptr1
784 store <4 x i32> %sel2, ptr %ptr2
788 define void @min_max_bitcast1(<vscale x 4 x float> %a, <vscale x 4 x float> %b, ptr %ptr1, ptr %ptr2) {
789 ; CHECK-LABEL: @min_max_bitcast1(
790 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <vscale x 4 x float> [[A:%.*]], [[B:%.*]]
791 ; CHECK-NEXT: [[SEL1_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[A]], <vscale x 4 x float> [[B]]
792 ; CHECK-NEXT: [[SEL2_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[B]], <vscale x 4 x float> [[A]]
793 ; CHECK-NEXT: store <vscale x 4 x float> [[SEL1_V]], ptr [[PTR1:%.*]], align 16
794 ; CHECK-NEXT: store <vscale x 4 x float> [[SEL2_V]], ptr [[PTR2:%.*]], align 16
795 ; CHECK-NEXT: ret void
797 %cmp = fcmp olt <vscale x 4 x float> %a, %b
798 %bc1 = bitcast <vscale x 4 x float> %a to <vscale x 4 x i32>
799 %bc2 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32>
800 %sel1 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %bc2
801 %sel2 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc2, <vscale x 4 x i32> %bc1
802 store <vscale x 4 x i32> %sel1, ptr %ptr1
803 store <vscale x 4 x i32> %sel2, ptr %ptr2
807 ; To avoid potential backend problems, we don't do the same transform for other casts.
809 define void @truncs_before_selects(<4 x float> %f1, <4 x float> %f2, <4 x i64> %a, <4 x i64> %b, ptr %ptr1, ptr %ptr2) {
810 ; CHECK-LABEL: @truncs_before_selects(
811 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <4 x float> [[F1:%.*]], [[F2:%.*]]
812 ; CHECK-NEXT: [[BC1:%.*]] = trunc <4 x i64> [[A:%.*]] to <4 x i32>
813 ; CHECK-NEXT: [[BC2:%.*]] = trunc <4 x i64> [[B:%.*]] to <4 x i32>
814 ; CHECK-NEXT: [[SEL1:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[BC1]], <4 x i32> [[BC2]]
815 ; CHECK-NEXT: [[SEL2:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[BC2]], <4 x i32> [[BC1]]
816 ; CHECK-NEXT: store <4 x i32> [[SEL1]], ptr [[PTR1:%.*]], align 16
817 ; CHECK-NEXT: store <4 x i32> [[SEL2]], ptr [[PTR2:%.*]], align 16
818 ; CHECK-NEXT: ret void
820 %cmp = fcmp olt <4 x float> %f1, %f2
821 %bc1 = trunc <4 x i64> %a to <4 x i32>
822 %bc2 = trunc <4 x i64> %b to <4 x i32>
823 %sel1 = select <4 x i1> %cmp, <4 x i32> %bc1, <4 x i32> %bc2
824 %sel2 = select <4 x i1> %cmp, <4 x i32> %bc2, <4 x i32> %bc1
825 store <4 x i32> %sel1, ptr %ptr1, align 16
826 store <4 x i32> %sel2, ptr %ptr2, align 16
832 define i32 @test52(i32 %n, i32 %m) {
833 ; CHECK-LABEL: @test52(
834 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], [[M:%.*]]
835 ; CHECK-NEXT: [[STOREMERGE:%.*]] = select i1 [[CMP]], i32 1, i32 6
836 ; CHECK-NEXT: ret i32 [[STOREMERGE]]
838 %cmp = icmp sgt i32 %n, %m
839 %. = select i1 %cmp, i32 1, i32 3
840 %add = add nsw i32 %., 3
841 %storemerge = select i1 %cmp, i32 %., i32 %add
847 define i32 @test53(i32 %x) {
848 ; CHECK-LABEL: @test53(
849 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -3
850 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
851 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 2, i32 1
852 ; CHECK-NEXT: ret i32 [[SEL]]
855 %cmp = icmp eq i32 %and, %x
856 %sel = select i1 %cmp, i32 2, i32 1
860 define i32 @test54(i32 %X, i32 %Y) {
861 ; CHECK-LABEL: @test54(
862 ; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
863 ; CHECK-NEXT: [[C:%.*]] = zext i1 [[B]] to i32
864 ; CHECK-NEXT: ret i32 [[C]]
866 %A = ashr exact i32 %X, %Y
867 %B = icmp eq i32 %A, 0
868 %C = select i1 %B, i32 %A, i32 1
872 define i1 @test55(i1 %X, i32 %Y, i32 %Z) {
873 ; CHECK-LABEL: @test55(
874 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[Y:%.*]], 0
875 ; CHECK-NEXT: ret i1 [[C]]
877 %A = ashr exact i32 %Y, %Z
878 %B = select i1 %X, i32 %Y, i32 %A
879 %C = icmp eq i32 %B, 0
883 define i32 @test56(i16 %x) {
884 ; CHECK-LABEL: @test56(
885 ; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[X:%.*]] to i32
886 ; CHECK-NEXT: ret i32 [[CONV]]
888 %tobool = icmp eq i16 %x, 0
889 %conv = zext i16 %x to i32
890 %cond = select i1 %tobool, i32 0, i32 %conv
894 define i32 @test57(i32 %x, i32 %y) {
895 ; CHECK-LABEL: @test57(
896 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
897 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X]], 0
898 ; CHECK-NEXT: [[DOTAND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 [[AND]]
899 ; CHECK-NEXT: ret i32 [[DOTAND]]
901 %and = and i32 %x, %y
902 %tobool = icmp eq i32 %x, 0
903 %.and = select i1 %tobool, i32 0, i32 %and
907 define i32 @test58(i16 %x) {
908 ; CHECK-LABEL: @test58(
909 ; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[X:%.*]] to i32
910 ; CHECK-NEXT: ret i32 [[CONV]]
912 %tobool = icmp ne i16 %x, 1
913 %conv = zext i16 %x to i32
914 %cond = select i1 %tobool, i32 %conv, i32 1
918 define i32 @test59(i32 %x, i32 %y) {
919 ; CHECK-LABEL: @test59(
920 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
921 ; CHECK-NEXT: ret i32 [[AND]]
923 %and = and i32 %x, %y
924 %tobool = icmp ne i32 %x, %y
925 %.and = select i1 %tobool, i32 %and, i32 %y
929 define i1 @test60(i32 %x, ptr %y) {
930 ; CHECK-LABEL: @test60(
931 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
932 ; CHECK-NEXT: [[LOAD:%.*]] = load i1, ptr [[Y:%.*]], align 1
933 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X]], 1
934 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i1 [[LOAD]], i1 [[CMP1]]
935 ; CHECK-NEXT: ret i1 [[SEL]]
937 %cmp = icmp eq i32 %x, 0
938 %load = load i1, ptr %y, align 1
939 %cmp1 = icmp slt i32 %x, 1
940 %sel = select i1 %cmp, i1 %load, i1 %cmp1
944 @glbl = constant i32 10
945 define i32 @test61(ptr %ptr) {
946 ; CHECK-LABEL: @test61(
947 ; CHECK-NEXT: ret i32 10
949 %A = load i32, ptr %ptr
950 %B = icmp eq ptr %ptr, @glbl
951 %C = select i1 %B, i32 %A, i32 10
956 define void @test64(i32 %p, i16 %b, i1 %c1) noreturn {
957 ; CHECK-LABEL: @test64(
959 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[LOR_RHS:%.*]], label [[LOR_END:%.*]]
961 ; CHECK-NEXT: br label [[LOR_END]]
963 ; CHECK-NEXT: br i1 poison, label [[COND_END17:%.*]], label [[COND_FALSE16:%.*]]
964 ; CHECK: cond.false16:
965 ; CHECK-NEXT: br label [[COND_END17]]
967 ; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
969 ; CHECK-NEXT: br label [[WHILE_BODY]]
972 %p.addr.0.insert.mask = and i32 %p, -65536
973 %conv2 = and i32 %p, 65535
974 br i1 %c1, label %lor.rhs, label %lor.end
977 %p.addr.0.extract.trunc = trunc i32 %p.addr.0.insert.mask to i16
978 %phitmp = zext i16 %p.addr.0.extract.trunc to i32
982 %t.1 = phi i32 [ 0, %entry ], [ %phitmp, %lor.rhs ]
983 %conv6 = zext i16 %b to i32
984 %div = udiv i32 %conv6, %t.1
985 %tobool8 = icmp eq i32 %div, 0
986 %cmp = icmp eq i32 %t.1, 0
987 %cmp12 = icmp ult i32 %conv2, 2
988 %cmp.sink = select i1 %tobool8, i1 %cmp12, i1 %cmp
989 br i1 %cmp.sink, label %cond.end17, label %cond.false16
1001 @under_aligned = external global i32, align 1
1003 ; The load here must not be speculated around the select. One side of the
1004 ; select is trivially dereferenceable but may have a lower alignment than the
1006 define i32 @test76(i1 %flag, ptr %x) {
1007 ; CHECK-LABEL: @test76(
1008 ; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4
1009 ; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], ptr @under_aligned, ptr [[X]]
1010 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 4
1011 ; CHECK-NEXT: ret i32 [[V]]
1014 %p = select i1 %flag, ptr @under_aligned, ptr %x
1015 %v = load i32, ptr %p
1019 declare void @scribble_on_i32(ptr)
1021 ; The load here must not be speculated around the select. One side of the
1022 ; select is trivially dereferenceable but may have a lower alignment than the
1025 define i32 @test77(i1 %flag, ptr %x) {
1026 ; CHECK-LABEL: @test77(
1027 ; CHECK-NEXT: [[UNDER_ALIGNED:%.*]] = alloca i32, align 1
1028 ; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[UNDER_ALIGNED]])
1029 ; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4
1030 ; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], ptr [[UNDER_ALIGNED]], ptr [[X]]
1031 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 4
1032 ; CHECK-NEXT: ret i32 [[V]]
1034 %under_aligned = alloca i32, align 1
1035 call void @scribble_on_i32(ptr %under_aligned)
1037 %p = select i1 %flag, ptr %under_aligned, ptr %x
1038 %v = load i32, ptr %p
1042 define i32 @test78(i1 %flag, ptr %x, ptr %y, ptr %z) {
1043 ; Test that we can speculate the loads around the select even when we can't
1044 ; fold the load completely away.
1045 ; CHECK-LABEL: @test78(
1046 ; CHECK-NEXT: entry:
1047 ; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4
1048 ; CHECK-NEXT: store i32 0, ptr [[Y:%.*]], align 4
1049 ; CHECK-NEXT: store i32 42, ptr [[Z:%.*]], align 4
1050 ; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X]], align 4
1051 ; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, ptr [[Y]], align 4
1052 ; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i32 [[X_VAL]], i32 [[Y_VAL]]
1053 ; CHECK-NEXT: ret i32 [[V]]
1058 ; Block forwarding by storing to %z which could alias either %x or %y.
1059 store i32 42, ptr %z
1060 %p = select i1 %flag, ptr %x, ptr %y
1061 %v = load i32, ptr %p
1065 ; Test that we can speculate the loads around the select even when we can't
1066 ; fold the load completely away.
1067 define i32 @test78_deref(i1 %flag, ptr dereferenceable(4) align 4 %x, ptr dereferenceable(4) align 4 %y, ptr %z) nofree nosync {
1068 ; CHECK-LABEL: @test78_deref(
1069 ; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
1070 ; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, ptr [[Y:%.*]], align 4
1071 ; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i32 [[X_VAL]], i32 [[Y_VAL]]
1072 ; CHECK-NEXT: ret i32 [[V]]
1074 %p = select i1 %flag, ptr %x, ptr %y
1075 %v = load i32, ptr %p
1079 ; The same as @test78 but we can't speculate the load because it can trap
1081 define i32 @test78_neg(i1 %flag, ptr %x, ptr %y, ptr %z) {
1082 ; CHECK-LABEL: @test78_neg(
1083 ; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4
1084 ; CHECK-NEXT: store i32 0, ptr [[Y:%.*]], align 4
1085 ; CHECK-NEXT: store i32 42, ptr [[Z:%.*]], align 4
1086 ; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], ptr [[X]], ptr [[Y]]
1087 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 16
1088 ; CHECK-NEXT: ret i32 [[V]]
1092 ; Block forwarding by storing to %z which could alias either %x or %y.
1093 store i32 42, ptr %z
1094 %p = select i1 %flag, ptr %x, ptr %y
1095 %v = load i32, ptr %p, align 16
1099 ; The same as @test78_deref but we can't speculate the load because
1100 ; one of the arguments is not sufficiently dereferenceable.
1101 define i32 @test78_deref_neg(i1 %flag, ptr dereferenceable(2) %x, ptr dereferenceable(4) %y, ptr %z) nofree nosync {
1102 ; CHECK-LABEL: @test78_deref_neg(
1103 ; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], ptr [[X:%.*]], ptr [[Y:%.*]]
1104 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 4
1105 ; CHECK-NEXT: ret i32 [[V]]
1107 %p = select i1 %flag, ptr %x, ptr %y
1108 %v = load i32, ptr %p
1112 ; Test that we can speculate the loads around the select even when we can't
1113 ; fold the load completely away.
1114 define float @test79(i1 %flag, ptr %x, ptr %y, ptr %z) {
1115 ; CHECK-LABEL: @test79(
1116 ; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4
1117 ; CHECK-NEXT: store i32 0, ptr [[Y:%.*]], align 4
1118 ; CHECK-NEXT: store i32 42, ptr [[Z:%.*]], align 4
1119 ; CHECK-NEXT: [[X_VAL:%.*]] = load float, ptr [[X]], align 4
1120 ; CHECK-NEXT: [[Y_VAL:%.*]] = load float, ptr [[Y]], align 4
1121 ; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], float [[X_VAL]], float [[Y_VAL]]
1122 ; CHECK-NEXT: ret float [[V]]
1126 ; Block forwarding by storing to %z which could alias either %x or %y.
1127 store i32 42, ptr %z
1128 %p = select i1 %flag, ptr %x, ptr %y
1129 %v = load float, ptr %p
1133 ; Test that when we speculate the loads around the select they fold throug
1134 ; load->load folding and load->store folding.
1135 define i32 @test80(i1 %flag) {
1136 ; CHECK-LABEL: @test80(
1137 ; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4
1138 ; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4
1139 ; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[X]])
1140 ; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[Y]])
1141 ; CHECK-NEXT: [[T:%.*]] = load i32, ptr [[X]], align 4
1142 ; CHECK-NEXT: store i32 [[T]], ptr [[Y]], align 4
1143 ; CHECK-NEXT: ret i32 [[T]]
1147 call void @scribble_on_i32(ptr %x)
1148 call void @scribble_on_i32(ptr %y)
1149 %t = load i32, ptr %x
1150 store i32 %t, ptr %y
1151 %p = select i1 %flag, ptr %x, ptr %y
1152 %v = load i32, ptr %p
1156 ; Test that we can speculate the load around the select even though they use
1157 ; differently typed pointers.
1158 define float @test81(i1 %flag) {
1159 ; CHECK-LABEL: @test81(
1160 ; CHECK-NEXT: [[X:%.*]] = alloca float, align 4
1161 ; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4
1162 ; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[X]])
1163 ; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[Y]])
1164 ; CHECK-NEXT: [[T:%.*]] = load i32, ptr [[X]], align 4
1165 ; CHECK-NEXT: store i32 [[T]], ptr [[Y]], align 4
1166 ; CHECK-NEXT: [[V:%.*]] = bitcast i32 [[T]] to float
1167 ; CHECK-NEXT: ret float [[V]]
1171 call void @scribble_on_i32(ptr %x)
1172 call void @scribble_on_i32(ptr %y)
1173 %t = load i32, ptr %x
1174 store i32 %t, ptr %y
1175 %p = select i1 %flag, ptr %x, ptr %y
1176 %v = load float, ptr %p
1180 ; Test that we can speculate the load around the select even though they use
1181 ; differently typed pointers.
1182 define i32 @test82(i1 %flag) {
1183 ; CHECK-LABEL: @test82(
1184 ; CHECK-NEXT: [[X:%.*]] = alloca float, align 4
1185 ; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4
1186 ; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[X]])
1187 ; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[Y]])
1188 ; CHECK-NEXT: [[T:%.*]] = load float, ptr [[X]], align 4
1189 ; CHECK-NEXT: store float [[T]], ptr [[Y]], align 4
1190 ; CHECK-NEXT: [[V:%.*]] = bitcast float [[T]] to i32
1191 ; CHECK-NEXT: ret i32 [[V]]
1195 call void @scribble_on_i32(ptr %x)
1196 call void @scribble_on_i32(ptr %y)
1197 %t = load float, ptr %x
1198 store float %t, ptr %y
1199 %p = select i1 %flag, ptr %x, ptr %y
1200 %v = load i32, ptr %p
1204 declare void @scribble_on_i64(ptr)
1205 declare void @scribble_on_i128(ptr)
1207 ; Test that we can speculate the load around the select even though they use
1208 ; differently typed pointers and requires inttoptr casts.
1209 define ptr @test83(i1 %flag) {
1210 ; CHECK-LABEL: @test83(
1211 ; CHECK-NEXT: [[X:%.*]] = alloca ptr, align 8
1212 ; CHECK-NEXT: [[Y:%.*]] = alloca i64, align 8
1213 ; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[X]])
1214 ; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[Y]])
1215 ; CHECK-NEXT: [[T:%.*]] = load i64, ptr [[X]], align 4
1216 ; CHECK-NEXT: store i64 [[T]], ptr [[Y]], align 4
1217 ; CHECK-NEXT: [[V:%.*]] = inttoptr i64 [[T]] to ptr
1218 ; CHECK-NEXT: ret ptr [[V]]
1222 call void @scribble_on_i64(ptr %x)
1223 call void @scribble_on_i64(ptr %y)
1224 %t = load i64, ptr %x
1225 store i64 %t, ptr %y
1226 %p = select i1 %flag, ptr %x, ptr %y
1227 %v = load ptr, ptr %p
1231 ; Test that we can speculate the load around the select even though they use
1232 ; differently typed pointers and requires a ptrtoint cast.
1233 define i64 @test84(i1 %flag) {
1234 ; CHECK-LABEL: @test84(
1235 ; CHECK-NEXT: [[X:%.*]] = alloca ptr, align 8
1236 ; CHECK-NEXT: [[Y:%.*]] = alloca i64, align 8
1237 ; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[X]])
1238 ; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[Y]])
1239 ; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[X]], align 8
1240 ; CHECK-NEXT: store ptr [[T]], ptr [[Y]], align 8
1241 ; CHECK-NEXT: [[V:%.*]] = ptrtoint ptr [[T]] to i64
1242 ; CHECK-NEXT: ret i64 [[V]]
1246 call void @scribble_on_i64(ptr %x)
1247 call void @scribble_on_i64(ptr %y)
1248 %t = load ptr, ptr %x
1249 store ptr %t, ptr %y
1250 %p = select i1 %flag, ptr %x, ptr %y
1251 %v = load i64, ptr %p
1255 ; Test that we can't speculate the load around the select. The load of the
1256 ; pointer doesn't load all of the stored integer bits. We could fix this, but it
1257 ; would require endianness checks and other nastiness.
1258 define ptr @test85(i1 %flag) {
1259 ; CHECK-LABEL: @test85(
1260 ; CHECK-NEXT: [[X:%.*]] = alloca [2 x ptr], align 8
1261 ; CHECK-NEXT: [[Y:%.*]] = alloca i128, align 8
1262 ; CHECK-NEXT: call void @scribble_on_i128(ptr nonnull [[X]])
1263 ; CHECK-NEXT: call void @scribble_on_i128(ptr nonnull [[Y]])
1264 ; CHECK-NEXT: [[T:%.*]] = load i128, ptr [[X]], align 4
1265 ; CHECK-NEXT: store i128 [[T]], ptr [[Y]], align 4
1266 ; CHECK-NEXT: [[X_VAL:%.*]] = load ptr, ptr [[X]], align 8
1267 ; CHECK-NEXT: [[Y_VAL:%.*]] = load ptr, ptr [[Y]], align 8
1268 ; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], ptr [[X_VAL]], ptr [[Y_VAL]]
1269 ; CHECK-NEXT: ret ptr [[V]]
1271 %x = alloca [2 x ptr]
1273 call void @scribble_on_i128(ptr %x)
1274 call void @scribble_on_i128(ptr %y)
1275 %t = load i128, ptr %x
1276 store i128 %t, ptr %y
1277 %p = select i1 %flag, ptr %x, ptr %y
1278 %v = load ptr, ptr %p
1282 ; Test that we can't speculate the load around the select when the integer size
1283 ; is larger than the pointer size. The store of the pointer doesn't store to all
1284 ; the bits of the integer.
1285 define i128 @test86(i1 %flag) {
1286 ; CHECK-LABEL: @test86(
1287 ; CHECK-NEXT: [[X:%.*]] = alloca [2 x ptr], align 8
1288 ; CHECK-NEXT: [[Y:%.*]] = alloca i128, align 8
1289 ; CHECK-NEXT: call void @scribble_on_i128(ptr nonnull [[X]])
1290 ; CHECK-NEXT: call void @scribble_on_i128(ptr nonnull [[Y]])
1291 ; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[X]], align 8
1292 ; CHECK-NEXT: store ptr [[T]], ptr [[Y]], align 8
1293 ; CHECK-NEXT: [[X_VAL:%.*]] = load i128, ptr [[X]], align 4
1294 ; CHECK-NEXT: [[Y_VAL:%.*]] = load i128, ptr [[Y]], align 4
1295 ; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i128 [[X_VAL]], i128 [[Y_VAL]]
1296 ; CHECK-NEXT: ret i128 [[V]]
1298 %x = alloca [2 x ptr]
1300 call void @scribble_on_i128(ptr %x)
1301 call void @scribble_on_i128(ptr %y)
1302 %t = load ptr, ptr %x
1303 store ptr %t, ptr %y
1304 %p = select i1 %flag, ptr %x, ptr %y
1305 %v = load i128, ptr %p
1309 define i32 @test_select_select0(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
1310 ; CHECK-LABEL: @test_select_select0(
1311 ; CHECK-NEXT: [[C0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[V1:%.*]]
1312 ; CHECK-NEXT: [[S0:%.*]] = select i1 [[C0_NOT]], i32 [[R1:%.*]], i32 [[R0:%.*]]
1313 ; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[A]], [[V2:%.*]]
1314 ; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1]], i32 [[S0]], i32 [[R1]]
1315 ; CHECK-NEXT: ret i32 [[S1]]
1317 %c0 = icmp sge i32 %a, %v1
1318 %s0 = select i1 %c0, i32 %r0, i32 %r1
1319 %c1 = icmp slt i32 %a, %v2
1320 %s1 = select i1 %c1, i32 %s0, i32 %r1
1324 define i32 @test_select_select1(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
1325 ; CHECK-LABEL: @test_select_select1(
1326 ; CHECK-NEXT: [[C0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[V1:%.*]]
1327 ; CHECK-NEXT: [[S0:%.*]] = select i1 [[C0_NOT]], i32 [[R1:%.*]], i32 [[R0:%.*]]
1328 ; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[A]], [[V2:%.*]]
1329 ; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1]], i32 [[R0]], i32 [[S0]]
1330 ; CHECK-NEXT: ret i32 [[S1]]
1332 %c0 = icmp sge i32 %a, %v1
1333 %s0 = select i1 %c0, i32 %r0, i32 %r1
1334 %c1 = icmp slt i32 %a, %v2
1335 %s1 = select i1 %c1, i32 %r0, i32 %s0
1339 define i32 @PR23757(i32 %x) {
1340 ; CHECK-LABEL: @PR23757(
1341 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 1
1342 ; CHECK-NEXT: ret i32 [[ADD]]
1344 %cmp = icmp eq i32 %x, 2147483647
1345 %add = add nsw i32 %x, 1
1346 %sel = select i1 %cmp, i32 -2147483648, i32 %add
1350 define i32 @PR23757_swapped(i32 %x) {
1351 ; CHECK-LABEL: @PR23757_swapped(
1352 ; CHECK-NEXT: ret i32 -2147483648
1354 %cmp = icmp eq i32 %x, 2147483647
1355 %add = add nsw i32 %x, 1
1356 %sel = select i1 %cmp, i32 %add, i32 -2147483648
1360 define i32 @PR23757_ne(i32 %x, ptr %p) {
1361 ; CHECK-LABEL: @PR23757_ne(
1362 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 2147483647
1363 ; CHECK-NEXT: store i1 [[CMP]], ptr [[P:%.*]], align 1
1364 ; CHECK-NEXT: ret i32 -2147483648
1366 %cmp = icmp ne i32 %x, 2147483647
1367 store i1 %cmp, ptr %p ; thwart predicate canonicalization
1368 %add = add nsw i32 %x, 1
1369 %sel = select i1 %cmp, i32 -2147483648, i32 %add
1373 define i32 @PR23757_ne_swapped(i32 %x, ptr %p) {
1374 ; CHECK-LABEL: @PR23757_ne_swapped(
1375 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 2147483647
1376 ; CHECK-NEXT: store i1 [[CMP]], ptr [[P:%.*]], align 1
1377 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X]], 1
1378 ; CHECK-NEXT: ret i32 [[ADD]]
1380 %cmp = icmp ne i32 %x, 2147483647
1381 store i1 %cmp, ptr %p ; thwart predicate canonicalization
1382 %add = add nsw i32 %x, 1
1383 %sel = select i1 %cmp, i32 %add, i32 -2147483648
1387 ; max(max(~a, -1), -1) --> ~min(a, 0)
1389 define i32 @PR27137(i32 %a) {
1390 ; CHECK-LABEL: @PR27137(
1391 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 0)
1392 ; CHECK-NEXT: [[S1:%.*]] = xor i32 [[TMP1]], -1
1393 ; CHECK-NEXT: ret i32 [[S1]]
1395 %not_a = xor i32 %a, -1
1396 %c0 = icmp slt i32 %a, 0
1397 %s0 = select i1 %c0, i32 %not_a, i32 -1
1398 %c1 = icmp sgt i32 %s0, -1
1399 %s1 = select i1 %c1, i32 %s0, i32 -1
1403 ; ub-safe negation pattern
1404 define i32 @PR27817(i32 %x) {
1405 ; CHECK-LABEL: @PR27817(
1406 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]]
1407 ; CHECK-NEXT: ret i32 [[SUB]]
1409 %cmp = icmp eq i32 %x, -2147483648
1410 %sub = sub i32 0, %x
1411 %sel = select i1 %cmp, i32 -2147483648, i32 %sub
1415 define i32 @PR27817_nsw(i32 %x) {
1416 ; CHECK-LABEL: @PR27817_nsw(
1417 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]]
1418 ; CHECK-NEXT: ret i32 [[SUB]]
1420 %cmp = icmp eq i32 %x, -2147483648
1421 %sub = sub nsw i32 0, %x
1422 %sel = select i1 %cmp, i32 -2147483648, i32 %sub
1426 define <2 x i32> @PR27817_nsw_vec(<2 x i32> %x) {
1427 ; CHECK-LABEL: @PR27817_nsw_vec(
1428 ; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]]
1429 ; CHECK-NEXT: ret <2 x i32> [[SUB]]
1431 %cmp = icmp eq <2 x i32> %x, <i32 -2147483648, i32 -2147483648>
1432 %sub = sub nsw <2 x i32> zeroinitializer, %x
1433 %sel = select <2 x i1> %cmp, <2 x i32> <i32 -2147483648, i32 -2147483648>, <2 x i32> %sub
1437 define i32 @select_icmp_slt0_xor(i32 %x) {
1438 ; CHECK-LABEL: @select_icmp_slt0_xor(
1439 ; CHECK-NEXT: [[X_XOR:%.*]] = or i32 [[X:%.*]], -2147483648
1440 ; CHECK-NEXT: ret i32 [[X_XOR]]
1442 %cmp = icmp slt i32 %x, zeroinitializer
1443 %xor = xor i32 %x, 2147483648
1444 %x.xor = select i1 %cmp, i32 %x, i32 %xor
1448 define <2 x i32> @select_icmp_slt0_xor_vec(<2 x i32> %x) {
1449 ; CHECK-LABEL: @select_icmp_slt0_xor_vec(
1450 ; CHECK-NEXT: [[X_XOR:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 -2147483648)
1451 ; CHECK-NEXT: ret <2 x i32> [[X_XOR]]
1453 %cmp = icmp slt <2 x i32> %x, zeroinitializer
1454 %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648>
1455 %x.xor = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %xor
1456 ret <2 x i32> %x.xor
1459 define <4 x i32> @canonicalize_to_shuffle(<4 x i32> %a, <4 x i32> %b) {
1460 ; CHECK-LABEL: @canonicalize_to_shuffle(
1461 ; CHECK-NEXT: [[SEL:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>
1462 ; CHECK-NEXT: ret <4 x i32> [[SEL]]
1464 %sel = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> %a, <4 x i32> %b
1468 ; Undef elements of the select condition may not be translated into undef elements of a shuffle mask
1469 ; because undef in a shuffle mask means we can return anything, not just one of the selected values.
1470 ; https://bugs.llvm.org/show_bug.cgi?id=32486
1472 define <4 x i32> @undef_elts_in_condition(<4 x i32> %a, <4 x i32> %b) {
1473 ; CHECK-LABEL: @undef_elts_in_condition(
1474 ; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]
1475 ; CHECK-NEXT: ret <4 x i32> [[SEL]]
1477 %sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> %a, <4 x i32> %b
1481 ; Don't die or try if the condition mask is a constant expression or contains a constant expression.
1485 define <4 x i32> @cannot_canonicalize_to_shuffle1(<4 x i32> %a, <4 x i32> %b) {
1486 ; CHECK-LABEL: @cannot_canonicalize_to_shuffle1(
1487 ; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> bitcast (i4 ptrtoint (ptr @g to i4) to <4 x i1>), <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]
1488 ; CHECK-NEXT: ret <4 x i32> [[SEL]]
1490 %sel = select <4 x i1> bitcast (i4 ptrtoint (ptr @g to i4) to <4 x i1>), <4 x i32> %a, <4 x i32> %b
1494 define <4 x i32> @cannot_canonicalize_to_shuffle2(<4 x i32> %a, <4 x i32> %b) {
1495 ; CHECK-LABEL: @cannot_canonicalize_to_shuffle2(
1496 ; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 ptrtoint (ptr @g to i1)>, <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]
1497 ; CHECK-NEXT: ret <4 x i32> [[SEL]]
1499 %sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 ptrtoint (ptr @g to i1)>, <4 x i32> %a, <4 x i32> %b
1503 declare void @llvm.assume(i1)
1505 define i8 @assume_cond_true(i1 %cond, i8 %x, i8 %y) {
1506 ; CHECK-LABEL: @assume_cond_true(
1507 ; CHECK-NEXT: call void @llvm.assume(i1 [[COND:%.*]])
1508 ; CHECK-NEXT: ret i8 [[X:%.*]]
1510 call void @llvm.assume(i1 %cond)
1511 %sel = select i1 %cond, i8 %x, i8 %y
1515 ; computeKnownBitsFromAssume() understands the 'not' of an assumed condition.
1517 define i8 @assume_cond_false(i1 %cond, i8 %x, i8 %y) {
1518 ; CHECK-LABEL: @assume_cond_false(
1519 ; CHECK-NEXT: [[NOTCOND:%.*]] = xor i1 [[COND:%.*]], true
1520 ; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]])
1521 ; CHECK-NEXT: ret i8 [[Y:%.*]]
1523 %notcond = xor i1 %cond, true
1524 call void @llvm.assume(i1 %notcond)
1525 %sel = select i1 %cond, i8 %x, i8 %y
1529 ; Test case to make sure we don't consider an all ones float values for converting the select into a sext.
1530 define <4 x float> @PR33721(<4 x float> %w) {
1531 ; CHECK-LABEL: @PR33721(
1532 ; CHECK-NEXT: entry:
1533 ; CHECK-NEXT: [[TMP0:%.*]] = fcmp ole <4 x float> [[W:%.*]], zeroinitializer
1534 ; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[TMP0]], <4 x float> splat (float 0xFFFFFFFFE0000000), <4 x float> zeroinitializer
1535 ; CHECK-NEXT: ret <4 x float> [[TMP1]]
1538 %0 = fcmp ole <4 x float> %w, zeroinitializer
1539 %1 = select <4 x i1> %0, <4 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>, <4 x float> zeroinitializer
1543 ; select(C, binop(select(C, X, Y), W), Z) -> select(C, binop(X, W), Z)
1544 define i8 @test87(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {
1545 ; CHECK-LABEL: @test87(
1546 ; CHECK-NEXT: [[B:%.*]] = add i8 [[X:%.*]], [[W:%.*]]
1547 ; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[B]], i8 [[Z:%.*]]
1548 ; CHECK-NEXT: ret i8 [[C]]
1550 %a = select i1 %cond, i8 %x, i8 %y
1552 %c = select i1 %cond, i8 %b, i8 %z
1556 ; select(C, binop(select(C, X, Y), W), Z) -> select(C, Z, binop(Y, W))
1557 define i8 @test88(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {
1558 ; CHECK-LABEL: @test88(
1559 ; CHECK-NEXT: [[B:%.*]] = sub i8 [[Y:%.*]], [[W:%.*]]
1560 ; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[Z:%.*]], i8 [[B]]
1561 ; CHECK-NEXT: ret i8 [[C]]
1563 %a = select i1 %cond, i8 %x, i8 %y
1565 %c = select i1 %cond, i8 %z, i8 %b
1569 ; select(C, Z, binop(W, select(C, X, Y))) -> select(C, binop(X, W), Z)
1570 define i8 @test89(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {
1571 ; CHECK-LABEL: @test89(
1572 ; CHECK-NEXT: [[B:%.*]] = and i8 [[W:%.*]], [[X:%.*]]
1573 ; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[B]], i8 [[Z:%.*]]
1574 ; CHECK-NEXT: ret i8 [[C]]
1576 %a = select i1 %cond, i8 %x, i8 %y
1578 %c = select i1 %cond, i8 %b, i8 %z
1582 ; select(C, Z, binop(W, select(C, X, Y))) -> select(C, Z, binop(W, Y))
1583 define i8 @test90(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {
1584 ; CHECK-LABEL: @test90(
1585 ; CHECK-NEXT: [[B:%.*]] = or i8 [[W:%.*]], [[Y:%.*]]
1586 ; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[Z:%.*]], i8 [[B]]
1587 ; CHECK-NEXT: ret i8 [[C]]
1589 %a = select i1 %cond, i8 %x, i8 %y
1591 %c = select i1 %cond, i8 %z, i8 %b
1595 define i32 @test_shl_zext_bool(i1 %t) {
1596 ; CHECK-LABEL: @test_shl_zext_bool(
1597 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T:%.*]], i32 4, i32 0
1598 ; CHECK-NEXT: ret i32 [[R]]
1600 %r = select i1 %t, i32 4, i32 0
1604 define <2 x i32> @test_shl_zext_bool_splat(<2 x i1> %t) {
1605 ; CHECK-LABEL: @test_shl_zext_bool_splat(
1606 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> splat (i32 8), <2 x i32> zeroinitializer
1607 ; CHECK-NEXT: ret <2 x i32> [[R]]
1609 %r = select <2 x i1> %t, <2 x i32> <i32 8, i32 8>, <2 x i32> zeroinitializer
1613 define <2 x i32> @test_shl_zext_bool_vec(<2 x i1> %t) {
1614 ; CHECK-LABEL: @test_shl_zext_bool_vec(
1615 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer
1616 ; CHECK-NEXT: ret <2 x i32> [[R]]
1618 %r = select <2 x i1> %t, <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer
1622 define float @copysign1(float %x) {
1623 ; CHECK-LABEL: @copysign1(
1624 ; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float [[X:%.*]])
1625 ; CHECK-NEXT: ret float [[R]]
1627 %i = bitcast float %x to i32
1628 %ispos = icmp sgt i32 %i, -1
1629 %r = select i1 %ispos, float 1.0, float -1.0
1633 define float @copysign1_fmf(float %x) {
1634 ; CHECK-LABEL: @copysign1_fmf(
1635 ; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float [[X:%.*]])
1636 ; CHECK-NEXT: ret float [[R]]
1638 %i = bitcast float %x to i32
1639 %ispos = icmp sgt i32 %i, -1
1640 %r = select nsz ninf i1 %ispos, float 1.0, float -1.0
1644 define <2 x float> @copysign2(<2 x float> %x) {
1645 ; CHECK-LABEL: @copysign2(
1646 ; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]]
1647 ; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[TMP1]])
1648 ; CHECK-NEXT: ret <2 x float> [[R]]
1650 %i = bitcast <2 x float> %x to <2 x i32>
1651 %isneg = icmp slt <2 x i32> %i, zeroinitializer
1652 %r = select nsz <2 x i1> %isneg, <2 x float> <float 42.0, float 42.0>, <2 x float> <float -42.0, float -42.0>
1656 define float @copysign3(float %x) {
1657 ; CHECK-LABEL: @copysign3(
1658 ; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[X:%.*]]
1659 ; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float 4.300000e+01, float [[TMP1]])
1660 ; CHECK-NEXT: ret float [[R]]
1662 %i = bitcast float %x to i32
1663 %ispos = icmp ult i32 %i, 2147483648
1664 %r = select fast i1 %ispos, float -43.0, float 43.0
1668 define <2 x float> @copysign_vec_poison(<2 x float> %x) {
1669 ; CHECK-LABEL: @copysign_vec_poison(
1670 ; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]]
1671 ; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[TMP1]])
1672 ; CHECK-NEXT: ret <2 x float> [[R]]
1674 %i = bitcast <2 x float> %x to <2 x i32>
1675 %isneg = icmp ugt <2 x i32> %i, <i32 2147483647, i32 2147483647>
1676 %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float 42.0, float poison>, <2 x float> <float -42.0, float -42.0>
1680 define <2 x float> @copysign_vec_poison1(<2 x float> %x) {
1681 ; CHECK-LABEL: @copysign_vec_poison1(
1682 ; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[X:%.*]])
1683 ; CHECK-NEXT: ret <2 x float> [[R]]
1685 %i = bitcast <2 x float> %x to <2 x i32>
1686 %isneg = icmp ult <2 x i32> %i, <i32 2147483648, i32 2147483648>
1687 %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float 42.0, float 42.0>, <2 x float> <float poison, float -42.0>
1691 define <2 x float> @copysign_vec_poison3(<2 x float> %x) {
1692 ; CHECK-LABEL: @copysign_vec_poison3(
1693 ; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[X:%.*]])
1694 ; CHECK-NEXT: ret <2 x float> [[R]]
1696 %i = bitcast <2 x float> %x to <2 x i32>
1697 %isneg = icmp ugt <2 x i32> %i, <i32 2147483647, i32 2147483647>
1698 %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float -42.0, float poison>, <2 x float> <float +42.0, float poison>
1702 declare void @use1(i1)
1706 define float @copysign_extra_use(float %x) {
1707 ; CHECK-LABEL: @copysign_extra_use(
1708 ; CHECK-NEXT: [[I:%.*]] = bitcast float [[X:%.*]] to i32
1709 ; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i32 [[I]], 0
1710 ; CHECK-NEXT: call void @use1(i1 [[ISNEG]])
1711 ; CHECK-NEXT: [[R:%.*]] = select i1 [[ISNEG]], float -4.400000e+01, float 4.400000e+01
1712 ; CHECK-NEXT: ret float [[R]]
1714 %i = bitcast float %x to i32
1715 %isneg = icmp ugt i32 %i, 2147483647
1716 call void @use1(i1 %isneg)
1717 %r = select i1 %isneg, float -44.0, float 44.0
1723 define float @copysign_type_mismatch(double %x) {
1724 ; CHECK-LABEL: @copysign_type_mismatch(
1725 ; CHECK-NEXT: [[I:%.*]] = bitcast double [[X:%.*]] to i64
1726 ; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i64 [[I]], -1
1727 ; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], float 1.000000e+00, float -1.000000e+00
1728 ; CHECK-NEXT: ret float [[R]]
1730 %i = bitcast double %x to i64
1731 %ispos = icmp sgt i64 %i, -1
1732 %r = select i1 %ispos, float 1.0, float -1.0
1738 define <2 x float> @copysign_type_mismatch2(<2 x float> %x) {
1739 ; CHECK-LABEL: @copysign_type_mismatch2(
1740 ; CHECK-NEXT: [[I:%.*]] = bitcast <2 x float> [[X:%.*]] to i64
1741 ; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i64 [[I]], -1
1742 ; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], <2 x float> splat (float 1.000000e+00), <2 x float> splat (float -1.000000e+00)
1743 ; CHECK-NEXT: ret <2 x float> [[R]]
1745 %i = bitcast <2 x float> %x to i64
1746 %ispos = icmp sgt i64 %i, -1
1747 %r = select i1 %ispos, <2 x float> <float 1.0, float 1.0>, <2 x float> <float -1.0, float -1.0>
1753 define float @copysign_wrong_cmp(float %x) {
1754 ; CHECK-LABEL: @copysign_wrong_cmp(
1755 ; CHECK-NEXT: [[I:%.*]] = bitcast float [[X:%.*]] to i32
1756 ; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i32 [[I]], 0
1757 ; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], float 1.000000e+00, float -1.000000e+00
1758 ; CHECK-NEXT: ret float [[R]]
1760 %i = bitcast float %x to i32
1761 %ispos = icmp sgt i32 %i, 0
1762 %r = select i1 %ispos, float 1.0, float -1.0
1768 define float @copysign_wrong_const(float %x) {
1769 ; CHECK-LABEL: @copysign_wrong_const(
1770 ; CHECK-NEXT: [[I:%.*]] = bitcast float [[X:%.*]] to i32
1771 ; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i32 [[I]], -1
1772 ; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], float 2.000000e+00, float -1.000000e+00
1773 ; CHECK-NEXT: ret float [[R]]
1775 %i = bitcast float %x to i32
1776 %ispos = icmp sgt i32 %i, -1
1777 %r = select i1 %ispos, float 2.0, float -1.0
1781 ; TODO: we can replace select with a Phi.
1782 define i32 @select_dominating_cond(i1 %cond, i32 %x, i32 %y) {
1783 ; CHECK-LABEL: @select_dominating_cond(
1784 ; CHECK-NEXT: entry:
1785 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1787 ; CHECK-NEXT: br label [[MERGE:%.*]]
1789 ; CHECK-NEXT: br label [[MERGE]]
1791 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE]] ], [ [[X:%.*]], [[IF_TRUE]] ]
1792 ; CHECK-NEXT: ret i32 [[S]]
1795 br i1 %cond, label %if.true, label %if.false
1804 %s = select i1 %cond, i32 %x, i32 %y
1808 define i32 @select_dominating_inverted(i1 %cond, i32 %x, i32 %y) {
1809 ; CHECK-LABEL: @select_dominating_inverted(
1810 ; CHECK-NEXT: entry:
1811 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
1813 ; CHECK-NEXT: br label [[MERGE:%.*]]
1815 ; CHECK-NEXT: br label [[MERGE]]
1817 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE]] ], [ [[Y:%.*]], [[IF_TRUE]] ]
1818 ; CHECK-NEXT: ret i32 [[S]]
1821 %inverted = xor i1 %cond, 1
1822 br i1 %inverted, label %if.true, label %if.false
1831 %s = select i1 %cond, i32 %x, i32 %y
1835 ; More complex CFG: the block with select has multiple predecessors.
1836 define i32 @select_dominating_cond_multiple_preds(i1 %cond, i1 %cond2, i1 %cond3, i32 %x, i32 %y) {
1837 ; CHECK-LABEL: @select_dominating_cond_multiple_preds(
1838 ; CHECK-NEXT: entry:
1839 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1841 ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]]
1843 ; CHECK-NEXT: br label [[MERGE:%.*]]
1845 ; CHECK-NEXT: br label [[MERGE]]
1847 ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]]
1848 ; CHECK: if.false.1:
1849 ; CHECK-NEXT: br label [[MERGE]]
1851 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE_1]] ], [ [[X:%.*]], [[IF_TRUE_2]] ], [ [[X]], [[IF_TRUE_1]] ]
1852 ; CHECK-NEXT: ret i32 [[S]]
1854 ; CHECK-NEXT: ret i32 0
1857 br i1 %cond, label %if.true, label %if.false
1860 br i1 %cond2, label %if.true.1, label %if.true.2
1869 br i1 %cond3, label %if.false.1, label %exit
1875 %s = select i1 %cond, i32 %x, i32 %y
1882 ; More complex CFG for inverted case: the block with select has multiple predecessors.
1883 define i32 @select_dominating_cond_inverted_multiple_preds(i1 %cond, i1 %cond2, i1 %cond3, i32 %x, i32 %y) {
1884 ; CHECK-LABEL: @select_dominating_cond_inverted_multiple_preds(
1885 ; CHECK-NEXT: entry:
1886 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
1888 ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]]
1890 ; CHECK-NEXT: br label [[MERGE:%.*]]
1892 ; CHECK-NEXT: br label [[MERGE]]
1894 ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]]
1895 ; CHECK: if.false.1:
1896 ; CHECK-NEXT: br label [[MERGE]]
1898 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE_1]] ], [ [[Y:%.*]], [[IF_TRUE_2]] ], [ [[Y]], [[IF_TRUE_1]] ]
1899 ; CHECK-NEXT: ret i32 [[S]]
1901 ; CHECK-NEXT: ret i32 0
1904 %inverted = xor i1 %cond, 1
1905 br i1 %inverted, label %if.true, label %if.false
1908 br i1 %cond2, label %if.true.1, label %if.true.2
1917 br i1 %cond3, label %if.false.1, label %exit
1923 %s = select i1 %cond, i32 %x, i32 %y
1930 ; More complex CFG for inverted case: the block with select has multiple predecessors that can duplicate.
1931 define i32 @select_dominating_cond_inverted_multiple_duplicating_preds(i1 %cond, i32 %cond2, i1 %cond3, i32 %x, i32 %y) {
1932 ; CHECK-LABEL: @select_dominating_cond_inverted_multiple_duplicating_preds(
1933 ; CHECK-NEXT: entry:
1934 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
1936 ; CHECK-NEXT: switch i32 [[COND2:%.*]], label [[SWITCH_CASE_1:%.*]] [
1937 ; CHECK-NEXT: i32 1, label [[MERGE:%.*]]
1938 ; CHECK-NEXT: i32 2, label [[MERGE]]
1939 ; CHECK-NEXT: i32 3, label [[MERGE]]
1941 ; CHECK: switch.case.1:
1942 ; CHECK-NEXT: br label [[MERGE]]
1944 ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]]
1945 ; CHECK: if.false.1:
1946 ; CHECK-NEXT: br label [[MERGE]]
1948 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE_1]] ], [ [[Y:%.*]], [[SWITCH_CASE_1]] ], [ [[Y]], [[IF_TRUE]] ], [ [[Y]], [[IF_TRUE]] ], [ [[Y]], [[IF_TRUE]] ]
1949 ; CHECK-NEXT: ret i32 [[S]]
1951 ; CHECK-NEXT: ret i32 0
1954 %inverted = xor i1 %cond, 1
1955 br i1 %inverted, label %if.true, label %if.false
1958 switch i32 %cond2, label %switch.case.1 [
1968 br i1 %cond3, label %if.false.1, label %exit
1974 %s = select i1 %cond, i32 %x, i32 %y
1981 ; Negative test: currently we take condition from IDom, but might be willing to expand it in the future.
1982 define i32 @select_not_imm_dominating_cond_neg(i1 %cond, i32 %x, i32 %y) {
1983 ; CHECK-LABEL: @select_not_imm_dominating_cond_neg(
1984 ; CHECK-NEXT: entry:
1985 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1987 ; CHECK-NEXT: br label [[MERGE:%.*]]
1989 ; CHECK-NEXT: br label [[MERGE]]
1991 ; CHECK-NEXT: br label [[EXIT:%.*]]
1993 ; CHECK-NEXT: [[S:%.*]] = select i1 [[COND]], i32 [[X:%.*]], i32 [[Y:%.*]]
1994 ; CHECK-NEXT: ret i32 [[S]]
1997 br i1 %cond, label %if.true, label %if.false
2009 %s = select i1 %cond, i32 %x, i32 %y
2013 ; Shows how we can leverage dominance to eliminate duplicating selects.
2014 define i32 @select_dominance_chain(i1 %cond, i32 %x, i32 %y) {
2015 ; CHECK-LABEL: @select_dominance_chain(
2016 ; CHECK-NEXT: entry:
2017 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]]
2019 ; CHECK-NEXT: br label [[MERGE_1:%.*]]
2020 ; CHECK: if.false.1:
2021 ; CHECK-NEXT: br label [[MERGE_1]]
2023 ; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]]
2025 ; CHECK-NEXT: br label [[MERGE_2:%.*]]
2026 ; CHECK: if.false.2:
2027 ; CHECK-NEXT: br label [[MERGE_2]]
2029 ; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE_3:%.*]], label [[IF_FALSE_3:%.*]]
2031 ; CHECK-NEXT: br label [[MERGE_3:%.*]]
2032 ; CHECK: if.false.3:
2033 ; CHECK-NEXT: br label [[MERGE_3]]
2035 ; CHECK-NEXT: [[S_1:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE_3]] ], [ [[X:%.*]], [[IF_TRUE_3]] ]
2036 ; CHECK-NEXT: [[SUM_2:%.*]] = mul i32 [[S_1]], 3
2037 ; CHECK-NEXT: ret i32 [[SUM_2]]
2040 br i1 %cond, label %if.true.1, label %if.false.1
2049 %s.1 = select i1 %cond, i32 %x, i32 %y
2050 br i1 %cond, label %if.true.2, label %if.false.2
2059 %s.2 = select i1 %cond, i32 %x, i32 %y
2060 br i1 %cond, label %if.true.3, label %if.false.3
2069 %s.3 = select i1 %cond, i32 %x, i32 %y
2070 %sum.1 = add i32 %s.1, %s.2
2071 %sum.2 = add i32 %sum.1, %s.3
2075 ; TODO: We can replace select with a Phi and then sink a and b to respective
2077 define i32 @select_dominating_cond_and_sink(i1 %cond, i32 %x, i32 %y) {
2078 ; CHECK-LABEL: @select_dominating_cond_and_sink(
2079 ; CHECK-NEXT: entry:
2080 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2082 ; CHECK-NEXT: br label [[MERGE:%.*]]
2084 ; CHECK-NEXT: br label [[MERGE]]
2086 ; CHECK-NEXT: [[B:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
2087 ; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], [[Y]]
2088 ; CHECK-NEXT: [[S:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
2089 ; CHECK-NEXT: ret i32 [[S]]
2094 br i1 %cond, label %if.true, label %if.false
2103 %s = select i1 %cond, i32 %a, i32 %b
2107 define i32 @select_dominating_cond_same_labels(i1 %cond) {
2108 ; CHECK-LABEL: @select_dominating_cond_same_labels(
2109 ; CHECK-NEXT: entry:
2110 ; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[EXIT]]
2112 ; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[COND:%.*]], i32 123, i32 456
2113 ; CHECK-NEXT: ret i32 [[RESULT]]
2116 %result = select i1 %cond, i32 123, i32 456
2117 br i1 %cond, label %exit, label %exit
2122 define i32 @select_phi_same_condition(i1 %cond, i32 %x, i32 %y, i32 %z) {
2123 ; CHECK-LABEL: @select_phi_same_condition(
2124 ; CHECK-NEXT: entry:
2125 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2127 ; CHECK-NEXT: br label [[MERGE:%.*]]
2129 ; CHECK-NEXT: br label [[MERGE]]
2131 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_TRUE]] ], [ [[Z:%.*]], [[IF_FALSE]] ]
2132 ; CHECK-NEXT: ret i32 [[S]]
2135 br i1 %cond, label %if.true, label %if.false
2144 %phi = phi i32 [0, %if.true], [%z, %if.false]
2145 %s = select i1 %cond, i32 %x, i32 %phi
2150 ; TODO: Replace with phi[a, c] and sink them to respective branches.
2151 define i32 @select_phi_same_condition_sink(i1 %cond, i32 %x, i32 %y, i32 %z) {
2152 ; CHECK-LABEL: @select_phi_same_condition_sink(
2153 ; CHECK-NEXT: entry:
2154 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2156 ; CHECK-NEXT: br label [[MERGE:%.*]]
2158 ; CHECK-NEXT: [[B:%.*]] = mul i32 [[X:%.*]], [[Z:%.*]]
2159 ; CHECK-NEXT: br label [[MERGE]]
2161 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]
2162 ; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], [[Y:%.*]]
2163 ; CHECK-NEXT: [[S:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[PHI]]
2164 ; CHECK-NEXT: ret i32 [[S]]
2169 br i1 %cond, label %if.true, label %if.false
2178 %phi = phi i32 [0, %if.true], [%b, %if.false]
2179 %s = select i1 %cond, i32 %a, i32 %phi
2183 declare i32 @__gxx_personality_v0(...)
2186 define i32 @test_invoke_neg(i32 %x, i32 %y) nounwind uwtable ssp personality ptr @__gxx_personality_v0 {
2187 ; CHECK-LABEL: @test_invoke_neg(
2188 ; CHECK-NEXT: entry:
2189 ; CHECK-NEXT: [[COND:%.*]] = invoke i1 @foo()
2190 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
2191 ; CHECK: invoke.cont:
2192 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i32 [[X:%.*]], i32 [[Y:%.*]]
2193 ; CHECK-NEXT: ret i32 [[SEL]]
2195 ; CHECK-NEXT: [[LP:%.*]] = landingpad { i1, i32 }
2196 ; CHECK-NEXT: filter [0 x i1] zeroinitializer
2197 ; CHECK-NEXT: unreachable
2200 %cond = invoke i1 @foo()
2201 to label %invoke.cont unwind label %lpad
2204 %sel = select i1 %cond, i32 %x, i32 %y
2208 %lp = landingpad { i1, i32 }
2209 filter [0 x i1] zeroinitializer
2215 define i32 @test_invoke_2_neg(i1 %cond, i32 %x, i32 %y) nounwind uwtable ssp personality ptr @__gxx_personality_v0 {
2216 ; CHECK-LABEL: @test_invoke_2_neg(
2217 ; CHECK-NEXT: entry:
2218 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2220 ; CHECK-NEXT: br label [[MERGE:%.*]]
2222 ; CHECK-NEXT: [[RESULT:%.*]] = invoke i32 @bar()
2223 ; CHECK-NEXT: to label [[MERGE]] unwind label [[LPAD:%.*]]
2225 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[RESULT]], [[IF_FALSE]] ]
2226 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i32 1, i32 [[PHI]]
2227 ; CHECK-NEXT: ret i32 [[SEL]]
2229 ; CHECK-NEXT: [[LP:%.*]] = landingpad { i1, i32 }
2230 ; CHECK-NEXT: filter [0 x i1] zeroinitializer
2231 ; CHECK-NEXT: unreachable
2234 br i1 %cond, label %if.true, label %if.false
2240 %result = invoke i32 @bar()
2241 to label %merge unwind label %lpad
2244 %phi = phi i32 [ 0, %if.true ], [ %result, %if.false ]
2245 %sel = select i1 %cond, i32 1, i32 %phi
2249 %lp = landingpad { i1, i32 }
2250 filter [0 x i1] zeroinitializer
2254 define i32 @select_phi_same_condition_switch(i1 %cond, i32 %x, i32 %y) {
2255 ; CHECK-LABEL: @select_phi_same_condition_switch(
2256 ; CHECK-NEXT: entry:
2257 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2259 ; CHECK-NEXT: switch i32 [[X:%.*]], label [[EXIT:%.*]] [
2260 ; CHECK-NEXT: i32 1, label [[MERGE:%.*]]
2261 ; CHECK-NEXT: i32 2, label [[MERGE]]
2264 ; CHECK-NEXT: ret i32 0
2266 ; CHECK-NEXT: br label [[MERGE]]
2268 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X]], [[IF_TRUE]] ], [ [[X]], [[IF_TRUE]] ], [ [[Y:%.*]], [[IF_FALSE]] ]
2269 ; CHECK-NEXT: ret i32 [[S]]
2272 br i1 %cond, label %if.true, label %if.false
2275 switch i32 %x, label %exit [
2287 %phi = phi i32 [0, %if.true], [0, %if.true], [%y, %if.false]
2288 %s = select i1 %cond, i32 %x, i32 %phi
2292 define i32 @transit_different_values_through_phi(i1 %cond, i1 %cond2) {
2293 ; CHECK-LABEL: @transit_different_values_through_phi(
2294 ; CHECK-NEXT: entry:
2295 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2297 ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]]
2299 ; CHECK-NEXT: br label [[MERGE:%.*]]
2301 ; CHECK-NEXT: br label [[MERGE]]
2303 ; CHECK-NEXT: br label [[MERGE]]
2305 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ 1, [[IF_TRUE_1]] ], [ 2, [[IF_TRUE_2]] ], [ 3, [[IF_FALSE]] ]
2306 ; CHECK-NEXT: ret i32 [[S]]
2308 ; CHECK-NEXT: ret i32 0
2311 br i1 %cond, label %if.true, label %if.false
2314 br i1 %cond2, label %if.true.1, label %if.true.2
2326 %p = phi i32 [ 1, %if.true.1 ], [ 2, %if.true.2 ], [ 4, %if.false ]
2327 %s = select i1 %cond, i32 %p, i32 3
2334 define i32 @select_phi_degenerate(i1 %cond, i1 %cond2) {
2335 ; CHECK-LABEL: @select_phi_degenerate(
2336 ; CHECK-NEXT: entry:
2337 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP:%.*]], label [[EXIT:%.*]]
2339 ; CHECK-NEXT: [[SELECT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[LOOP]] ]
2340 ; CHECK-NEXT: [[IV_INC]] = add i32 [[SELECT]], 1
2341 ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT2:%.*]]
2343 ; CHECK-NEXT: ret i32 0
2345 ; CHECK-NEXT: ret i32 [[IV_INC]]
2348 br i1 %cond, label %loop, label %exit
2351 %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
2352 %select = select i1 %cond, i32 %iv, i32 -1
2353 %iv.inc = add i32 %select, 1
2354 br i1 %cond2, label %loop, label %exit2
2363 define i32 @test_select_into_phi_not_idom(i1 %cond, i32 %A, i32 %B) {
2364 ; CHECK-LABEL: @test_select_into_phi_not_idom(
2365 ; CHECK-NEXT: entry:
2366 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2368 ; CHECK-NEXT: br label [[MERGE:%.*]]
2370 ; CHECK-NEXT: br label [[MERGE]]
2372 ; CHECK-NEXT: br label [[EXIT:%.*]]
2374 ; CHECK-NEXT: ret i32 [[A:%.*]]
2377 br i1 %cond, label %if.true, label %if.false
2386 %phi = phi i32 [%A, %if.true], [%B, %if.false]
2390 %sel = select i1 %cond, i32 %phi, i32 %A
2394 define i32 @test_select_into_phi_not_idom_2(i1 %cond, i32 %A, i32 %B) {
2395 ; CHECK-LABEL: @test_select_into_phi_not_idom_2(
2396 ; CHECK-NEXT: entry:
2397 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2399 ; CHECK-NEXT: br label [[MERGE:%.*]]
2401 ; CHECK-NEXT: br label [[MERGE]]
2403 ; CHECK-NEXT: br label [[EXIT:%.*]]
2405 ; CHECK-NEXT: ret i32 [[B:%.*]]
2408 br i1 %cond, label %if.true, label %if.false
2417 %phi = phi i32 [%A, %if.true], [%B, %if.false]
2421 %sel = select i1 %cond, i32 %B, i32 %phi
2425 define i32 @test_select_into_phi_not_idom_inverted(i1 %cond, i32 %A, i32 %B) {
2426 ; CHECK-LABEL: @test_select_into_phi_not_idom_inverted(
2427 ; CHECK-NEXT: entry:
2428 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
2430 ; CHECK-NEXT: br label [[MERGE:%.*]]
2432 ; CHECK-NEXT: br label [[MERGE]]
2434 ; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[A:%.*]], [[IF_TRUE]] ], [ [[B:%.*]], [[IF_FALSE]] ]
2435 ; CHECK-NEXT: br label [[EXIT:%.*]]
2437 ; CHECK-NEXT: ret i32 [[SEL]]
2440 %inverted = xor i1 %cond, 1
2441 br i1 %inverted, label %if.true, label %if.false
2450 %phi = phi i32 [%A, %if.true], [%B, %if.false]
2454 %sel = select i1 %cond, i32 %phi, i32 %A
2458 define i32 @test_select_into_phi_not_idom_inverted_2(i1 %cond, i32 %A, i32 %B) {
2459 ; CHECK-LABEL: @test_select_into_phi_not_idom_inverted_2(
2460 ; CHECK-NEXT: entry:
2461 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
2463 ; CHECK-NEXT: br label [[MERGE:%.*]]
2465 ; CHECK-NEXT: br label [[MERGE]]
2467 ; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[A:%.*]], [[IF_TRUE]] ], [ [[B:%.*]], [[IF_FALSE]] ]
2468 ; CHECK-NEXT: br label [[EXIT:%.*]]
2470 ; CHECK-NEXT: ret i32 [[SEL]]
2473 %inverted = xor i1 %cond, 1
2474 br i1 %inverted, label %if.true, label %if.false
2483 %phi = phi i32 [%A, %if.true], [%B, %if.false]
2487 %sel = select i1 %cond, i32 %B, i32 %phi
2491 define i32 @test_select_into_phi_not_idom_no_dom_input_1(i1 %cond, i32 %A, i32 %B, ptr %p) {
2492 ; CHECK-LABEL: @test_select_into_phi_not_idom_no_dom_input_1(
2493 ; CHECK-NEXT: entry:
2494 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2496 ; CHECK-NEXT: [[C:%.*]] = load i32, ptr [[P:%.*]], align 4
2497 ; CHECK-NEXT: br label [[MERGE:%.*]]
2499 ; CHECK-NEXT: br label [[MERGE]]
2501 ; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[C]], [[IF_TRUE]] ], [ [[A:%.*]], [[IF_FALSE]] ]
2502 ; CHECK-NEXT: br label [[EXIT:%.*]]
2504 ; CHECK-NEXT: ret i32 [[SEL]]
2507 br i1 %cond, label %if.true, label %if.false
2510 %C = load i32, ptr %p
2517 %phi = phi i32 [%C, %if.true], [%B, %if.false]
2521 %sel = select i1 %cond, i32 %phi, i32 %A
2525 define i32 @test_select_into_phi_not_idom_no_dom_input_2(i1 %cond, i32 %A, i32 %B, ptr %p) {
2526 ; CHECK-LABEL: @test_select_into_phi_not_idom_no_dom_input_2(
2527 ; CHECK-NEXT: entry:
2528 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
2530 ; CHECK-NEXT: br label [[MERGE:%.*]]
2532 ; CHECK-NEXT: [[C:%.*]] = load i32, ptr [[P:%.*]], align 4
2533 ; CHECK-NEXT: br label [[MERGE]]
2535 ; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[B:%.*]], [[IF_TRUE]] ], [ [[C]], [[IF_FALSE]] ]
2536 ; CHECK-NEXT: br label [[EXIT:%.*]]
2538 ; CHECK-NEXT: ret i32 [[SEL]]
2541 br i1 %cond, label %if.true, label %if.false
2547 %C = load i32, ptr %p
2551 %phi = phi i32 [%A, %if.true], [%C, %if.false]
2555 %sel = select i1 %cond, i32 %B, i32 %phi
2559 ; Negative tests to ensure we don't remove selects with undef true/false values.
2560 ; See https://bugs.llvm.org/show_bug.cgi?id=31633
2561 ; https://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html
2562 ; https://reviews.llvm.org/D83360
2563 define i32 @false_undef(i1 %cond, i32 %x) {
2564 ; CHECK-LABEL: @false_undef(
2565 ; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 undef
2566 ; CHECK-NEXT: ret i32 [[S]]
2568 %s = select i1 %cond, i32 %x, i32 undef
2572 define i32 @true_undef(i1 %cond, i32 %x) {
2573 ; CHECK-LABEL: @true_undef(
2574 ; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 undef, i32 [[X:%.*]]
2575 ; CHECK-NEXT: ret i32 [[S]]
2577 %s = select i1 %cond, i32 undef, i32 %x
2581 define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) {
2582 ; CHECK-LABEL: @false_undef_vec(
2583 ; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> [[X:%.*]], <2 x i32> undef
2584 ; CHECK-NEXT: ret <2 x i32> [[S]]
2586 %s = select i1 %cond, <2 x i32> %x, <2 x i32> undef
2590 define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) {
2591 ; CHECK-LABEL: @true_undef_vec(
2592 ; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> undef, <2 x i32> [[X:%.*]]
2593 ; CHECK-NEXT: ret <2 x i32> [[S]]
2595 %s = select i1 %cond, <2 x i32> undef, <2 x i32> %x
2599 define i8 @cond_freeze(i8 %x, i8 %y) {
2600 ; CHECK-LABEL: @cond_freeze(
2601 ; CHECK-NEXT: ret i8 [[Y:%.*]]
2603 %cond.fr = freeze i1 undef
2604 %s = select i1 %cond.fr, i8 %x, i8 %y
2608 define i8 @cond_freeze_constant_false_val(i8 %x) {
2609 ; CHECK-LABEL: @cond_freeze_constant_false_val(
2610 ; CHECK-NEXT: ret i8 1
2612 %cond.fr = freeze i1 undef
2613 %s = select i1 %cond.fr, i8 %x, i8 1
2617 define i8 @cond_freeze_constant_true_val(i8 %x) {
2618 ; CHECK-LABEL: @cond_freeze_constant_true_val(
2619 ; CHECK-NEXT: ret i8 1
2621 %cond.fr = freeze i1 undef
2622 %s = select i1 %cond.fr, i8 1, i8 %x
2626 define i8 @cond_freeze_both_arms_constant() {
2627 ; CHECK-LABEL: @cond_freeze_both_arms_constant(
2628 ; CHECK-NEXT: ret i8 42
2630 %cond.fr = freeze i1 undef
2631 %s = select i1 %cond.fr, i8 42, i8 3
2635 define <2 x i8> @cond_freeze_constant_true_val_vec(<2 x i8> %x) {
2636 ; CHECK-LABEL: @cond_freeze_constant_true_val_vec(
2637 ; CHECK-NEXT: ret <2 x i8> <i8 1, i8 2>
2639 %cond.fr = freeze <2 x i1> <i1 undef, i1 undef>
2640 %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> %x
2644 define <2 x i8> @partial_cond_freeze_constant_true_val_vec(<2 x i8> %x) {
2645 ; CHECK-LABEL: @partial_cond_freeze_constant_true_val_vec(
2646 ; CHECK-NEXT: ret <2 x i8> <i8 1, i8 2>
2648 %cond.fr = freeze <2 x i1> <i1 true, i1 undef>
2649 %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> %x
2653 define <2 x i8> @partial_cond_freeze_constant_false_val_vec(<2 x i8> %x) {
2654 ; CHECK-LABEL: @partial_cond_freeze_constant_false_val_vec(
2655 ; CHECK-NEXT: [[S1:%.*]] = insertelement <2 x i8> [[X:%.*]], i8 2, i64 1
2656 ; CHECK-NEXT: ret <2 x i8> [[S1]]
2658 %cond.fr = freeze <2 x i1> <i1 true, i1 undef>
2659 %s = select <2 x i1> %cond.fr, <2 x i8> %x, <2 x i8> <i8 1, i8 2>
2663 define <2 x i8> @partial_cond_freeze_both_arms_constant_vec() {
2664 ; CHECK-LABEL: @partial_cond_freeze_both_arms_constant_vec(
2665 ; CHECK-NEXT: ret <2 x i8> <i8 42, i8 2>
2667 %cond.fr = freeze <2 x i1> <i1 false, i1 undef>
2668 %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> <i8 42, i8 43>
2672 declare void @foo2(i8, i8)
2674 define void @cond_freeze_multipleuses(i8 %x, i8 %y) {
2675 ; CHECK-LABEL: @cond_freeze_multipleuses(
2676 ; CHECK-NEXT: call void @foo2(i8 [[Y:%.*]], i8 [[X:%.*]])
2677 ; CHECK-NEXT: ret void
2679 %cond.fr = freeze i1 undef
2680 %s = select i1 %cond.fr, i8 %x, i8 %y
2681 %s2 = select i1 %cond.fr, i8 %y, i8 %x
2682 call void @foo2(i8 %s, i8 %s2)
2686 define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) {
2687 ; CHECK-LABEL: @select_freeze_icmp_eq(
2688 ; CHECK-NEXT: ret i32 [[Y:%.*]]
2690 %c = icmp eq i32 %x, %y
2691 %c.fr = freeze i1 %c
2692 %v = select i1 %c.fr, i32 %x, i32 %y
2696 define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) {
2697 ; CHECK-LABEL: @select_freeze_icmp_ne(
2698 ; CHECK-NEXT: ret i32 [[X:%.*]]
2700 %c = icmp ne i32 %x, %y
2701 %c.fr = freeze i1 %c
2702 %v = select i1 %c.fr, i32 %x, i32 %y
2706 define i32 @select_freeze_icmp_else(i32 %x, i32 %y) {
2707 ; CHECK-LABEL: @select_freeze_icmp_else(
2708 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2709 ; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]]
2710 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]]
2711 ; CHECK-NEXT: ret i32 [[V]]
2713 %c = icmp ult i32 %x, %y
2714 %c.fr = freeze i1 %c
2715 %v = select i1 %c.fr, i32 %x, i32 %y
2719 declare void @use_i1_i32(i1, i32)
2721 define void @select_freeze_icmp_multuses(i32 %x, i32 %y) {
2722 ; CHECK-LABEL: @select_freeze_icmp_multuses(
2723 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
2724 ; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]]
2725 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]]
2726 ; CHECK-NEXT: call void @use_i1_i32(i1 [[C_FR]], i32 [[V]])
2727 ; CHECK-NEXT: ret void
2729 %c = icmp ne i32 %x, %y
2730 %c.fr = freeze i1 %c
2731 %v = select i1 %c.fr, i32 %x, i32 %y
2732 call void @use_i1_i32(i1 %c.fr, i32 %v)
2736 define i32 @pr47322_more_poisonous_replacement(i32 %arg) {
2737 ; CHECK-LABEL: @pr47322_more_poisonous_replacement(
2738 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ARG:%.*]], 0
2739 ; CHECK-NEXT: [[TRAILING:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[ARG]], i1 true)
2740 ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[ARG]], [[TRAILING]]
2741 ; CHECK-NEXT: [[R1_SROA_0_1:%.*]] = select i1 [[CMP]], i32 0, i32 [[SHIFTED]]
2742 ; CHECK-NEXT: ret i32 [[R1_SROA_0_1]]
2744 %cmp = icmp eq i32 %arg, 0
2745 %trailing = call i32 @llvm.cttz.i32(i32 %arg, i1 true)
2746 %shifted = lshr i32 %arg, %trailing
2747 %r1.sroa.0.1 = select i1 %cmp, i32 0, i32 %shifted
2748 ret i32 %r1.sroa.0.1
2751 define i8 @select_replacement_add_eq(i8 %x, i8 %y) {
2752 ; CHECK-LABEL: @select_replacement_add_eq(
2753 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 1
2754 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y:%.*]]
2755 ; CHECK-NEXT: ret i8 [[SEL]]
2757 %cmp = icmp eq i8 %x, 1
2759 %sel = select i1 %cmp, i8 %add, i8 %y
2763 define <2 x i8> @select_replacement_add_eq_vec(<2 x i8> %x, <2 x i8> %y) {
2764 ; CHECK-LABEL: @select_replacement_add_eq_vec(
2765 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 1)
2766 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> splat (i8 2), <2 x i8> [[Y:%.*]]
2767 ; CHECK-NEXT: ret <2 x i8> [[SEL]]
2769 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 1>
2770 %add = add <2 x i8> %x, <i8 1, i8 1>
2771 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2775 define <2 x i8> @select_replacement_add_eq_vec_nonuniform(<2 x i8> %x, <2 x i8> %y) {
2776 ; CHECK-LABEL: @select_replacement_add_eq_vec_nonuniform(
2777 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 2>
2778 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 4, i8 6>, <2 x i8> [[Y:%.*]]
2779 ; CHECK-NEXT: ret <2 x i8> [[SEL]]
2781 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 2>
2782 %add = add <2 x i8> %x, <i8 3, i8 4>
2783 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2787 define <2 x i8> @select_replacement_add_eq_vec_poison(<2 x i8> %x, <2 x i8> %y) {
2788 ; CHECK-LABEL: @select_replacement_add_eq_vec_poison(
2789 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 poison>
2790 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 2, i8 poison>, <2 x i8> [[Y:%.*]]
2791 ; CHECK-NEXT: ret <2 x i8> [[SEL]]
2793 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 poison>
2794 %add = add <2 x i8> %x, <i8 1, i8 1>
2795 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2799 define <2 x i8> @select_replacement_add_eq_vec_undef(<2 x i8> %x, <2 x i8> %y) {
2800 ; CHECK-LABEL: @select_replacement_add_eq_vec_undef(
2801 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 undef>
2802 ; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[X]], splat (i8 1)
2803 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[ADD]], <2 x i8> [[Y:%.*]]
2804 ; CHECK-NEXT: ret <2 x i8> [[SEL]]
2806 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 undef>
2807 %add = add <2 x i8> %x, <i8 1, i8 1>
2808 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2812 define <2 x i8> @select_replacement_add_eq_vec_undef_okay(<2 x i8> %x, <2 x i8> %y) {
2813 ; CHECK-LABEL: @select_replacement_add_eq_vec_undef_okay(
2814 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 1)
2815 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 2, i8 undef>, <2 x i8> [[Y:%.*]]
2816 ; CHECK-NEXT: ret <2 x i8> [[SEL]]
2818 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 1>
2819 %add = add <2 x i8> %x, <i8 1, i8 undef>
2820 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2825 define <2 x i8> @select_replacement_add_eq_vec_undef_okay_todo(<2 x i8> %x, <2 x i8> %y) {
2826 ; CHECK-LABEL: @select_replacement_add_eq_vec_undef_okay_todo(
2827 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 undef>
2828 ; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[X]], <i8 1, i8 undef>
2829 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[ADD]], <2 x i8> [[Y:%.*]]
2830 ; CHECK-NEXT: ret <2 x i8> [[SEL]]
2832 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 undef>
2833 %add = add <2 x i8> %x, <i8 1, i8 undef>
2834 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y
2838 define <2 x i8> @select_replacement_xor_eq_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
2839 ; CHECK-LABEL: @select_replacement_xor_eq_vec(
2840 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], [[Y:%.*]]
2841 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> zeroinitializer, <2 x i8> [[Z:%.*]]
2842 ; CHECK-NEXT: ret <2 x i8> [[SEL]]
2844 %cmp = icmp eq <2 x i8> %x, %y
2845 %add = xor <2 x i8> %x, %y
2846 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %z
2851 define i8 @select_replacement_add_ne(i8 %x, i8 %y) {
2852 ; CHECK-LABEL: @select_replacement_add_ne(
2853 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 1
2854 ; CHECK-NEXT: call void @use(i1 [[CMP]])
2855 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[Y:%.*]], i8 2
2856 ; CHECK-NEXT: ret i8 [[SEL]]
2858 %cmp = icmp ne i8 %x, 1
2859 call void @use(i1 %cmp)
2861 %sel = select i1 %cmp, i8 %y, i8 %add
2865 define i8 @select_replacement_add_nuw(i8 %x, i8 %y) {
2866 ; CHECK-LABEL: @select_replacement_add_nuw(
2867 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 1
2868 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y:%.*]]
2869 ; CHECK-NEXT: ret i8 [[SEL]]
2871 %cmp = icmp eq i8 %x, 1
2872 %add = add nuw i8 %x, 1
2873 %sel = select i1 %cmp, i8 %add, i8 %y
2877 define i8 @select_replacement_sub_noundef(i8 %x, i8 noundef %y, i8 %z) {
2878 ; CHECK-LABEL: @select_replacement_sub_noundef(
2879 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
2880 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z:%.*]]
2881 ; CHECK-NEXT: ret i8 [[SEL]]
2883 %cmp = icmp eq i8 %x, %y
2884 %sub = sub i8 %x, %y
2885 %sel = select i1 %cmp, i8 %sub, i8 %z
2889 define i8 @select_replacement_sub_noundef_but_may_be_poison(i8 %x, i8 noundef %yy, i8 %z) {
2890 ; CHECK-LABEL: @select_replacement_sub_noundef_but_may_be_poison(
2891 ; CHECK-NEXT: [[Y:%.*]] = shl nuw i8 [[YY:%.*]], 1
2892 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y]]
2893 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z:%.*]]
2894 ; CHECK-NEXT: ret i8 [[SEL]]
2896 %y = shl nuw i8 %yy, 1
2897 %cmp = icmp eq i8 %x, %y
2898 %sub = sub i8 %x, %y
2899 %sel = select i1 %cmp, i8 %sub, i8 %z
2903 ; TODO: The transform is also safe without noundef.
2904 define i8 @select_replacement_sub(i8 %x, i8 %y, i8 %z) {
2905 ; CHECK-LABEL: @select_replacement_sub(
2906 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
2907 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z:%.*]]
2908 ; CHECK-NEXT: ret i8 [[SEL]]
2910 %cmp = icmp eq i8 %x, %y
2911 %sub = sub i8 %x, %y
2912 %sel = select i1 %cmp, i8 %sub, i8 %z
2916 ; FIXME: This is safe to fold.
2917 define i8 @select_replacement_shift_noundef(i8 %x, i8 %y, i8 %z) {
2918 ; CHECK-LABEL: @select_replacement_shift_noundef(
2919 ; CHECK-NEXT: [[SHR:%.*]] = lshr exact i8 [[X:%.*]], 1
2920 ; CHECK-NEXT: call void @use_i8(i8 noundef [[SHR]])
2921 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y:%.*]]
2922 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[Y]], 1
2923 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z:%.*]]
2924 ; CHECK-NEXT: ret i8 [[SEL]]
2926 %shr = lshr exact i8 %x, 1
2927 call void @use_i8(i8 noundef %shr)
2928 %cmp = icmp eq i8 %shr, %y
2930 %sel = select i1 %cmp, i8 %shl, i8 %z
2934 ; TODO: The transform is also safe without noundef.
2935 define i8 @select_replacement_shift(i8 %x, i8 %y, i8 %z) {
2936 ; CHECK-LABEL: @select_replacement_shift(
2937 ; CHECK-NEXT: [[SHR:%.*]] = lshr exact i8 [[X:%.*]], 1
2938 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y:%.*]]
2939 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[Y]], 1
2940 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z:%.*]]
2941 ; CHECK-NEXT: ret i8 [[SEL]]
2943 %shr = lshr exact i8 %x, 1
2944 %cmp = icmp eq i8 %shr, %y
2946 %sel = select i1 %cmp, i8 %shl, i8 %z
2950 define i8 @select_replacement_loop(i8 %x, i8 %y, i8 %z) {
2951 ; CHECK-LABEL: @select_replacement_loop(
2952 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
2953 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[Z:%.*]]
2954 ; CHECK-NEXT: ret i8 [[SEL]]
2956 %cmp = icmp eq i8 %x, %y
2957 %sel = select i1 %cmp, i8 %x, i8 %z
2961 define i32 @select_replacement_loop2(i32 %arg, i32 %arg2) {
2962 ; CHECK-LABEL: @select_replacement_loop2(
2963 ; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[ARG:%.*]], [[ARG2:%.*]]
2964 ; CHECK-NEXT: ret i32 [[DIV]]
2966 %div = udiv i32 %arg, %arg2
2967 %mul = mul nsw i32 %div, %arg2
2968 %cmp = icmp eq i32 %mul, %arg
2969 %sel = select i1 %cmp, i32 %div, i32 undef
2973 define i8 @select_replacement_loop3(i32 noundef %x) {
2974 ; CHECK-LABEL: @select_replacement_loop3(
2975 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[X:%.*]] to i8
2976 ; CHECK-NEXT: [[REV:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TRUNC]])
2977 ; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[REV]] to i32
2978 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[EXT]]
2979 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[TRUNC]], i8 0
2980 ; CHECK-NEXT: ret i8 [[SEL]]
2982 %trunc = trunc i32 %x to i8
2983 %rev = call i8 @llvm.bitreverse.i8(i8 %trunc)
2984 %ext = zext i8 %rev to i32
2985 %cmp = icmp eq i32 %ext, %x
2986 %sel = select i1 %cmp, i8 %trunc, i8 0
2990 define i16 @select_replacement_loop4(i16 noundef %p_12) {
2991 ; CHECK-LABEL: @select_replacement_loop4(
2992 ; CHECK-NEXT: [[AND1:%.*]] = and i16 [[P_12:%.*]], 1
2993 ; CHECK-NEXT: [[CMP21:%.*]] = icmp ult i16 [[P_12]], 2
2994 ; CHECK-NEXT: [[AND3:%.*]] = select i1 [[CMP21]], i16 [[AND1]], i16 0
2995 ; CHECK-NEXT: ret i16 [[AND3]]
2997 %cmp1 = icmp ult i16 %p_12, 2
2998 %and1 = and i16 %p_12, 1
2999 %and2 = select i1 %cmp1, i16 %and1, i16 0
3000 %cmp2 = icmp eq i16 %and2, %p_12
3001 %and3 = select i1 %cmp2, i16 %and1, i16 0
3005 define ptr @select_replacement_gep_inbounds(ptr %base, i64 %offset) {
3006 ; CHECK-LABEL: @select_replacement_gep_inbounds(
3007 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[BASE:%.*]], i64 [[OFFSET:%.*]]
3008 ; CHECK-NEXT: ret ptr [[GEP]]
3010 %cmp = icmp eq i64 %offset, 0
3011 %gep = getelementptr inbounds i8, ptr %base, i64 %offset
3012 %sel = select i1 %cmp, ptr %base, ptr %gep
3016 define i8 @replace_false_op_eq_shl_or_disjoint(i8 %x) {
3017 ; CHECK-LABEL: @replace_false_op_eq_shl_or_disjoint(
3018 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 3
3019 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X]], [[SHL]]
3020 ; CHECK-NEXT: ret i8 [[OR]]
3022 %eq0 = icmp eq i8 %x, -1
3024 %or = or disjoint i8 %x, %shl
3025 %sel = select i1 %eq0, i8 -1, i8 %or
3029 define i8 @select_or_disjoint_eq(i8 %x, i8 %y) {
3030 ; CHECK-LABEL: @select_or_disjoint_eq(
3031 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
3032 ; CHECK-NEXT: ret i8 [[OR]]
3034 %cmp = icmp eq i8 %x, %y
3035 %or = or disjoint i8 %x, %y
3036 %sel = select i1 %cmp, i8 %x, i8 %or
3040 define <2 x i1> @partial_true_undef_condval(<2 x i1> %x) {
3041 ; CHECK-LABEL: @partial_true_undef_condval(
3042 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 poison>
3044 %r = select <2 x i1> <i1 true, i1 poison>, <2 x i1> <i1 true, i1 poison>, <2 x i1> %x
3048 define <2 x i1> @partial_false_undef_condval(<2 x i1> %x) {
3049 ; CHECK-LABEL: @partial_false_undef_condval(
3050 ; CHECK-NEXT: ret <2 x i1> <i1 false, i1 poison>
3052 %r = select <2 x i1> <i1 false, i1 poison>, <2 x i1> %x, <2 x i1> <i1 false, i1 poison>
3056 ; select (x == 0), 0, x * y --> freeze(y) * x
3057 define i32 @mul_select_eq_zero(i32 %x, i32 %y) {
3058 ; CHECK-LABEL: @mul_select_eq_zero(
3059 ; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
3060 ; CHECK-NEXT: [[M:%.*]] = mul i32 [[X:%.*]], [[Y_FR]]
3061 ; CHECK-NEXT: ret i32 [[M]]
3063 %c = icmp eq i32 %x, 0
3065 %r = select i1 %c, i32 0, i32 %m
3069 ; select (y == 0), 0, x * y --> freeze(x) * y
3070 define i32 @mul_select_eq_zero_commute(i32 %x, i32 %y) {
3071 ; CHECK-LABEL: @mul_select_eq_zero_commute(
3072 ; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]]
3073 ; CHECK-NEXT: [[M:%.*]] = mul i32 [[X_FR]], [[Y:%.*]]
3074 ; CHECK-NEXT: ret i32 [[M]]
3076 %c = icmp eq i32 %y, 0
3078 %r = select i1 %c, i32 0, i32 %m
3082 ; Check that mul's flags preserved during the transformation.
3083 define i32 @mul_select_eq_zero_copy_flags(i32 %x, i32 %y) {
3084 ; CHECK-LABEL: @mul_select_eq_zero_copy_flags(
3085 ; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
3086 ; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X:%.*]], [[Y_FR]]
3087 ; CHECK-NEXT: ret i32 [[M]]
3089 %c = icmp eq i32 %x, 0
3090 %m = mul nuw nsw i32 %x, %y
3091 %r = select i1 %c, i32 0, i32 %m
3095 ; Check that the transformation could be applied after condition's inversion.
3096 ; select (x != 0), x * y, 0 --> freeze(y) * x
3097 define i32 @mul_select_ne_zero(i32 %x, i32 %y) {
3098 ; CHECK-LABEL: @mul_select_ne_zero(
3099 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X:%.*]], 0
3100 ; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
3101 ; CHECK-NEXT: [[M:%.*]] = mul i32 [[X]], [[Y_FR]]
3102 ; CHECK-NEXT: call void @use(i1 [[C]])
3103 ; CHECK-NEXT: ret i32 [[M]]
3105 %c = icmp ne i32 %x, 0
3107 %r = select i1 %c, i32 %m, i32 0
3108 call void @use(i1 %c)
3112 ; Check that if one of a select's branches returns undef then
3113 ; an expression could be folded into mul as if there was a 0 instead of undef.
3114 ; select (x == 0), undef, x * y --> freeze(y) * x
3115 define i32 @mul_select_eq_zero_sel_undef(i32 %x, i32 %y) {
3116 ; CHECK-LABEL: @mul_select_eq_zero_sel_undef(
3117 ; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
3118 ; CHECK-NEXT: [[M:%.*]] = mul i32 [[X:%.*]], [[Y_FR]]
3119 ; CHECK-NEXT: ret i32 [[M]]
3121 %c = icmp eq i32 %x, 0
3123 %r = select i1 %c, i32 undef, i32 %m
3127 ; Check that the transformation is applied disregard to a number
3128 ; of expression's users.
3129 define i32 @mul_select_eq_zero_multiple_users(i32 %x, i32 %y) {
3130 ; CHECK-LABEL: @mul_select_eq_zero_multiple_users(
3131 ; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
3132 ; CHECK-NEXT: [[M:%.*]] = mul i32 [[X:%.*]], [[Y_FR]]
3133 ; CHECK-NEXT: call void @use_i32(i32 [[M]])
3134 ; CHECK-NEXT: call void @use_i32(i32 [[M]])
3135 ; CHECK-NEXT: call void @use_i32(i32 [[M]])
3136 ; CHECK-NEXT: ret i32 [[M]]
3139 call void @use_i32(i32 %m)
3140 %c = icmp eq i32 %x, 0
3141 %r = select i1 %c, i32 0, i32 %m
3142 call void @use_i32(i32 %m)
3143 call void @use_i32(i32 %r)
3147 ; Negative test: select's condition is unrelated to multiplied values,
3148 ; so the transformation should not be applied.
3149 define i32 @mul_select_eq_zero_unrelated_condition(i32 %x, i32 %y, i32 %z) {
3150 ; CHECK-LABEL: @mul_select_eq_zero_unrelated_condition(
3151 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[Z:%.*]], 0
3152 ; CHECK-NEXT: [[M:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
3153 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 0, i32 [[M]]
3154 ; CHECK-NEXT: ret i32 [[R]]
3156 %c = icmp eq i32 %z, 0
3158 %r = select i1 %c, i32 0, i32 %m
3162 ; select (<k x elt> x == 0), <k x elt> 0, <k x elt> x * y --> freeze(y) * x
3163 define <4 x i32> @mul_select_eq_zero_vector(<4 x i32> %x, <4 x i32> %y) {
3164 ; CHECK-LABEL: @mul_select_eq_zero_vector(
3165 ; CHECK-NEXT: [[Y_FR:%.*]] = freeze <4 x i32> [[Y:%.*]]
3166 ; CHECK-NEXT: [[M:%.*]] = mul <4 x i32> [[X:%.*]], [[Y_FR]]
3167 ; CHECK-NEXT: ret <4 x i32> [[M]]
3169 %c = icmp eq <4 x i32> %x, zeroinitializer
3170 %m = mul <4 x i32> %x, %y
3171 %r = select <4 x i1> %c, <4 x i32> zeroinitializer, <4 x i32> %m
3175 ; Check that a select is folded into multiplication if condition's operand
3176 ; is a vector consisting of zeros and poisons.
3177 ; select (<k x elt> x == {0, poison, ...}), <k x elt> 0, <k x elt> x * y --> freeze(y) * x
3178 define <2 x i32> @mul_select_eq_poison_vector(<2 x i32> %x, <2 x i32> %y) {
3179 ; CHECK-LABEL: @mul_select_eq_poison_vector(
3180 ; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 0, i32 poison>
3181 ; CHECK-NEXT: [[M:%.*]] = mul <2 x i32> [[X]], [[Y:%.*]]
3182 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C]], <2 x i32> <i32 0, i32 42>, <2 x i32> [[M]]
3183 ; CHECK-NEXT: ret <2 x i32> [[R]]
3185 %c = icmp eq <2 x i32> %x, <i32 0, i32 poison>
3186 %m = mul <2 x i32> %x, %y
3187 %r = select <2 x i1> %c, <2 x i32> <i32 0, i32 42>, <2 x i32> %m
3191 ; Check that a select is folded into multiplication if other select's operand
3192 ; is a vector consisting of zeros and poisons.
3193 ; select (<k x elt> x == 0), <k x elt> {0, poison, ...}, <k x elt> x * y --> freeze(y) * x
3194 define <2 x i32> @mul_select_eq_zero_sel_poison_vector(<2 x i32> %x, <2 x i32> %y) {
3195 ; CHECK-LABEL: @mul_select_eq_zero_sel_poison_vector(
3196 ; CHECK-NEXT: [[Y_FR:%.*]] = freeze <2 x i32> [[Y:%.*]]
3197 ; CHECK-NEXT: [[M:%.*]] = mul <2 x i32> [[X:%.*]], [[Y_FR]]
3198 ; CHECK-NEXT: ret <2 x i32> [[M]]
3200 %c = icmp eq <2 x i32> %x, zeroinitializer
3201 %m = mul <2 x i32> %x, %y
3202 %r = select <2 x i1> %c, <2 x i32> <i32 0, i32 poison>, <2 x i32> %m
3206 ; Negative test: select should not be folded into mul because
3207 ; condition's operand and select's operand do not merge into zero vector.
3208 define <2 x i32> @mul_select_eq_poison_vector_not_merging_to_zero(<2 x i32> %x, <2 x i32> %y) {
3209 ; CHECK-LABEL: @mul_select_eq_poison_vector_not_merging_to_zero(
3210 ; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 0, i32 poison>
3211 ; CHECK-NEXT: [[M:%.*]] = mul <2 x i32> [[X]], [[Y:%.*]]
3212 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C]], <2 x i32> <i32 1, i32 0>, <2 x i32> [[M]]
3213 ; CHECK-NEXT: ret <2 x i32> [[R]]
3215 %c = icmp eq <2 x i32> %x, <i32 0, i32 poison>
3216 %m = mul <2 x i32> %x, %y
3217 %r = select <2 x i1> %c, <2 x i32> <i32 1, i32 0>, <2 x i32> %m
3221 define i8 @ne0_is_all_ones(i8 %x) {
3222 ; CHECK-LABEL: @ne0_is_all_ones(
3223 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
3224 ; CHECK-NEXT: [[R:%.*]] = sext i1 [[TMP1]] to i8
3225 ; CHECK-NEXT: ret i8 [[R]]
3227 %negx = sub i8 0, %x
3228 %ugt1 = icmp ugt i8 %x, 1
3229 %r = select i1 %ugt1, i8 -1, i8 %negx
3233 define i8 @ne0_is_all_ones_use1(i8 %x) {
3234 ; CHECK-LABEL: @ne0_is_all_ones_use1(
3235 ; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
3236 ; CHECK-NEXT: call void @use_i8(i8 [[NEGX]])
3237 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X]], 0
3238 ; CHECK-NEXT: [[R:%.*]] = sext i1 [[TMP1]] to i8
3239 ; CHECK-NEXT: ret i8 [[R]]
3241 %negx = sub i8 0, %x
3242 call void @use_i8(i8 %negx)
3243 %ugt1 = icmp ugt i8 %x, 1
3244 %r = select i1 %ugt1, i8 -1, i8 %negx
3250 define i8 @ne0_is_all_ones_use2(i8 %x) {
3251 ; CHECK-LABEL: @ne0_is_all_ones_use2(
3252 ; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
3253 ; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i8 [[X]], 1
3254 ; CHECK-NEXT: call void @use(i1 [[UGT1]])
3255 ; CHECK-NEXT: [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]]
3256 ; CHECK-NEXT: ret i8 [[R]]
3258 %negx = sub i8 0, %x
3259 %ugt1 = icmp ugt i8 %x, 1
3260 call void @use(i1 %ugt1)
3261 %r = select i1 %ugt1, i8 -1, i8 %negx
3267 define i8 @ne0_is_all_ones_wrong_pred(i8 %x) {
3268 ; CHECK-LABEL: @ne0_is_all_ones_wrong_pred(
3269 ; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
3270 ; CHECK-NEXT: [[UGT1:%.*]] = icmp sgt i8 [[X]], 2
3271 ; CHECK-NEXT: [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]]
3272 ; CHECK-NEXT: ret i8 [[R]]
3274 %negx = sub i8 0, %x
3275 %ugt1 = icmp sgt i8 %x, 2
3276 %r = select i1 %ugt1, i8 -1, i8 %negx
3282 define i8 @ne0_is_all_ones_wrong_cmp(i8 %x) {
3283 ; CHECK-LABEL: @ne0_is_all_ones_wrong_cmp(
3284 ; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
3285 ; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i8 [[X]], 2
3286 ; CHECK-NEXT: [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]]
3287 ; CHECK-NEXT: ret i8 [[R]]
3289 %negx = sub i8 0, %x
3290 %ugt1 = icmp ugt i8 %x, 2
3291 %r = select i1 %ugt1, i8 -1, i8 %negx
3297 define i8 @ne0_is_all_ones_wrong_sel(i8 %x) {
3298 ; CHECK-LABEL: @ne0_is_all_ones_wrong_sel(
3299 ; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
3300 ; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i8 [[X]], 2
3301 ; CHECK-NEXT: [[R:%.*]] = select i1 [[UGT1]], i8 1, i8 [[NEGX]]
3302 ; CHECK-NEXT: ret i8 [[R]]
3304 %negx = sub i8 0, %x
3305 %ugt1 = icmp ugt i8 %x, 2
3306 %r = select i1 %ugt1, i8 1, i8 %negx
3310 define <2 x i8> @ne0_is_all_ones_swap_vec(<2 x i8> %x) {
3311 ; CHECK-LABEL: @ne0_is_all_ones_swap_vec(
3312 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer
3313 ; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>
3314 ; CHECK-NEXT: ret <2 x i8> [[R]]
3316 %negx = sub <2 x i8> zeroinitializer, %x
3317 %ult2 = icmp ult <2 x i8> %x, <i8 2, i8 2>
3318 %r = select <2 x i1> %ult2, <2 x i8> %negx, <2 x i8> <i8 -1, i8 -1>
3322 define <2 x i8> @ne0_is_all_ones_swap_vec_poison(<2 x i8> %x) {
3323 ; CHECK-LABEL: @ne0_is_all_ones_swap_vec_poison(
3324 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer
3325 ; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>
3326 ; CHECK-NEXT: ret <2 x i8> [[R]]
3328 %negx = sub <2 x i8> <i8 0, i8 poison>, %x
3329 %ult2 = icmp ult <2 x i8> %x, <i8 2, i8 poison>
3330 %r = select <2 x i1> %ult2, <2 x i8> %negx, <2 x i8> <i8 -1, i8 poison>
3334 define i64 @udiv_of_select_constexpr(i1 %c, i64 %x) {
3335 ; CHECK-LABEL: @udiv_of_select_constexpr(
3336 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i64 [[X:%.*]], i64 ptrtoint (ptr @glbl to i64)
3337 ; CHECK-NEXT: [[OP:%.*]] = udiv i64 [[SEL]], 3
3338 ; CHECK-NEXT: ret i64 [[OP]]
3340 %sel = select i1 %c, i64 %x, i64 ptrtoint (ptr @glbl to i64)
3341 %op = udiv i64 %sel, 3
3345 define i64 @udiv_of_select_constexpr_commuted(i1 %c, i64 %x) {
3346 ; CHECK-LABEL: @udiv_of_select_constexpr_commuted(
3347 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i64 ptrtoint (ptr @glbl to i64), i64 [[X:%.*]]
3348 ; CHECK-NEXT: [[OP:%.*]] = udiv i64 [[SEL]], 3
3349 ; CHECK-NEXT: ret i64 [[OP]]
3351 %sel = select i1 %c, i64 ptrtoint (ptr @glbl to i64), i64 %x
3352 %op = udiv i64 %sel, 3
3356 declare void @use(i1)
3357 declare void @use_i8(i8)
3358 declare void @use_i32(i32)
3359 declare i32 @llvm.cttz.i32(i32, i1 immarg)
3361 define i32 @select_cond_zext_cond(i1 %cond, i32 %b) {
3362 ; CHECK-LABEL: @select_cond_zext_cond(
3363 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 1, i32 [[B:%.*]]
3364 ; CHECK-NEXT: ret i32 [[SEL]]
3366 %zext = zext i1 %cond to i32
3367 %sel = select i1 %cond, i32 %zext, i32 %b
3371 define <2 x i32> @select_cond_zext_cond_vec(<2 x i1> %cond, <2 x i32> %b) {
3372 ; CHECK-LABEL: @select_cond_zext_cond_vec(
3373 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> splat (i32 1), <2 x i32> [[B:%.*]]
3374 ; CHECK-NEXT: ret <2 x i32> [[SEL]]
3376 %zext = zext <2 x i1> %cond to <2 x i32>
3377 %sel = select <2 x i1> %cond, <2 x i32> %zext, <2 x i32> %b
3381 define i32 @select_cond_sext_cond(i1 %cond, i32 %b) {
3382 ; CHECK-LABEL: @select_cond_sext_cond(
3383 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 -1, i32 [[B:%.*]]
3384 ; CHECK-NEXT: ret i32 [[SEL]]
3386 %sext = sext i1 %cond to i32
3387 %sel = select i1 %cond, i32 %sext, i32 %b
3391 define <2 x i32> @select_cond_sext_cond_vec(<2 x i1> %cond, <2 x i32> %b) {
3392 ; CHECK-LABEL: @select_cond_sext_cond_vec(
3393 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> splat (i32 -1), <2 x i32> [[B:%.*]]
3394 ; CHECK-NEXT: ret <2 x i32> [[SEL]]
3396 %sext = sext <2 x i1> %cond to <2 x i32>
3397 %sel = select <2 x i1> %cond, <2 x i32> %sext, <2 x i32> %b
3401 define i32 @select_cond_val_zext_cond(i1 %cond, i32 %b) {
3402 ; CHECK-LABEL: @select_cond_val_zext_cond(
3403 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 0
3404 ; CHECK-NEXT: ret i32 [[SEL]]
3406 %zext = zext i1 %cond to i32
3407 %sel = select i1 %cond, i32 %b, i32 %zext
3411 define <2 x i32> @select_cond_val_zext_cond_vec(<2 x i1> %cond, <2 x i32> %b) {
3412 ; CHECK-LABEL: @select_cond_val_zext_cond_vec(
3413 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> [[B:%.*]], <2 x i32> zeroinitializer
3414 ; CHECK-NEXT: ret <2 x i32> [[SEL]]
3416 %zext = zext <2 x i1> %cond to <2 x i32>
3417 %sel = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %zext
3421 define i32 @select_cond_val_sext_cond(i1 %cond, i32 %b) {
3422 ; CHECK-LABEL: @select_cond_val_sext_cond(
3423 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 0
3424 ; CHECK-NEXT: ret i32 [[SEL]]
3426 %sext = sext i1 %cond to i32
3427 %sel = select i1 %cond, i32 %b, i32 %sext
3431 define i32 @select_cond_zext_not_cond_val(i1 %cond, i32 %b) {
3432 ; CHECK-LABEL: @select_cond_zext_not_cond_val(
3433 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 0, i32 [[B:%.*]]
3434 ; CHECK-NEXT: ret i32 [[SEL]]
3436 %not_cond = xor i1 %cond, true
3437 %zext = zext i1 %not_cond to i32
3438 %sel = select i1 %cond, i32 %zext, i32 %b
3442 define i32 @select_cond_sext_not_cond_val(i1 %cond, i32 %b) {
3443 ; CHECK-LABEL: @select_cond_sext_not_cond_val(
3444 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 0, i32 [[B:%.*]]
3445 ; CHECK-NEXT: ret i32 [[SEL]]
3447 %not_cond = xor i1 %cond, true
3448 %sext = sext i1 %not_cond to i32
3449 %sel = select i1 %cond, i32 %sext, i32 %b
3454 define i32 @select_cond_val_zext_not_cond(i1 %cond, i32 %b) {
3455 ; CHECK-LABEL: @select_cond_val_zext_not_cond(
3456 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 1
3457 ; CHECK-NEXT: ret i32 [[SEL]]
3459 %not_cond = xor i1 %cond, true
3460 %zext = zext i1 %not_cond to i32
3461 %sel = select i1 %cond, i32 %b, i32 %zext
3465 define i32 @select_cond_val_sext_not_cond(i1 %cond, i32 %b) {
3466 ; CHECK-LABEL: @select_cond_val_sext_not_cond(
3467 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 -1
3468 ; CHECK-NEXT: ret i32 [[SEL]]
3470 %not_cond = xor i1 %cond, true
3471 %sext = sext i1 %not_cond to i32
3472 %sel = select i1 %cond, i32 %b, i32 %sext
3476 define i32 @select_cond_not_cond_cond1(i1 %cond) {
3477 ; CHECK-LABEL: @select_cond_not_cond_cond1(
3478 ; CHECK-NEXT: ret i32 0
3480 %z = zext i1 %cond to i32
3481 %not_cond = xor i1 %cond, true
3482 %s = sext i1 %not_cond to i32
3483 %v = select i1 %cond, i32 %s, i32 %z
3487 define i32 @select_cond_not_cond_cond2(i1 %cond) {
3488 ; CHECK-LABEL: @select_cond_not_cond_cond2(
3489 ; CHECK-NEXT: ret i32 0
3491 %z = sext i1 %cond to i32
3492 %not_cond = xor i1 %cond, true
3493 %s = zext i1 %not_cond to i32
3494 %v = select i1 %cond, i32 %s, i32 %z
3498 ; This previously crashed due to Constant::getUniqueInteger not handling
3499 ; scalable vector splat ConstantExprs.
3500 define <vscale x 2 x i32> @and_constant_select_svec(<vscale x 2 x i32> %x, <vscale x 2 x i1> %cond) {
3501 ; CHECK-LABEL: @and_constant_select_svec(
3502 ; CHECK-NEXT: [[A:%.*]] = and <vscale x 2 x i32> [[X:%.*]], splat (i32 1)
3503 ; CHECK-NEXT: [[B:%.*]] = select <vscale x 2 x i1> [[COND:%.*]], <vscale x 2 x i32> [[A]], <vscale x 2 x i32> [[X]]
3504 ; CHECK-NEXT: ret <vscale x 2 x i32> [[B]]
3506 %a = and <vscale x 2 x i32> %x, splat (i32 1)
3507 %b = select <vscale x 2 x i1> %cond, <vscale x 2 x i32> %a, <vscale x 2 x i32> %x
3508 ret <vscale x 2 x i32> %b
3511 define <vscale x 2 x i32> @scalable_sign_bits(<vscale x 2 x i8> %x) {
3512 ; CHECK-LABEL: @scalable_sign_bits(
3513 ; CHECK-NEXT: [[A:%.*]] = sext <vscale x 2 x i8> [[X:%.*]] to <vscale x 2 x i32>
3514 ; CHECK-NEXT: [[B:%.*]] = shl nsw <vscale x 2 x i32> [[A]], splat (i32 16)
3515 ; CHECK-NEXT: ret <vscale x 2 x i32> [[B]]
3517 %a = sext <vscale x 2 x i8> %x to <vscale x 2 x i32>
3518 %b = shl <vscale x 2 x i32> %a, splat (i32 16)
3519 ret <vscale x 2 x i32> %b
3522 define <vscale x 2 x i1> @scalable_non_zero(<vscale x 2 x i32> %x) {
3523 ; CHECK-LABEL: @scalable_non_zero(
3524 ; CHECK-NEXT: [[A:%.*]] = or <vscale x 2 x i32> [[X:%.*]], splat (i32 1)
3525 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <vscale x 2 x i32> [[A]], splat (i32 57)
3526 ; CHECK-NEXT: ret <vscale x 2 x i1> [[CMP]]
3528 %a = or <vscale x 2 x i32> %x, splat (i32 1)
3529 %b = add <vscale x 2 x i32> %a, splat (i32 -1)
3530 %cmp = icmp ult <vscale x 2 x i32> %b, splat (i32 56)
3531 ret <vscale x 2 x i1> %cmp
3534 define i32 @clamp_umin(i32 %x) {
3535 ; CHECK-LABEL: @clamp_umin(
3536 ; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 1)
3537 ; CHECK-NEXT: ret i32 [[SEL]]
3539 %cmp = icmp eq i32 %x, 0
3540 %sel = select i1 %cmp, i32 1, i32 %x
3544 define i32 @clamp_umin_use(i32 %x) {
3545 ; CHECK-LABEL: @clamp_umin_use(
3546 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
3547 ; CHECK-NEXT: call void @use1(i1 [[CMP]])
3548 ; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1)
3549 ; CHECK-NEXT: ret i32 [[SEL]]
3551 %cmp = icmp eq i32 %x, 0
3552 call void @use1(i1 %cmp)
3553 %sel = select i1 %cmp, i32 1, i32 %x
3557 ; negative test - wrong cmp constant
3559 define i32 @not_clamp_umin1(i32 %x) {
3560 ; CHECK-LABEL: @not_clamp_umin1(
3561 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2
3562 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 [[X]]
3563 ; CHECK-NEXT: ret i32 [[SEL]]
3565 %cmp = icmp eq i32 %x, 2
3566 %sel = select i1 %cmp, i32 1, i32 %x
3570 ; negative test - wrong select constant
3572 define i32 @not_clamp_umin2(i32 %x) {
3573 ; CHECK-LABEL: @not_clamp_umin2(
3574 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
3575 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[X]]
3576 ; CHECK-NEXT: ret i32 [[SEL]]
3578 %cmp = icmp eq i32 %x, 0
3579 %sel = select i1 %cmp, i32 -1, i32 %x
3583 define <2 x i8> @clamp_umaxval(<2 x i8> %x) {
3584 ; CHECK-LABEL: @clamp_umaxval(
3585 ; CHECK-NEXT: [[SEL:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 -2))
3586 ; CHECK-NEXT: ret <2 x i8> [[SEL]]
3588 %cmp = icmp eq <2 x i8> %x, <i8 255, i8 255>
3589 %sel = select <2 x i1> %cmp, <2 x i8> <i8 254, i8 254>, <2 x i8> %x
3593 ; negative test - wrong cmp constant
3595 define i8 @not_clamp_umax1(i8 %x) {
3596 ; CHECK-LABEL: @not_clamp_umax1(
3597 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -3
3598 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 -2, i8 [[X]]
3599 ; CHECK-NEXT: ret i8 [[SEL]]
3601 %cmp = icmp eq i8 %x, 253
3602 %sel = select i1 %cmp, i8 254, i8 %x
3606 ; negative test - wrong select constant
3608 define i8 @not_clamp_umax2(i8 %x) {
3609 ; CHECK-LABEL: @not_clamp_umax2(
3610 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -1
3611 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 1, i8 [[X]]
3612 ; CHECK-NEXT: ret i8 [[SEL]]
3614 %cmp = icmp eq i8 %x, 255
3615 %sel = select i1 %cmp, i8 1, i8 %x
3619 define i8 @clamp_smin(i8 %x) {
3620 ; CHECK-LABEL: @clamp_smin(
3621 ; CHECK-NEXT: [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 -127)
3622 ; CHECK-NEXT: ret i8 [[SEL]]
3624 %cmp = icmp eq i8 %x, -128
3625 %sel = select i1 %cmp, i8 -127, i8 %x
3629 define i8 @clamp_smin_use(i8 %x) {
3630 ; CHECK-LABEL: @clamp_smin_use(
3631 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128
3632 ; CHECK-NEXT: call void @use1(i1 [[CMP]])
3633 ; CHECK-NEXT: [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 -127)
3634 ; CHECK-NEXT: ret i8 [[SEL]]
3636 %cmp = icmp eq i8 %x, -128
3637 call void @use1(i1 %cmp)
3638 %sel = select i1 %cmp, i8 -127, i8 %x
3642 ; negative test - wrong cmp constant
3644 define i8 @not_clamp_smin1(i8 %x) {
3645 ; CHECK-LABEL: @not_clamp_smin1(
3646 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 127
3647 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 -127, i8 [[X]]
3648 ; CHECK-NEXT: ret i8 [[SEL]]
3650 %cmp = icmp eq i8 %x, 127
3651 %sel = select i1 %cmp, i8 -127, i8 %x
3655 ; negative test - wrong select constant
3657 define i8 @not_clamp_smin2(i8 %x) {
3658 ; CHECK-LABEL: @not_clamp_smin2(
3659 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128
3660 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 -1, i8 [[X]]
3661 ; CHECK-NEXT: ret i8 [[SEL]]
3663 %cmp = icmp eq i8 %x, -128
3664 %sel = select i1 %cmp, i8 -1, i8 %x
3668 define <2 x i8> @clamp_smaxval(<2 x i8> %x) {
3669 ; CHECK-LABEL: @clamp_smaxval(
3670 ; CHECK-NEXT: [[SEL:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 126))
3671 ; CHECK-NEXT: ret <2 x i8> [[SEL]]
3673 %cmp = icmp eq <2 x i8> %x, <i8 127, i8 127>
3674 %sel = select <2 x i1> %cmp, <2 x i8> <i8 126, i8 126>, <2 x i8> %x
3678 ; negative test - wrong cmp constant
3680 define i8 @not_clamp_smax1(i8 %x) {
3681 ; CHECK-LABEL: @not_clamp_smax1(
3682 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128
3683 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 126, i8 [[X]]
3684 ; CHECK-NEXT: ret i8 [[SEL]]
3686 %cmp = icmp eq i8 %x, -128
3687 %sel = select i1 %cmp, i8 126, i8 %x
3691 ; negative test - wrong select constant
3693 define i8 @not_clamp_smax2(i8 %x) {
3694 ; CHECK-LABEL: @not_clamp_smax2(
3695 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 127
3696 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 125, i8 [[X]]
3697 ; CHECK-NEXT: ret i8 [[SEL]]
3699 %cmp = icmp eq i8 %x, 127
3700 %sel = select i1 %cmp, i8 125, i8 %x
3704 ; Used to infinite loop.
3705 define i32 @pr61361(i32 %arg) {
3706 ; CHECK-LABEL: @pr61361(
3707 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[ARG:%.*]], 0
3708 ; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 16777215, i32 0
3709 ; CHECK-NEXT: ret i32 [[SEL2]]
3711 %cmp1 = icmp eq i32 %arg, 1
3712 %sel1 = select i1 %cmp1, i32 0, i32 33554431
3713 %cmp2 = icmp eq i32 %arg, 0
3714 %sel2 = select i1 %cmp2, i32 %sel1, i32 0
3715 %ashr = ashr i32 %sel2, 1
3719 define i32 @pr62088() {
3720 ; CHECK-LABEL: @pr62088(
3721 ; CHECK-NEXT: entry:
3722 ; CHECK-NEXT: br label [[LOOP:%.*]]
3724 ; CHECK-NEXT: [[NOT2:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ -2, [[LOOP]] ]
3725 ; CHECK-NEXT: [[H_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ 1, [[LOOP]] ]
3726 ; CHECK-NEXT: [[XOR:%.*]] = or disjoint i32 [[H_0]], [[NOT2]]
3727 ; CHECK-NEXT: [[SUB5:%.*]] = sub i32 -1824888657, [[XOR]]
3728 ; CHECK-NEXT: [[XOR6:%.*]] = xor i32 [[SUB5]], -1260914025
3729 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[XOR6]], 824855120
3730 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
3732 ; CHECK-NEXT: ret i32 [[H_0]]
3738 %not2 = phi i32 [ 0, %entry ], [ -2, %loop ]
3739 %i.0 = phi i32 [ 0, %entry ], [ %shr, %loop ]
3740 %h.0 = phi i32 [ 0, %entry ], [ 1, %loop ]
3741 %i.0.fr = freeze i32 %i.0
3742 %sext = shl i32 %i.0.fr, 16
3743 %conv = ashr exact i32 %sext, 16
3744 %not = xor i32 %conv, -1
3745 %and = and i32 %h.0, 1
3746 %rem.urem = sub nsw i32 %and, %conv
3747 %rem.cmp = icmp ult i32 %and, %conv
3748 %rem = select i1 %rem.cmp, i32 %not, i32 %rem.urem
3749 %xor = xor i32 %rem, %not2
3750 %sub = sub nsw i32 0, %xor
3751 %sub5 = sub i32 -1824888657, %xor
3752 %xor6 = xor i32 %sub5, -1260914025
3753 %cmp = icmp slt i32 %xor6, 824855120
3754 %shr = ashr i32 %xor6, 40
3755 br i1 %cmp, label %loop, label %exit
3761 ; Select icmp and/or/xor
3762 ; https://alive2.llvm.org/ce/z/QXQDwF
3763 ; X&Y==C?X|Y:X^Y, X&Y==C?X^Y:X|Y
3764 ; TODO: X&Y==0 could imply no_common_bit to TrueValue
3765 define i32 @src_and_eq_0_or_xor(i32 %x, i32 %y) {
3766 ; CHECK-LABEL: @src_and_eq_0_or_xor(
3767 ; CHECK-NEXT: entry:
3768 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3769 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
3770 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]]
3771 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3772 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[XOR]]
3773 ; CHECK-NEXT: ret i32 [[COND]]
3776 %and = and i32 %y, %x
3777 %cmp = icmp eq i32 %and, 0
3779 %xor = xor i32 %y, %x
3780 %cond = select i1 %cmp, i32 %or, i32 %xor
3784 ; TODO: X&Y==0 could imply no_common_bit to TrueValue
3785 define i32 @src_and_eq_0_xor_or(i32 %x, i32 %y) {
3786 ; CHECK-LABEL: @src_and_eq_0_xor_or(
3787 ; CHECK-NEXT: entry:
3788 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3789 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
3790 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3791 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]]
3792 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[OR]]
3793 ; CHECK-NEXT: ret i32 [[COND]]
3796 %and = and i32 %y, %x
3797 %cmp = icmp eq i32 %and, 0
3798 %xor = xor i32 %y, %x
3800 %cond = select i1 %cmp, i32 %xor, i32 %or
3804 ; TODO: X&Y==-1 could imply all_common_bit to TrueValue
3805 define i32 @src_and_eq_neg1_or_xor(i32 %x, i32 %y) {
3806 ; CHECK-LABEL: @src_and_eq_neg1_or_xor(
3807 ; CHECK-NEXT: entry:
3808 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3809 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], -1
3810 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3811 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[XOR]]
3812 ; CHECK-NEXT: ret i32 [[COND]]
3815 %and = and i32 %y, %x
3816 %cmp = icmp eq i32 %and, -1
3818 %xor = xor i32 %y, %x
3819 %cond = select i1 %cmp, i32 %or, i32 %xor
3823 ; TODO: X&Y==-1 could imply all_common_bit to TrueValue
3824 define i32 @src_and_eq_neg1_xor_or(i32 %x, i32 %y) {
3825 ; CHECK-LABEL: @src_and_eq_neg1_xor_or(
3826 ; CHECK-NEXT: entry:
3827 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3828 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], -1
3829 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]]
3830 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 0, i32 [[OR]]
3831 ; CHECK-NEXT: ret i32 [[COND]]
3834 %and = and i32 %y, %x
3835 %cmp = icmp eq i32 %and, -1
3836 %xor = xor i32 %y, %x
3838 %cond = select i1 %cmp, i32 %xor, i32 %or
3842 define i32 @src_and_eq_C_or_xororC(i32 %x, i32 %y, i32 %c) {
3843 ; CHECK-LABEL: @src_and_eq_C_or_xororC(
3844 ; CHECK-NEXT: entry:
3845 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
3846 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XOR]], [[C:%.*]]
3847 ; CHECK-NEXT: ret i32 [[OR1]]
3850 %and = and i32 %y, %x
3851 %cmp = icmp eq i32 %and, %c
3853 %xor = xor i32 %y, %x
3854 %or1 = or i32 %xor, %c
3855 %cond = select i1 %cmp, i32 %or, i32 %or1
3859 define i32 @src_and_eq_C_or_xorxorC(i32 %x, i32 %y, i32 %c) {
3860 ; CHECK-LABEL: @src_and_eq_C_or_xorxorC(
3861 ; CHECK-NEXT: entry:
3862 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
3863 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[XOR]], [[C:%.*]]
3864 ; CHECK-NEXT: ret i32 [[XOR1]]
3867 %and = and i32 %y, %x
3868 %cmp = icmp eq i32 %and, %c
3870 %xor = xor i32 %y, %x
3871 %xor1 = xor i32 %xor, %c
3872 %cond = select i1 %cmp, i32 %or, i32 %xor1
3876 define i32 @src_and_eq_C_xor_OrAndNotC(i32 %x, i32 %y, i32 %c) {
3877 ; CHECK-LABEL: @src_and_eq_C_xor_OrAndNotC(
3878 ; CHECK-NEXT: entry:
3879 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
3880 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[C:%.*]], -1
3881 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[OR]], [[NOT]]
3882 ; CHECK-NEXT: ret i32 [[AND1]]
3885 %and = and i32 %y, %x
3886 %cmp = icmp eq i32 %and, %c
3887 %xor = xor i32 %y, %x
3889 %not = xor i32 %c, -1
3890 %and1 = and i32 %or, %not
3891 %cond = select i1 %cmp, i32 %xor, i32 %and1
3895 define <2 x i32> @src_and_eq_C_xor_OrAndNotC_vec_poison(<2 x i32> %0, <2 x i32> %1, <2 x i32> %2) {
3896 ; CHECK-LABEL: @src_and_eq_C_xor_OrAndNotC_vec_poison(
3897 ; CHECK-NEXT: entry:
3898 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[TMP1:%.*]], [[TMP0:%.*]]
3899 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], [[TMP2:%.*]]
3900 ; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[TMP1]], [[TMP0]]
3901 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[TMP1]], [[TMP0]]
3902 ; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i32> [[TMP2]], <i32 -1, i32 poison>
3903 ; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[OR]], [[NOT]]
3904 ; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[XOR]], <2 x i32> [[AND1]]
3905 ; CHECK-NEXT: ret <2 x i32> [[COND]]
3908 %and = and <2 x i32> %1, %0
3909 %cmp = icmp eq <2 x i32> %and, %2
3910 %xor = xor <2 x i32> %1, %0
3911 %or = or <2 x i32> %1, %0
3912 %not = xor <2 x i32> %2, <i32 -1, i32 poison>
3913 %and1 = and <2 x i32> %or, %not
3914 %cond = select <2 x i1> %cmp, <2 x i32> %xor, <2 x i32> %and1
3918 define i32 @src_and_eq_C_xor_orxorC(i32 %x, i32 %y, i32 %c) {
3919 ; CHECK-LABEL: @src_and_eq_C_xor_orxorC(
3920 ; CHECK-NEXT: entry:
3921 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
3922 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[OR]], [[C:%.*]]
3923 ; CHECK-NEXT: ret i32 [[XOR1]]
3926 %and = and i32 %y, %x
3927 %cmp = icmp eq i32 %and, %c
3928 %xor = xor i32 %y, %x
3930 %xor1 = xor i32 %or, %c
3931 %cond = select i1 %cmp, i32 %xor, i32 %xor1
3935 ; https://alive2.llvm.org/ce/z/9RPwfN
3936 ; X|Y==C?X&Y:X^Y, X|Y==C?X^Y:X&Y
3937 ; TODO: X|Y==0 could imply no_common_bit to TrueValue
3938 define i32 @src_or_eq_0_and_xor(i32 %x, i32 %y) {
3939 ; CHECK-LABEL: @src_or_eq_0_and_xor(
3940 ; CHECK-NEXT: entry:
3941 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
3942 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], 0
3943 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]]
3944 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 0, i32 [[XOR]]
3945 ; CHECK-NEXT: ret i32 [[COND]]
3949 %cmp = icmp eq i32 %or, 0
3950 %and = and i32 %y, %x
3951 %xor = xor i32 %y, %x
3952 %cond = select i1 %cmp, i32 %and, i32 %xor
3956 ; TODO: X|Y==0 could imply no_common_bit to TrueValue
3957 define i32 @src_or_eq_0_xor_and(i32 %x, i32 %y) {
3958 ; CHECK-LABEL: @src_or_eq_0_xor_and(
3959 ; CHECK-NEXT: entry:
3960 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
3961 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], 0
3962 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]]
3963 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 0, i32 [[AND]]
3964 ; CHECK-NEXT: ret i32 [[COND]]
3968 %cmp = icmp eq i32 %or, 0
3969 %xor = xor i32 %y, %x
3970 %and = and i32 %y, %x
3971 %cond = select i1 %cmp, i32 %xor, i32 %and
3975 define i32 @src_or_eq_neg1_and_xor(i32 %x, i32 %y) {
3976 ; CHECK-LABEL: @src_or_eq_neg1_and_xor(
3977 ; CHECK-NEXT: entry:
3978 ; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
3979 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[TMP0]], -1
3980 ; CHECK-NEXT: ret i32 [[NOT]]
3984 %cmp = icmp eq i32 %or, -1
3985 %and = and i32 %y, %x
3987 %not = xor i32 %0, -1
3988 %cond = select i1 %cmp, i32 %and, i32 %not
3992 define i32 @src_or_eq_neg1_xor_and(i32 %x, i32 %y) {
3993 ; CHECK-LABEL: @src_or_eq_neg1_xor_and(
3994 ; CHECK-NEXT: entry:
3995 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
3996 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[AND]], -1
3997 ; CHECK-NEXT: ret i32 [[NOT]]
4001 %cmp = icmp eq i32 %or, -1
4002 %xor = xor i32 %y, %x
4003 %and = and i32 %y, %x
4004 %not = xor i32 %and, -1
4005 %cond = select i1 %cmp, i32 %xor, i32 %not
4009 define i32 @src_or_eq_C_and_xorC(i32 %x, i32 %y, i32 %c) {
4010 ; CHECK-LABEL: @src_or_eq_C_and_xorC(
4011 ; CHECK-NEXT: entry:
4012 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
4013 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[XOR]], [[C:%.*]]
4014 ; CHECK-NEXT: ret i32 [[XOR1]]
4018 %cmp = icmp eq i32 %or, %c
4019 %and = and i32 %y, %x
4020 %xor = xor i32 %y, %x
4021 %xor1 = xor i32 %xor, %c
4022 %cond = select i1 %cmp, i32 %and, i32 %xor1
4026 define i32 @src_or_eq_C_and_andnotxorC(i32 %x, i32 %y, i32 %c) {
4027 ; CHECK-LABEL: @src_or_eq_C_and_andnotxorC(
4028 ; CHECK-NEXT: entry:
4029 ; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4030 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[TMP0]], -1
4031 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C:%.*]], [[NOT]]
4032 ; CHECK-NEXT: ret i32 [[AND1]]
4036 %cmp = icmp eq i32 %or, %c
4037 %and = and i32 %y, %x
4039 %not = xor i32 %0, -1
4040 %and1 = and i32 %not, %c
4041 %cond = select i1 %cmp, i32 %and, i32 %and1
4045 define i32 @src_or_eq_C_xor_xorandC(i32 %x, i32 %y, i32 %c) {
4046 ; CHECK-LABEL: @src_or_eq_C_xor_xorandC(
4047 ; CHECK-NEXT: entry:
4048 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
4049 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[AND]], [[C:%.*]]
4050 ; CHECK-NEXT: ret i32 [[XOR1]]
4054 %cmp = icmp eq i32 %or, %c
4055 %xor = xor i32 %y, %x
4056 %and = and i32 %y, %x
4057 %xor1 = xor i32 %and, %c
4058 %cond = select i1 %cmp, i32 %xor, i32 %xor1
4062 define i32 @src_or_eq_C_xor_andnotandC(i32 %x, i32 %y, i32 %c) {
4063 ; CHECK-LABEL: @src_or_eq_C_xor_andnotandC(
4064 ; CHECK-NEXT: entry:
4065 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
4066 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[AND]], -1
4067 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C:%.*]], [[NOT]]
4068 ; CHECK-NEXT: ret i32 [[AND1]]
4072 %cmp = icmp eq i32 %or, %c
4073 %xor = xor i32 %y, %x
4074 %and = and i32 %y, %x
4075 %not = xor i32 %and, -1
4076 %and1 = and i32 %not, %c
4077 %cond = select i1 %cmp, i32 %xor, i32 %and1
4081 ; https://alive2.llvm.org/ce/z/c6oXi4
4082 ; X^Y==C?X&Y:X|Y, X^Y==C?X|Y:X&Y
4083 define i32 @src_xor_eq_neg1_and(i32 %x, i32 %y) {
4084 ; CHECK-LABEL: @src_xor_eq_neg1_and(
4085 ; CHECK-NEXT: entry:
4086 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
4087 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[OR]], -1
4088 ; CHECK-NEXT: ret i32 [[NOT]]
4091 %xor = xor i32 %y, %x
4092 %cmp = icmp eq i32 %xor, -1
4093 %and = and i32 %y, %x
4095 %not = xor i32 %or, -1
4096 %cond = select i1 %cmp, i32 %and, i32 %not
4100 ; TODO: X^Y==-1 could imply no_common_bit to TrueValue
4101 define i32 @src_xor_eq_neg1_or(i32 %x, i32 %y) {
4102 ; CHECK-LABEL: @src_xor_eq_neg1_or(
4103 ; CHECK-NEXT: entry:
4104 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
4105 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[XOR]], -1
4106 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]]
4107 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 -1
4108 ; CHECK-NEXT: ret i32 [[COND]]
4111 %xor = xor i32 %y, %x
4112 %cmp = icmp eq i32 %xor, -1
4114 %cond = select i1 %cmp, i32 %or, i32 -1
4118 define i32 @src_xor_eq_C_and_xororC(i32 %x, i32 %y, i32 %c) {
4119 ; CHECK-LABEL: @src_xor_eq_C_and_xororC(
4120 ; CHECK-NEXT: entry:
4121 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
4122 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[OR]], [[C:%.*]]
4123 ; CHECK-NEXT: ret i32 [[XOR1]]
4126 %xor = xor i32 %y, %x
4127 %cmp = icmp eq i32 %xor, %c
4128 %and = and i32 %y, %x
4130 %xor1 = xor i32 %or, %c
4131 %cond = select i1 %cmp, i32 %and, i32 %xor1
4135 define i32 @src_xor_eq_C_and_andornotC(i32 %x, i32 %y, i32 %c) {
4136 ; CHECK-LABEL: @src_xor_eq_C_and_andornotC(
4137 ; CHECK-NEXT: entry:
4138 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
4139 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[C:%.*]], -1
4140 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[OR]], [[NOT]]
4141 ; CHECK-NEXT: ret i32 [[AND1]]
4144 %xor = xor i32 %y, %x
4145 %cmp = icmp eq i32 %xor, %c
4146 %and = and i32 %y, %x
4148 %not = xor i32 %c, -1
4149 %and1 = and i32 %or, %not
4150 %cond = select i1 %cmp, i32 %and, i32 %and1
4154 define i32 @src_xor_eq_C_or_xorandC(i32 %x, i32 %y, i32 %c) {
4155 ; CHECK-LABEL: @src_xor_eq_C_or_xorandC(
4156 ; CHECK-NEXT: entry:
4157 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
4158 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[AND]], [[C:%.*]]
4159 ; CHECK-NEXT: ret i32 [[XOR1]]
4162 %xor = xor i32 %y, %x
4163 %cmp = icmp eq i32 %xor, %c
4165 %and = and i32 %y, %x
4166 %xor1 = xor i32 %and, %c
4167 %cond = select i1 %cmp, i32 %or, i32 %xor1
4171 define i32 @src_xor_eq_C_or_orandC(i32 %x, i32 %y, i32 %c) {
4172 ; CHECK-LABEL: @src_xor_eq_C_or_orandC(
4173 ; CHECK-NEXT: entry:
4174 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
4175 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[AND]], [[C:%.*]]
4176 ; CHECK-NEXT: ret i32 [[OR1]]
4179 %xor = xor i32 %y, %x
4180 %cmp = icmp eq i32 %xor, %c
4182 %and = and i32 %y, %x
4183 %or1 = or i32 %and, %c
4184 %cond = select i1 %cmp, i32 %or, i32 %or1
4188 ; Select icmp and/or/xor
4189 ; NO TRANSFORMED - select condition is compare with not 0
4190 define i32 @src_select_and_min_positive_int(i32 %x, i32 %y) {
4191 ; CHECK-LABEL: @src_select_and_min_positive_int(
4192 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4193 ; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 1
4194 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4195 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4196 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]]
4197 ; CHECK-NEXT: ret i32 [[COND]]
4199 %and = and i32 %x, %y
4200 %and0 = icmp eq i32 %and, 1
4201 %xor = xor i32 %x, %y
4203 %cond = select i1 %and0, i32 %or, i32 %xor
4207 define i32 @src_select_and_max_positive_int(i32 %x, i32 %y) {
4208 ; CHECK-LABEL: @src_select_and_max_positive_int(
4209 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4210 ; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 2147483647
4211 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4212 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4213 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]]
4214 ; CHECK-NEXT: ret i32 [[COND]]
4216 %and = and i32 %x, %y
4217 %and0 = icmp eq i32 %and, 2147483647
4218 %xor = xor i32 %x, %y
4220 %cond = select i1 %and0, i32 %or, i32 %xor
4224 define i32 @src_select_and_min_negative_int(i32 %x, i32 %y) {
4225 ; CHECK-LABEL: @src_select_and_min_negative_int(
4226 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4227 ; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], -2147483648
4228 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4229 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4230 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]]
4231 ; CHECK-NEXT: ret i32 [[COND]]
4233 %and = and i32 %x, %y
4234 %and0 = icmp eq i32 %and, -2147483648
4235 %xor = xor i32 %x, %y
4237 %cond = select i1 %and0, i32 %or, i32 %xor
4241 define i32 @src_select_or_min_positive_int(i32 %x, i32 %y) {
4242 ; CHECK-LABEL: @src_select_or_min_positive_int(
4243 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4244 ; CHECK-NEXT: [[OR0:%.*]] = icmp eq i32 [[OR]], 1
4245 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4246 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4247 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]
4248 ; CHECK-NEXT: ret i32 [[COND]]
4251 %or0 = icmp eq i32 %or, 1
4252 %and = and i32 %x, %y
4253 %xor = xor i32 %x, %y
4254 %cond = select i1 %or0, i32 %and, i32 %xor
4258 define i32 @src_select_or_max_positive_int(i32 %x, i32 %y) {
4259 ; CHECK-LABEL: @src_select_or_max_positive_int(
4260 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4261 ; CHECK-NEXT: [[OR0:%.*]] = icmp eq i32 [[OR]], 2147483647
4262 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4263 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4264 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]
4265 ; CHECK-NEXT: ret i32 [[COND]]
4268 %or0 = icmp eq i32 %or, 2147483647
4269 %and = and i32 %x, %y
4270 %xor = xor i32 %x, %y
4271 %cond = select i1 %or0, i32 %and, i32 %xor
4275 define i32 @src_select_or_min_negative_int(i32 %x, i32 %y) {
4276 ; CHECK-LABEL: @src_select_or_min_negative_int(
4277 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4278 ; CHECK-NEXT: [[OR0:%.*]] = icmp eq i32 [[OR]], -2147483648
4279 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4280 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4281 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]
4282 ; CHECK-NEXT: ret i32 [[COND]]
4285 %or0 = icmp eq i32 %or, -2147483648
4286 %and = and i32 %x, %y
4287 %xor = xor i32 %x, %y
4288 %cond = select i1 %or0, i32 %and, i32 %xor
4292 define i32 @src_select_or_max_negative_int(i32 %x, i32 %y) {
4293 ; CHECK-LABEL: @src_select_or_max_negative_int(
4294 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4295 ; CHECK-NEXT: [[OR0:%.*]] = icmp eq i32 [[OR]], -1
4296 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4297 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4298 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]
4299 ; CHECK-NEXT: ret i32 [[COND]]
4302 %or0 = icmp eq i32 %or, -1
4303 %and = and i32 %x, %y
4304 %xor = xor i32 %x, %y
4305 %cond = select i1 %or0, i32 %and, i32 %xor
4309 define i32 @src_select_xor_min_positive_int(i32 %x, i32 %y) {
4310 ; CHECK-LABEL: @src_select_xor_min_positive_int(
4311 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4312 ; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], 1
4313 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4314 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4315 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]
4316 ; CHECK-NEXT: ret i32 [[COND]]
4318 %xor = xor i32 %x, %y
4319 %xor0 = icmp eq i32 %xor, 1
4320 %and = and i32 %x, %y
4322 %cond = select i1 %xor0, i32 %and, i32 %or
4326 define i32 @src_select_xor_max_positive_int(i32 %x, i32 %y) {
4327 ; CHECK-LABEL: @src_select_xor_max_positive_int(
4328 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4329 ; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], 2147483647
4330 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4331 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4332 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]
4333 ; CHECK-NEXT: ret i32 [[COND]]
4335 %xor = xor i32 %x, %y
4336 %xor0 = icmp eq i32 %xor, 2147483647
4337 %and = and i32 %x, %y
4339 %cond = select i1 %xor0, i32 %and, i32 %or
4343 define i32 @src_select_xor_min_negative_int(i32 %x, i32 %y) {
4344 ; CHECK-LABEL: @src_select_xor_min_negative_int(
4345 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4346 ; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], -2147483648
4347 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4348 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4349 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]
4350 ; CHECK-NEXT: ret i32 [[COND]]
4352 %xor = xor i32 %x, %y
4353 %xor0 = icmp eq i32 %xor, -2147483648
4354 %and = and i32 %x, %y
4356 %cond = select i1 %xor0, i32 %and, i32 %or
4360 define i32 @src_select_xor_max_negative_int(i32 %x, i32 %y) {
4361 ; CHECK-LABEL: @src_select_xor_max_negative_int(
4362 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4363 ; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], -1
4364 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4365 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4366 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]
4367 ; CHECK-NEXT: ret i32 [[COND]]
4369 %xor = xor i32 %x, %y
4370 %xor0 = icmp eq i32 %xor, -1
4371 %and = and i32 %x, %y
4373 %cond = select i1 %xor0, i32 %and, i32 %or
4377 ; Select icmp and/or/xor
4378 ; https://alive2.llvm.org/ce/z/BVgrJ-
4379 ; NO TRANSFORMED - not supported
4380 define i32 @src_no_trans_select_and_eq0_and_or(i32 %x, i32 %y) {
4381 ; CHECK-LABEL: @src_no_trans_select_and_eq0_and_or(
4382 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4383 ; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 0
4384 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4385 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 0, i32 [[OR]]
4386 ; CHECK-NEXT: ret i32 [[COND]]
4388 %and = and i32 %x, %y
4389 %and0 = icmp eq i32 %and, 0
4391 %cond = select i1 %and0, i32 %and, i32 %or
4395 define i32 @src_no_trans_select_and_eq0_and_xor(i32 %x, i32 %y) {
4396 ; CHECK-LABEL: @src_no_trans_select_and_eq0_and_xor(
4397 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4398 ; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 0
4399 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4400 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 0, i32 [[XOR]]
4401 ; CHECK-NEXT: ret i32 [[COND]]
4403 %and = and i32 %x, %y
4404 %and0 = icmp eq i32 %and, 0
4405 %xor = xor i32 %x, %y
4406 %cond = select i1 %and0, i32 %and, i32 %xor
4410 define i32 @src_no_trans_select_and_eq0_or_and(i32 %x, i32 %y) {
4411 ; CHECK-LABEL: @src_no_trans_select_and_eq0_or_and(
4412 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4413 ; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 0
4414 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4415 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[AND]]
4416 ; CHECK-NEXT: ret i32 [[COND]]
4418 %and = and i32 %x, %y
4419 %and0 = icmp eq i32 %and, 0
4421 %cond = select i1 %and0, i32 %or, i32 %and
4425 define i32 @src_no_trans_select_and_eq0_xor_and(i32 %x, i32 %y) {
4426 ; CHECK-LABEL: @src_no_trans_select_and_eq0_xor_and(
4427 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4428 ; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 0
4429 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4430 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[XOR]], i32 [[AND]]
4431 ; CHECK-NEXT: ret i32 [[COND]]
4433 %and = and i32 %x, %y
4434 %and0 = icmp eq i32 %and, 0
4435 %xor = xor i32 %x, %y
4436 %cond = select i1 %and0, i32 %xor, i32 %and
4440 define i32 @src_no_trans_select_or_eq0_or_and(i32 %x, i32 %y) {
4441 ; CHECK-LABEL: @src_no_trans_select_or_eq0_or_and(
4442 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4443 ; CHECK-NEXT: [[OR0:%.*]] = icmp eq i32 [[OR]], 0
4444 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4445 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0]], i32 0, i32 [[AND]]
4446 ; CHECK-NEXT: ret i32 [[COND]]
4449 %or0 = icmp eq i32 %or, 0
4450 %and = and i32 %x, %y
4451 %cond = select i1 %or0, i32 %or, i32 %and
4455 define i32 @src_no_trans_select_or_eq0_or_xor(i32 %x, i32 %y) {
4456 ; CHECK-LABEL: @src_no_trans_select_or_eq0_or_xor(
4457 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4458 ; CHECK-NEXT: [[OR0:%.*]] = icmp eq i32 [[OR]], 0
4459 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4460 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0]], i32 0, i32 [[XOR]]
4461 ; CHECK-NEXT: ret i32 [[COND]]
4464 %or0 = icmp eq i32 %or, 0
4465 %xor = xor i32 %x, %y
4466 %cond = select i1 %or0, i32 %or, i32 %xor
4470 define i32 @src_no_trans_select_or_eq0_and_or(i32 %x, i32 %y) {
4471 ; CHECK-LABEL: @src_no_trans_select_or_eq0_and_or(
4472 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4473 ; CHECK-NEXT: ret i32 [[OR]]
4476 %or0 = icmp eq i32 %or, 0
4477 %and = and i32 %x, %y
4478 %cond = select i1 %or0, i32 %and, i32 %or
4482 define i32 @src_no_trans_select_or_eq0_xor_or(i32 %x, i32 %y) {
4483 ; CHECK-LABEL: @src_no_trans_select_or_eq0_xor_or(
4484 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4485 ; CHECK-NEXT: ret i32 [[OR]]
4488 %or0 = icmp eq i32 %or, 0
4489 %xor = xor i32 %x, %y
4490 %cond = select i1 %or0, i32 %xor, i32 %or
4494 define i32 @src_no_trans_select_and_ne0_xor_or(i32 %x, i32 %y) {
4495 ; CHECK-LABEL: @src_no_trans_select_and_ne0_xor_or(
4496 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
4497 ; CHECK-NEXT: [[OR0_NOT:%.*]] = icmp eq i32 [[OR]], 0
4498 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4499 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0_NOT]], i32 0, i32 [[XOR]]
4500 ; CHECK-NEXT: ret i32 [[COND]]
4503 %or0 = icmp ne i32 %or, 0
4504 %xor = xor i32 %x, %y
4505 %cond = select i1 %or0, i32 %xor, i32 %or
4509 define i32 @src_no_trans_select_xor_eq0_xor_and(i32 %x, i32 %y) {
4510 ; CHECK-LABEL: @src_no_trans_select_xor_eq0_xor_and(
4511 ; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
4512 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4513 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[AND]]
4514 ; CHECK-NEXT: ret i32 [[COND]]
4516 %xor = xor i32 %x, %y
4517 %xor0 = icmp eq i32 %xor, 0
4518 %and = and i32 %x, %y
4519 %cond = select i1 %xor0, i32 %xor, i32 %and
4523 define i32 @src_no_trans_select_xor_eq0_xor_or(i32 %x, i32 %y) {
4524 ; CHECK-LABEL: @src_no_trans_select_xor_eq0_xor_or(
4525 ; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
4526 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4527 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[OR]]
4528 ; CHECK-NEXT: ret i32 [[COND]]
4530 %xor = xor i32 %x, %y
4531 %xor0 = icmp eq i32 %xor, 0
4533 %cond = select i1 %xor0, i32 %xor, i32 %or
4537 define i32 @src_no_trans_select_xor_eq0_and_xor(i32 %x, i32 %y) {
4538 ; CHECK-LABEL: @src_no_trans_select_xor_eq0_and_xor(
4539 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4540 ; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]
4541 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4542 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[XOR]]
4543 ; CHECK-NEXT: ret i32 [[COND]]
4545 %xor = xor i32 %x, %y
4546 %xor0 = icmp eq i32 %xor, 0
4547 %and = and i32 %x, %y
4548 %cond = select i1 %xor0, i32 %and, i32 %xor
4552 ; https://alive2.llvm.org/ce/z/SBe8ei
4553 define i32 @src_no_trans_select_xor_eq0_or_xor(i32 %x, i32 %y) {
4554 ; CHECK-LABEL: @src_no_trans_select_xor_eq0_or_xor(
4555 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4556 ; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]
4557 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4558 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[OR]], i32 [[XOR]]
4559 ; CHECK-NEXT: ret i32 [[COND]]
4561 %xor = xor i32 %x, %y
4562 %xor0 = icmp eq i32 %xor, 0
4564 %cond = select i1 %xor0, i32 %or, i32 %xor
4568 ; (X == C) ? X : Y -> (X == C) ? C : Y
4570 define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
4571 ; CHECK-LABEL: @src_select_xxory_eq0_xorxy_y(
4572 ; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
4573 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[Y]]
4574 ; CHECK-NEXT: ret i32 [[COND]]
4576 %xor = xor i32 %x, %y
4577 %xor0 = icmp eq i32 %xor, 0
4578 %cond = select i1 %xor0, i32 %xor, i32 %y
4582 define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
4583 ; CHECK-LABEL: @sequence_select_with_same_cond_false(
4584 ; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 23, i32 45
4585 ; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 [[S1]]
4586 ; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]
4587 ; CHECK-NEXT: ret i32 [[S3]]
4589 %s1 = select i1 %c1, i32 23, i32 45
4590 %s2 = select i1 %c2, i32 666, i32 %s1
4591 %s3 = select i1 %c1, i32 789, i32 %s2
4595 define i32 @sequence_select_with_same_cond_true(i1 %c1, i1 %c2){
4596 ; CHECK-LABEL: @sequence_select_with_same_cond_true(
4597 ; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 45, i32 23
4598 ; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 [[S1]], i32 666
4599 ; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 [[S2]], i32 789
4600 ; CHECK-NEXT: ret i32 [[S3]]
4602 %s1 = select i1 %c1, i32 45, i32 23
4603 %s2 = select i1 %c2, i32 %s1, i32 666
4604 %s3 = select i1 %c1, i32 %s2, i32 789
4608 define double @sequence_select_with_same_cond_double(double %a, i1 %c1, i1 %c2, double %r1, double %r2){
4609 ; CHECK-LABEL: @sequence_select_with_same_cond_double(
4610 ; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], double 1.000000e+00, double 0.000000e+00
4611 ; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], double [[S1]], double 2.000000e+00
4612 ; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], double [[S2]], double 3.000000e+00
4613 ; CHECK-NEXT: ret double [[S3]]
4615 %s1 = select i1 %c1, double 1.0, double 0.0
4616 %s2 = select i1 %c2, double %s1, double 2.0
4617 %s3 = select i1 %c1, double %s2, double 3.0
4621 declare void @use32(i32)
4623 define i32 @sequence_select_with_same_cond_extra_use(i1 %c1, i1 %c2){
4624 ; CHECK-LABEL: @sequence_select_with_same_cond_extra_use(
4625 ; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 23, i32 45
4626 ; CHECK-NEXT: call void @use32(i32 [[S1]])
4627 ; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 [[S1]]
4628 ; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]
4629 ; CHECK-NEXT: ret i32 [[S3]]
4631 %s1 = select i1 %c1, i32 23, i32 45
4632 call void @use32(i32 %s1)
4633 %s2 = select i1 %c2, i32 666, i32 %s1
4634 %s3 = select i1 %c1, i32 789, i32 %s2
4638 define i8 @test_replace_freeze_multiuse(i1 %x, i8 %y) {
4639 ; CHECK-LABEL: @test_replace_freeze_multiuse(
4640 ; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[X:%.*]] to i8
4641 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y:%.*]]
4642 ; CHECK-NEXT: [[SHL_FR:%.*]] = freeze i8 [[SHL]]
4643 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]]
4644 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SHL_FR]], [[SEL]]
4645 ; CHECK-NEXT: ret i8 [[ADD]]
4647 %ext = zext i1 %x to i8
4648 %shl = shl nuw i8 %ext, %y
4649 %shl.fr = freeze i8 %shl
4650 %sel = select i1 %x, i8 0, i8 %shl.fr
4651 %add = add i8 %shl.fr, %sel
4655 define i8 @test_replace_freeze_oneuse(i1 %x, i8 %y) {
4656 ; CHECK-LABEL: @test_replace_freeze_oneuse(
4657 ; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[X:%.*]] to i8
4658 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y:%.*]]
4659 ; CHECK-NEXT: [[SHL_FR:%.*]] = freeze i8 [[SHL]]
4660 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]]
4661 ; CHECK-NEXT: ret i8 [[SEL]]
4663 %ext = zext i1 %x to i8
4664 %shl = shl nuw i8 %ext, %y
4665 %shl.fr = freeze i8 %shl
4666 %sel = select i1 %x, i8 0, i8 %shl.fr
4670 define i8 @select_knownbits_simplify(i8 noundef %x) {
4671 ; CHECK-LABEL: @select_knownbits_simplify(
4672 ; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1
4673 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4674 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
4675 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0
4676 ; CHECK-NEXT: ret i8 [[RES]]
4678 %x.lo = and i8 %x, 1
4679 %cmp = icmp eq i8 %x.lo, 0
4680 %and = and i8 %x, -2
4681 %res = select i1 %cmp, i8 %and, i8 0
4685 define i8 @select_knownbits_simplify_nested(i8 noundef %x) {
4686 ; CHECK-LABEL: @select_knownbits_simplify_nested(
4687 ; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1
4688 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4689 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
4690 ; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[AND]], [[AND]]
4691 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 0
4692 ; CHECK-NEXT: ret i8 [[RES]]
4694 %x.lo = and i8 %x, 1
4695 %cmp = icmp eq i8 %x.lo, 0
4696 %and = and i8 %x, -2
4697 %mul = mul i8 %and, %and
4698 %res = select i1 %cmp, i8 %mul, i8 0
4702 define i8 @select_knownbits_simplify_missing_noundef(i8 %x) {
4703 ; CHECK-LABEL: @select_knownbits_simplify_missing_noundef(
4704 ; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1
4705 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4706 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
4707 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0
4708 ; CHECK-NEXT: ret i8 [[RES]]
4710 %x.lo = and i8 %x, 1
4711 %cmp = icmp eq i8 %x.lo, 0
4712 %and = and i8 %x, -2
4713 %res = select i1 %cmp, i8 %and, i8 0
4717 @g_ext = external global i8
4719 ; Make sure we don't replace %ptr with @g_ext, which may cause the load to trigger UB.
4720 define i32 @pr99436(ptr align 4 dereferenceable(4) %ptr) {
4721 ; CHECK-LABEL: @pr99436(
4722 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[PTR:%.*]], @g_ext
4723 ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[PTR]], align 4
4724 ; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[VAL]], i32 0
4725 ; CHECK-NEXT: ret i32 [[RET]]
4727 %cmp = icmp eq ptr %ptr, @g_ext
4728 %val = load i32, ptr %ptr, align 4
4729 %ret = select i1 %cmp, i32 %val, i32 0
4733 define i8 @sel_trunc_simplify(i1 %c, i8 %x, i16 %y) {
4734 ; CHECK-LABEL: @sel_trunc_simplify(
4735 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i16 [[Y:%.*]] to i8
4736 ; CHECK-NEXT: [[TRUNC:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
4737 ; CHECK-NEXT: ret i8 [[TRUNC]]
4739 %x.ext = zext i8 %x to i16
4740 %sel = select i1 %c, i16 %x.ext, i16 %y
4741 %trunc = trunc i16 %sel to i8
4745 define i32 @sel_umin_simplify(i1 %c, i32 %x, i16 %y) {
4746 ; CHECK-LABEL: @sel_umin_simplify(
4747 ; CHECK-NEXT: [[ARG2_EXT:%.*]] = zext i16 [[ARG2:%.*]] to i32
4748 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[ARG2_EXT]])
4749 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[C:%.*]], i32 [[TMP1]], i32 0
4750 ; CHECK-NEXT: ret i32 [[RES]]
4752 %sel = select i1 %c, i32 %x, i32 0
4753 %y.ext = zext i16 %y to i32
4754 %res = call i32 @llvm.umin.i32(i32 %sel, i32 %y.ext)
4758 define i32 @sel_extractvalue_simplify(i1 %c, { i32, i32 } %agg1, i32 %x, i32 %y) {
4759 ; CHECK-LABEL: @sel_extractvalue_simplify(
4760 ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i32 } [[AGG1:%.*]], 1
4761 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[C:%.*]], i32 [[TMP1]], i32 [[Y:%.*]]
4762 ; CHECK-NEXT: ret i32 [[RES]]
4764 %agg2.0 = insertvalue { i32, i32 } poison, i32 %x, 0
4765 %agg2.1 = insertvalue { i32, i32 } %agg2.0, i32 %y, 1
4766 %sel = select i1 %c, { i32, i32 } %agg1, { i32, i32 } %agg2.1
4767 %res = extractvalue { i32, i32 } %sel, 1