1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,CONSTVEC
3 ; RUN: opt < %s -passes=instcombine -S -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=CHECK,CONSTSPLAT
5 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n32:64"
9 define i32 @test12(i32 %A) {
10 ; CHECK-LABEL: @test12(
11 ; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], 8
12 ; CHECK-NEXT: ret i32 [[C]]
19 define i32 @test13(i32 %A) {
20 ; CHECK-LABEL: @test13(
21 ; CHECK-NEXT: ret i32 8
29 define i1 @test14(i32 %A, i32 %B) {
30 ; CHECK-LABEL: @test14(
31 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
32 ; CHECK-NEXT: ret i1 [[D]]
34 %C1 = icmp ult i32 %A, %B
35 %C2 = icmp ugt i32 %A, %B
36 ; (A < B) | (A > B) === A != B
41 define i1 @test14_commuted(i32 %A, i32 %B) {
42 ; CHECK-LABEL: @test14_commuted(
43 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], [[A:%.*]]
44 ; CHECK-NEXT: ret i1 [[D]]
46 %C1 = icmp ult i32 %A, %B
47 %C2 = icmp ult i32 %B, %A
48 ; (A < B) | (A > B) === A != B
53 define i1 @test14_logical(i32 %A, i32 %B) {
54 ; CHECK-LABEL: @test14_logical(
55 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
56 ; CHECK-NEXT: ret i1 [[D]]
58 %C1 = icmp ult i32 %A, %B
59 %C2 = icmp ugt i32 %A, %B
60 ; (A < B) | (A > B) === A != B
61 %D = select i1 %C1, i1 true, i1 %C2
65 define i1 @test15(i32 %A, i32 %B) {
66 ; CHECK-LABEL: @test15(
67 ; CHECK-NEXT: [[D:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
68 ; CHECK-NEXT: ret i1 [[D]]
70 %C1 = icmp ult i32 %A, %B
71 %C2 = icmp eq i32 %A, %B
72 ; (A < B) | (A == B) === A <= B
77 define i1 @test15_logical(i32 %A, i32 %B) {
78 ; CHECK-LABEL: @test15_logical(
79 ; CHECK-NEXT: [[D:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
80 ; CHECK-NEXT: ret i1 [[D]]
82 %C1 = icmp ult i32 %A, %B
83 %C2 = icmp eq i32 %A, %B
84 ; (A < B) | (A == B) === A <= B
85 %D = select i1 %C1, i1 true, i1 %C2
89 define i32 @test16(i32 %A) {
90 ; CHECK-LABEL: @test16(
91 ; CHECK-NEXT: ret i32 [[A:%.*]]
96 ; %D = and int %B, -1 == %B
101 define i32 @test17(i32 %A) {
102 ; CHECK-LABEL: @test17(
103 ; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], 5
104 ; CHECK-NEXT: ret i32 [[D]]
113 define i1 @test18(i32 %A) {
114 ; CHECK-LABEL: @test18(
115 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100
116 ; CHECK-NEXT: [[D:%.*]] = icmp ult i32 [[TMP1]], -50
117 ; CHECK-NEXT: ret i1 [[D]]
119 %B = icmp sge i32 %A, 100
120 %C = icmp slt i32 %A, 50
125 define i1 @test18_logical(i32 %A) {
126 ; CHECK-LABEL: @test18_logical(
127 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100
128 ; CHECK-NEXT: [[D:%.*]] = icmp ult i32 [[TMP1]], -50
129 ; CHECK-NEXT: ret i1 [[D]]
131 %B = icmp sge i32 %A, 100
132 %C = icmp slt i32 %A, 50
133 %D = select i1 %B, i1 true, i1 %C
137 define <2 x i1> @test18vec(<2 x i32> %A) {
138 ; CHECK-LABEL: @test18vec(
139 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -100)
140 ; CHECK-NEXT: [[D:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -50)
141 ; CHECK-NEXT: ret <2 x i1> [[D]]
143 %B = icmp sge <2 x i32> %A, <i32 100, i32 100>
144 %C = icmp slt <2 x i32> %A, <i32 50, i32 50>
145 %D = or <2 x i1> %B, %C
149 define i32 @test20(i32 %x) {
150 ; CHECK-LABEL: @test20(
151 ; CHECK-NEXT: ret i32 [[X:%.*]]
158 ; TODO: This should combine to t1 + 2.
159 define i32 @test21(i32 %t1) {
160 ; CHECK-LABEL: @test21(
161 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[T1:%.*]], -2
162 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[TMP1]], 2
163 ; CHECK-NEXT: [[T5:%.*]] = and i32 [[T1]], 1
164 ; CHECK-NEXT: [[T6:%.*]] = or disjoint i32 [[T5]], [[T3]]
165 ; CHECK-NEXT: ret i32 [[T6]]
167 %t1.mask1 = add i32 %t1, 2
168 %t3 = and i32 %t1.mask1, -2
171 %t6 = or i32 %t5, %t3
175 define i32 @test22(i32 %B) {
176 ; CHECK-LABEL: @test22(
177 ; CHECK-NEXT: ret i32 [[B:%.*]]
179 %ELIM41 = and i32 %B, 1
180 %ELIM7 = and i32 %B, -2
181 %ELIM5 = or i32 %ELIM41, %ELIM7
185 define i16 @test23(i16 %A) {
186 ; CHECK-LABEL: @test23(
187 ; CHECK-NEXT: [[B:%.*]] = lshr i16 [[A:%.*]], 1
188 ; CHECK-NEXT: [[D:%.*]] = xor i16 [[B]], -24575
189 ; CHECK-NEXT: ret i16 [[D]]
193 %C = or i16 %B, -32768
194 %D = xor i16 %C, 8193
198 define <2 x i16> @test23vec(<2 x i16> %A) {
199 ; CHECK-LABEL: @test23vec(
200 ; CHECK-NEXT: [[B:%.*]] = lshr <2 x i16> [[A:%.*]], splat (i16 1)
201 ; CHECK-NEXT: [[D:%.*]] = xor <2 x i16> [[B]], splat (i16 -24575)
202 ; CHECK-NEXT: ret <2 x i16> [[D]]
204 %B = lshr <2 x i16> %A, <i16 1, i16 1>
206 %C = or <2 x i16> %B, <i16 -32768, i16 -32768>
207 %D = xor <2 x i16> %C, <i16 8193, i16 8193>
212 define i1 @test25(i32 %A, i32 %B) {
213 ; CHECK-LABEL: @test25(
214 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
215 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
216 ; CHECK-NEXT: [[E_NOT:%.*]] = and i1 [[C]], [[D]]
217 ; CHECK-NEXT: ret i1 [[E_NOT]]
219 %C = icmp eq i32 %A, 0
220 %D = icmp eq i32 %B, 57
226 define i1 @test25_logical(i32 %A, i32 %B) {
227 ; CHECK-LABEL: @test25_logical(
228 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
229 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
230 ; CHECK-NEXT: [[E_NOT:%.*]] = select i1 [[C]], i1 [[D]], i1 false
231 ; CHECK-NEXT: ret i1 [[E_NOT]]
233 %C = icmp eq i32 %A, 0
234 %D = icmp eq i32 %B, 57
235 %E = select i1 %C, i1 true, i1 %D
241 define i1 @and_icmp_eq_0(i32 %A, i32 %B) {
242 ; CHECK-LABEL: @and_icmp_eq_0(
243 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
244 ; CHECK-NEXT: [[D:%.*]] = icmp eq i32 [[TMP1]], 0
245 ; CHECK-NEXT: ret i1 [[D]]
247 %C1 = icmp eq i32 %A, 0
248 %C2 = icmp eq i32 %B, 0
249 ; (A == 0) & (A == 0) --> (A|B) == 0
254 define <2 x i1> @and_icmp_eq_0_vector(<2 x i32> %A, <2 x i32> %B) {
255 ; CHECK-LABEL: @and_icmp_eq_0_vector(
256 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
257 ; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
258 ; CHECK-NEXT: ret <2 x i1> [[D]]
260 %C1 = icmp eq <2 x i32> %A, zeroinitializer
261 %C2 = icmp eq <2 x i32> %B, zeroinitializer
262 %D = and <2 x i1> %C1, %C2
266 define <2 x i1> @and_icmp_eq_0_vector_poison1(<2 x i32> %A, <2 x i32> %B) {
267 ; CHECK-LABEL: @and_icmp_eq_0_vector_poison1(
268 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
269 ; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
270 ; CHECK-NEXT: ret <2 x i1> [[D]]
272 %C1 = icmp eq <2 x i32> %A, <i32 0, i32 poison>
273 %C2 = icmp eq <2 x i32> %B, <i32 0, i32 poison>
274 %D = and <2 x i1> %C1, %C2
278 define <2 x i1> @and_icmp_eq_0_vector_poison2(<2 x i32> %A, <2 x i32> %B) {
279 ; CHECK-LABEL: @and_icmp_eq_0_vector_poison2(
280 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
281 ; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
282 ; CHECK-NEXT: ret <2 x i1> [[D]]
284 %C1 = icmp eq <2 x i32> %A, <i32 0, i32 poison>
285 %C2 = icmp eq <2 x i32> %B, <i32 poison, i32 0>
286 %D = and <2 x i1> %C1, %C2
290 define i1 @and_icmp_eq_0_logical(i32 %A, i32 %B) {
291 ; CHECK-LABEL: @and_icmp_eq_0_logical(
292 ; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[A:%.*]], 0
293 ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[B:%.*]], 0
294 ; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
295 ; CHECK-NEXT: ret i1 [[D]]
297 %C1 = icmp eq i32 %A, 0
298 %C2 = icmp eq i32 %B, 0
299 ; (A == 0) & (A == 0) --> (A|B) == 0
300 %D = select i1 %C1, i1 %C2, i1 false
304 define i1 @test27(ptr %A, ptr %B) {
305 ; CHECK-LABEL: @test27(
306 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[A:%.*]], null
307 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq ptr [[B:%.*]], null
308 ; CHECK-NEXT: [[E:%.*]] = and i1 [[TMP1]], [[TMP2]]
309 ; CHECK-NEXT: ret i1 [[E]]
311 %C1 = ptrtoint ptr %A to i32
312 %C2 = ptrtoint ptr %B to i32
314 %E = icmp eq i32 %D, 0
318 define <2 x i1> @test27vec(<2 x ptr> %A, <2 x ptr> %B) {
319 ; CHECK-LABEL: @test27vec(
320 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x ptr> [[A:%.*]], zeroinitializer
321 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x ptr> [[B:%.*]], zeroinitializer
322 ; CHECK-NEXT: [[E:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]]
323 ; CHECK-NEXT: ret <2 x i1> [[E]]
325 %C1 = ptrtoint <2 x ptr> %A to <2 x i32>
326 %C2 = ptrtoint <2 x ptr> %B to <2 x i32>
327 %D = or <2 x i32> %C1, %C2
328 %E = icmp eq <2 x i32> %D, zeroinitializer
333 define i1 @test28(i32 %A, i32 %B) {
334 ; CHECK-LABEL: @test28(
335 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
336 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[TMP1]], 0
337 ; CHECK-NEXT: ret i1 [[D]]
339 %C1 = icmp ne i32 %A, 0
340 %C2 = icmp ne i32 %B, 0
341 ; (A != 0) | (A != 0) --> (A|B) != 0
346 define i1 @test28_logical(i32 %A, i32 %B) {
347 ; CHECK-LABEL: @test28_logical(
348 ; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[A:%.*]], 0
349 ; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 [[B:%.*]], 0
350 ; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
351 ; CHECK-NEXT: ret i1 [[D]]
353 %C1 = icmp ne i32 %A, 0
354 %C2 = icmp ne i32 %B, 0
355 ; (A != 0) | (A != 0) --> (A|B) != 0
356 %D = select i1 %C1, i1 true, i1 %C2
360 define i1 @test29(ptr %A, ptr %B) {
361 ; CHECK-LABEL: @test29(
362 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr [[A:%.*]], null
363 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne ptr [[B:%.*]], null
364 ; CHECK-NEXT: [[E:%.*]] = or i1 [[TMP1]], [[TMP2]]
365 ; CHECK-NEXT: ret i1 [[E]]
367 %C1 = ptrtoint ptr %A to i32
368 %C2 = ptrtoint ptr %B to i32
370 %E = icmp ne i32 %D, 0
374 define <2 x i1> @test29vec(<2 x ptr> %A, <2 x ptr> %B) {
375 ; CHECK-LABEL: @test29vec(
376 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x ptr> [[A:%.*]], zeroinitializer
377 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x ptr> [[B:%.*]], zeroinitializer
378 ; CHECK-NEXT: [[E:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
379 ; CHECK-NEXT: ret <2 x i1> [[E]]
381 %C1 = ptrtoint <2 x ptr> %A to <2 x i32>
382 %C2 = ptrtoint <2 x ptr> %B to <2 x i32>
383 %D = or <2 x i32> %C1, %C2
384 %E = icmp ne <2 x i32> %D, zeroinitializer
389 define i32 @test30(i32 %A) {
390 ; CHECK-LABEL: @test30(
391 ; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], -58312
392 ; CHECK-NEXT: [[E:%.*]] = or disjoint i32 [[D]], 32962
393 ; CHECK-NEXT: ret i32 [[E]]
395 %B = or i32 %A, 32962 ; 0b1000_0000_1100_0010
396 %C = and i32 %A, -65536 ; 0xffff0000
397 %D = and i32 %B, 40186 ; 0b1001_1100_1111_1010
402 define <2 x i32> @test30vec(<2 x i32> %A) {
403 ; CONSTVEC-LABEL: @test30vec(
404 ; CONSTVEC-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -58312)
405 ; CONSTVEC-NEXT: [[E:%.*]] = or disjoint <2 x i32> [[TMP1]], splat (i32 32962)
406 ; CONSTVEC-NEXT: ret <2 x i32> [[E]]
408 ; CONSTSPLAT-LABEL: @test30vec(
409 ; CONSTSPLAT-NEXT: [[D:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -58312)
410 ; CONSTSPLAT-NEXT: [[E:%.*]] = or disjoint <2 x i32> [[D]], splat (i32 32962)
411 ; CONSTSPLAT-NEXT: ret <2 x i32> [[E]]
413 %B = or <2 x i32> %A, <i32 32962, i32 32962>
414 %C = and <2 x i32> %A, <i32 -65536, i32 -65536>
415 %D = and <2 x i32> %B, <i32 40186, i32 40186>
416 %E = or <2 x i32> %D, %C
421 define i64 @test31(i64 %A) {
422 ; CHECK-LABEL: @test31(
423 ; CHECK-NEXT: [[E:%.*]] = and i64 [[A:%.*]], 4294908984
424 ; CHECK-NEXT: [[F:%.*]] = or disjoint i64 [[E]], 32962
425 ; CHECK-NEXT: ret i64 [[F]]
430 %C = or i64 %A, 32768
431 %E = and i64 %C, 4294941696
437 define <2 x i64> @test31vec(<2 x i64> %A) {
438 ; CHECK-LABEL: @test31vec(
439 ; CHECK-NEXT: [[E:%.*]] = and <2 x i64> [[A:%.*]], splat (i64 4294908984)
440 ; CHECK-NEXT: [[F:%.*]] = or disjoint <2 x i64> [[E]], splat (i64 32962)
441 ; CHECK-NEXT: ret <2 x i64> [[F]]
443 %B = or <2 x i64> %A, <i64 194, i64 194>
444 %D = and <2 x i64> %B, <i64 250, i64 250>
446 %C = or <2 x i64> %A, <i64 32768, i64 32768>
447 %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696>
449 %F = or <2 x i64> %D, %E
453 ; codegen is mature enough to handle vector selects.
454 define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) {
455 ; CHECK-LABEL: @test32(
456 ; CHECK-NEXT: [[OR_I:%.*]] = select <4 x i1> [[AND_I1352:%.*]], <4 x i32> [[VECINIT6_I176:%.*]], <4 x i32> [[VECINIT6_I191:%.*]]
457 ; CHECK-NEXT: ret <4 x i32> [[OR_I]]
459 %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32>
460 %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135
461 %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1>
462 %and.i = and <4 x i32> %vecinit6.i191, %neg.i
463 %or.i = or <4 x i32> %and.i, %and.i129
467 define i1 @test33(i1 %X, i1 %Y) {
468 ; CHECK-LABEL: @test33(
469 ; CHECK-NEXT: [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
470 ; CHECK-NEXT: ret i1 [[A]]
477 define i1 @test33_logical(i1 %X, i1 %Y) {
478 ; CHECK-LABEL: @test33_logical(
479 ; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]
480 ; CHECK-NEXT: ret i1 [[A]]
482 %a = select i1 %X, i1 true, i1 %Y
483 %b = select i1 %a, i1 true, i1 %X
487 define i32 @test34(i32 %X, i32 %Y) {
488 ; CHECK-LABEL: @test34(
489 ; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
490 ; CHECK-NEXT: ret i32 [[A]]
497 define i32 @test35(i32 %a, i32 %b) {
498 ; CHECK-LABEL: @test35(
499 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
500 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 1135
501 ; CHECK-NEXT: ret i32 [[TMP2]]
508 define i1 @test36(i32 %x) {
509 ; CHECK-LABEL: @test36(
510 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23
511 ; CHECK-NEXT: [[RET2:%.*]] = icmp ult i32 [[TMP1]], 3
512 ; CHECK-NEXT: ret i1 [[RET2]]
514 %cmp1 = icmp eq i32 %x, 23
515 %cmp2 = icmp eq i32 %x, 24
516 %ret1 = or i1 %cmp1, %cmp2
517 %cmp3 = icmp eq i32 %x, 25
518 %ret2 = or i1 %ret1, %cmp3
522 define i1 @test36_logical(i32 %x) {
523 ; CHECK-LABEL: @test36_logical(
524 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23
525 ; CHECK-NEXT: [[RET2:%.*]] = icmp ult i32 [[TMP1]], 3
526 ; CHECK-NEXT: ret i1 [[RET2]]
528 %cmp1 = icmp eq i32 %x, 23
529 %cmp2 = icmp eq i32 %x, 24
530 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
531 %cmp3 = icmp eq i32 %x, 25
532 %ret2 = select i1 %ret1, i1 true, i1 %cmp3
536 define i1 @test37(i32 %x) {
537 ; CHECK-LABEL: @test37(
538 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
539 ; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31
540 ; CHECK-NEXT: ret i1 [[RET1]]
542 %add1 = add i32 %x, 7
543 %cmp1 = icmp ult i32 %add1, 30
544 %cmp2 = icmp eq i32 %x, 23
545 %ret1 = or i1 %cmp1, %cmp2
549 define i1 @test37_logical(i32 %x) {
550 ; CHECK-LABEL: @test37_logical(
551 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
552 ; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31
553 ; CHECK-NEXT: ret i1 [[RET1]]
555 %add1 = add i32 %x, 7
556 %cmp1 = icmp ult i32 %add1, 30
557 %cmp2 = icmp eq i32 %x, 23
558 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
562 define <2 x i1> @test37_uniform(<2 x i32> %x) {
563 ; CHECK-LABEL: @test37_uniform(
564 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 7)
565 ; CHECK-NEXT: [[RET1:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 31)
566 ; CHECK-NEXT: ret <2 x i1> [[RET1]]
568 %add1 = add <2 x i32> %x, <i32 7, i32 7>
569 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 30>
570 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 23>
571 %ret1 = or <2 x i1> %cmp1, %cmp2
575 define <2 x i1> @test37_poison(<2 x i32> %x) {
576 ; CHECK-LABEL: @test37_poison(
577 ; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 poison>
578 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 poison>
579 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 poison>
580 ; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
581 ; CHECK-NEXT: ret <2 x i1> [[RET1]]
583 %add1 = add <2 x i32> %x, <i32 7, i32 poison>
584 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 poison>
585 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 poison>
586 %ret1 = or <2 x i1> %cmp1, %cmp2
590 define i1 @test38(i32 %x) {
591 ; CHECK-LABEL: @test38(
592 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
593 ; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31
594 ; CHECK-NEXT: ret i1 [[RET1]]
596 %add1 = add i32 %x, 7
597 %cmp1 = icmp eq i32 %x, 23
598 %cmp2 = icmp ult i32 %add1, 30
599 %ret1 = or i1 %cmp1, %cmp2
603 define i1 @test38_logical(i32 %x) {
604 ; CHECK-LABEL: @test38_logical(
605 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
606 ; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31
607 ; CHECK-NEXT: ret i1 [[RET1]]
609 %add1 = add i32 %x, 7
610 %cmp1 = icmp eq i32 %x, 23
611 %cmp2 = icmp ult i32 %add1, 30
612 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
616 define <2 x i1> @test38_nonuniform(<2 x i32> %x) {
617 ; CHECK-LABEL: @test38_nonuniform(
618 ; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 24>
619 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 8>
620 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 32>
621 ; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
622 ; CHECK-NEXT: ret <2 x i1> [[RET1]]
624 %add1 = add <2 x i32> %x, <i32 7, i32 24>
625 %cmp1 = icmp eq <2 x i32> %x, <i32 23, i32 8>
626 %cmp2 = icmp ult <2 x i32> %add1, <i32 30, i32 32>
627 %ret1 = or <2 x i1> %cmp1, %cmp2
631 ; (~A & B) | A --> A | B
633 define i32 @test39a(i32 %a, float %b) {
634 ; CHECK-LABEL: @test39a(
635 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
636 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
637 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
638 ; CHECK-NEXT: ret i32 [[OR]]
640 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
641 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
642 %nota = xor i32 %a1, -1
643 %and = and i32 %nota, %b1
644 %or = or i32 %and, %a1
648 ; Commute 'and' operands:
649 ; (B & ~A) | A --> A | B
651 define i32 @test39b(i32 %a, float %b) {
652 ; CHECK-LABEL: @test39b(
653 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
654 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
655 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
656 ; CHECK-NEXT: ret i32 [[OR]]
658 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
659 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
660 %nota = xor i32 %a1, -1
661 %and = and i32 %b1, %nota
662 %or = or i32 %and, %a1
666 ; Commute 'or' operands:
667 ; A | (~A & B) --> A | B
669 define i32 @test39c(i32 %a, float %b) {
670 ; CHECK-LABEL: @test39c(
671 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
672 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
673 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
674 ; CHECK-NEXT: ret i32 [[OR]]
676 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
677 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
678 %nota = xor i32 %a1, -1
679 %and = and i32 %nota, %b1
680 %or = or i32 %a1, %and
684 ; Commute 'and' operands:
685 ; A | (B & ~A) --> A | B
687 define i32 @test39d(i32 %a, float %b) {
688 ; CHECK-LABEL: @test39d(
689 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
690 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
691 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
692 ; CHECK-NEXT: ret i32 [[OR]]
694 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
695 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
696 %nota = xor i32 %a1, -1
697 %and = and i32 %b1, %nota
698 %or = or i32 %a1, %and
702 define i32 @test40(i32 %a, i32 %b) {
703 ; CHECK-LABEL: @test40(
704 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
705 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]
706 ; CHECK-NEXT: ret i32 [[OR]]
708 %and = and i32 %a, %b
709 %xor = xor i32 %a, -1
710 %or = or i32 %and, %xor
714 define i32 @test40b(i32 %a, i32 %b) {
715 ; CHECK-LABEL: @test40b(
716 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
717 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]
718 ; CHECK-NEXT: ret i32 [[OR]]
720 %and = and i32 %b, %a
721 %xor = xor i32 %a, -1
722 %or = or i32 %and, %xor
726 define i32 @test40c(i32 %a, i32 %b) {
727 ; CHECK-LABEL: @test40c(
728 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
729 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]
730 ; CHECK-NEXT: ret i32 [[OR]]
732 %and = and i32 %b, %a
733 %xor = xor i32 %a, -1
734 %or = or i32 %xor, %and
738 define i32 @test40d(i32 %a, i32 %b) {
739 ; CHECK-LABEL: @test40d(
740 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
741 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]
742 ; CHECK-NEXT: ret i32 [[OR]]
744 %and = and i32 %a, %b
745 %xor = xor i32 %a, -1
746 %or = or i32 %xor, %and
750 define i32 @test45(i32 %x, i32 %y, i32 %z) {
751 ; CHECK-LABEL: @test45(
752 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
753 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]]
754 ; CHECK-NEXT: ret i32 [[OR1]]
757 %and = and i32 %x, %or
758 %or1 = or i32 %and, %y
762 define i32 @test45_uses1(i32 %x, i32 %y, i32 %z) {
763 ; CHECK-LABEL: @test45_uses1(
764 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[Z:%.*]]
765 ; CHECK-NEXT: call void @use(i32 [[OR]])
766 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z]]
767 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y]]
768 ; CHECK-NEXT: ret i32 [[OR1]]
771 call void @use(i32 %or)
772 %and = and i32 %x, %or
773 %or1 = or i32 %and, %y
777 define i32 @test45_uses2(i32 %x, i32 %y, i32 %z) {
778 ; CHECK-LABEL: @test45_uses2(
779 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[Z:%.*]]
780 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[OR]]
781 ; CHECK-NEXT: call void @use(i32 [[AND]])
782 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[AND]], [[Y]]
783 ; CHECK-NEXT: ret i32 [[OR1]]
786 %and = and i32 %x, %or
787 call void @use(i32 %and)
788 %or1 = or i32 %and, %y
792 define i32 @test45_commuted1(i32 %x, i32 %y, i32 %z) {
793 ; CHECK-LABEL: @test45_commuted1(
794 ; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
795 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Z:%.*]], [[X:%.*]]
796 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]
797 ; CHECK-NEXT: ret i32 [[OR1]]
799 %yy = mul i32 %y, %y ; thwart complexity-based ordering
801 %and = and i32 %or, %x
802 %or1 = or i32 %yy, %and
806 define i32 @test45_commuted2(i32 %x, i32 %y, i32 %z) {
807 ; CHECK-LABEL: @test45_commuted2(
808 ; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
809 ; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]
810 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[XX]], [[Z:%.*]]
811 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[YY]]
812 ; CHECK-NEXT: ret i32 [[OR1]]
814 %yy = mul i32 %y, %y ; thwart complexity-based ordering
815 %xx = mul i32 %x, %x ; thwart complexity-based ordering
817 %and = and i32 %xx, %or
818 %or1 = or i32 %and, %yy
822 define i32 @test45_commuted3(i32 %x, i32 %y, i32 %z) {
823 ; CHECK-LABEL: @test45_commuted3(
824 ; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
825 ; CHECK-NEXT: [[ZZ:%.*]] = mul i32 [[Z:%.*]], [[Z]]
826 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZZ]], [[X:%.*]]
827 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[YY]]
828 ; CHECK-NEXT: ret i32 [[OR1]]
830 %yy = mul i32 %y, %y ; thwart complexity-based ordering
831 %zz = mul i32 %z, %z ; thwart complexity-based ordering
832 %or = or i32 %zz, %yy
833 %and = and i32 %or, %x
834 %or1 = or i32 %and, %yy
838 define i1 @test46(i8 signext %c) {
839 ; CHECK-LABEL: @test46(
840 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
841 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
842 ; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 26
843 ; CHECK-NEXT: ret i1 [[OR]]
845 %c.off = add i8 %c, -97
846 %cmp1 = icmp ult i8 %c.off, 26
847 %c.off17 = add i8 %c, -65
848 %cmp2 = icmp ult i8 %c.off17, 26
849 %or = or i1 %cmp1, %cmp2
853 define i1 @test46_logical(i8 signext %c) {
854 ; CHECK-LABEL: @test46_logical(
855 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
856 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
857 ; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 26
858 ; CHECK-NEXT: ret i1 [[OR]]
860 %c.off = add i8 %c, -97
861 %cmp1 = icmp ult i8 %c.off, 26
862 %c.off17 = add i8 %c, -65
863 %cmp2 = icmp ult i8 %c.off17, 26
864 %or = select i1 %cmp1, i1 true, i1 %cmp2
868 define <2 x i1> @test46_uniform(<2 x i8> %c) {
869 ; CHECK-LABEL: @test46_uniform(
870 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[C:%.*]], splat (i8 -33)
871 ; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[TMP1]], splat (i8 -65)
872 ; CHECK-NEXT: [[OR:%.*]] = icmp ult <2 x i8> [[TMP2]], splat (i8 26)
873 ; CHECK-NEXT: ret <2 x i1> [[OR]]
875 %c.off = add <2 x i8> %c, <i8 -97, i8 -97>
876 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 26>
877 %c.off17 = add <2 x i8> %c, <i8 -65, i8 -65>
878 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 26>
879 %or = or <2 x i1> %cmp1, %cmp2
883 define <2 x i1> @test46_poison(<2 x i8> %c) {
884 ; CHECK-LABEL: @test46_poison(
885 ; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 poison>
886 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 26, i8 poison>
887 ; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -65, i8 poison>
888 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 26, i8 poison>
889 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
890 ; CHECK-NEXT: ret <2 x i1> [[OR]]
892 %c.off = add <2 x i8> %c, <i8 -97, i8 poison>
893 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 poison>
894 %c.off17 = add <2 x i8> %c, <i8 -65, i8 poison>
895 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 poison>
896 %or = or <2 x i1> %cmp1, %cmp2
900 ; This is the variant of the above pattern where one of the ranges is
901 ; represented with an add.
902 define i1 @two_ranges_to_mask_and_range_degenerate(i16 %x) {
903 ; CHECK-LABEL: @two_ranges_to_mask_and_range_degenerate(
904 ; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], -20
905 ; CHECK-NEXT: [[OR:%.*]] = icmp ult i16 [[TMP1]], 12
906 ; CHECK-NEXT: ret i1 [[OR]]
908 %cmp1 = icmp ult i16 %x, 12
909 %cmp2 = icmp uge i16 %x, 16
910 %cmp3 = icmp ult i16 %x, 28
911 %and = and i1 %cmp2, %cmp3
912 %or = or i1 %cmp1, %and
916 define i1 @test47(i8 signext %c) {
917 ; CHECK-LABEL: @test47(
918 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
919 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
920 ; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 27
921 ; CHECK-NEXT: ret i1 [[OR]]
923 %c.off = add i8 %c, -65
924 %cmp1 = icmp ule i8 %c.off, 26
925 %c.off17 = add i8 %c, -97
926 %cmp2 = icmp ule i8 %c.off17, 26
927 %or = or i1 %cmp1, %cmp2
931 define i1 @test47_logical(i8 signext %c) {
932 ; CHECK-LABEL: @test47_logical(
933 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
934 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
935 ; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 27
936 ; CHECK-NEXT: ret i1 [[OR]]
938 %c.off = add i8 %c, -65
939 %cmp1 = icmp ule i8 %c.off, 26
940 %c.off17 = add i8 %c, -97
941 %cmp2 = icmp ule i8 %c.off17, 26
942 %or = select i1 %cmp1, i1 true, i1 %cmp2
946 define <2 x i1> @test47_nonuniform(<2 x i8> %c) {
947 ; CHECK-LABEL: @test47_nonuniform(
948 ; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -65, i8 -97>
949 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], splat (i8 27)
950 ; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -97, i8 -65>
951 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], splat (i8 27)
952 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
953 ; CHECK-NEXT: ret <2 x i1> [[OR]]
955 %c.off = add <2 x i8> %c, <i8 -65, i8 -97>
956 %cmp1 = icmp ule <2 x i8> %c.off, <i8 26, i8 26>
957 %c.off17 = add <2 x i8> %c, <i8 -97, i8 -65>
958 %cmp2 = icmp ule <2 x i8> %c.off17, <i8 26, i8 26>
959 %or = or <2 x i1> %cmp1, %cmp2
963 define i32 @test49(i1 %C) {
964 ; CHECK-LABEL: @test49(
965 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1019, i32 123
966 ; CHECK-NEXT: ret i32 [[V]]
968 %A = select i1 %C, i32 1000, i32 10
973 define <2 x i32> @test49vec(i1 %C) {
974 ; CHECK-LABEL: @test49vec(
975 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 1019), <2 x i32> splat (i32 123)
976 ; CHECK-NEXT: ret <2 x i32> [[V]]
978 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
979 %V = or <2 x i32> %A, <i32 123, i32 123>
983 define <2 x i32> @test49vec2(i1 %C) {
984 ; CHECK-LABEL: @test49vec2(
985 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 2509>, <2 x i32> <i32 123, i32 351>
986 ; CHECK-NEXT: ret <2 x i32> [[V]]
988 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
989 %V = or <2 x i32> %A, <i32 123, i32 333>
993 define i32 @test50(i1 %which) {
994 ; CHECK-LABEL: @test50(
996 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
998 ; CHECK-NEXT: br label [[FINAL]]
1000 ; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1019, [[ENTRY:%.*]] ], [ 123, [[DELAY]] ]
1001 ; CHECK-NEXT: ret i32 [[A]]
1004 br i1 %which, label %final, label %delay
1010 %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
1011 %value = or i32 %A, 123
1015 define <2 x i32> @test50vec(i1 %which) {
1016 ; CHECK-LABEL: @test50vec(
1017 ; CHECK-NEXT: entry:
1018 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1020 ; CHECK-NEXT: br label [[FINAL]]
1022 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ splat (i32 1019), [[ENTRY:%.*]] ], [ splat (i32 123), [[DELAY]] ]
1023 ; CHECK-NEXT: ret <2 x i32> [[A]]
1026 br i1 %which, label %final, label %delay
1032 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
1033 %value = or <2 x i32> %A, <i32 123, i32 123>
1034 ret <2 x i32> %value
1037 define <2 x i32> @test50vec2(i1 %which) {
1038 ; CHECK-LABEL: @test50vec2(
1039 ; CHECK-NEXT: entry:
1040 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1042 ; CHECK-NEXT: br label [[FINAL]]
1044 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 2509>, [[ENTRY:%.*]] ], [ <i32 123, i32 351>, [[DELAY]] ]
1045 ; CHECK-NEXT: ret <2 x i32> [[A]]
1048 br i1 %which, label %final, label %delay
1054 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
1055 %value = or <2 x i32> %A, <i32 123, i32 333>
1056 ret <2 x i32> %value
1059 ; In the next 4 tests, vary the types and predicates for extra coverage.
1060 ; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp
1062 define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) {
1063 ; CHECK-LABEL: @or_andn_cmp_1(
1064 ; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
1065 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1066 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]
1067 ; CHECK-NEXT: ret i1 [[OR]]
1069 %x = icmp sgt i32 %a, %b
1070 %x_inv = icmp sle i32 %a, %b
1071 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1072 %and = and i1 %y, %x_inv
1073 %or = or i1 %x, %and
1077 define i1 @or_andn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {
1078 ; CHECK-LABEL: @or_andn_cmp_1_logical(
1079 ; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
1080 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1081 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
1082 ; CHECK-NEXT: ret i1 [[OR]]
1084 %x = icmp sgt i32 %a, %b
1085 %x_inv = icmp sle i32 %a, %b
1086 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1087 %and = select i1 %y, i1 %x_inv, i1 false
1088 %or = select i1 %x, i1 true, i1 %and
1093 ; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp
1095 define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
1096 ; CHECK-LABEL: @or_andn_cmp_2(
1097 ; CHECK-NEXT: [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
1098 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
1099 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[Y]], [[X]]
1100 ; CHECK-NEXT: ret <2 x i1> [[OR]]
1102 %x = icmp sge <2 x i32> %a, %b
1103 %x_inv = icmp slt <2 x i32> %a, %b
1104 %y = icmp ugt <2 x i32> %c, <i32 42, i32 47> ; thwart complexity-based ordering
1105 %and = and <2 x i1> %y, %x_inv
1106 %or = or <2 x i1> %and, %x
1110 ; Commute the 'and':
1111 ; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp
1113 define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) {
1114 ; CHECK-LABEL: @or_andn_cmp_3(
1115 ; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1116 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1117 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]
1118 ; CHECK-NEXT: ret i1 [[OR]]
1120 %x = icmp ugt i72 %a, %b
1121 %x_inv = icmp ule i72 %a, %b
1122 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering
1123 %and = and i1 %x_inv, %y
1124 %or = or i1 %x, %and
1128 define i1 @or_andn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {
1129 ; CHECK-LABEL: @or_andn_cmp_3_logical(
1130 ; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1131 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1132 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
1133 ; CHECK-NEXT: ret i1 [[OR]]
1135 %x = icmp ugt i72 %a, %b
1136 %x_inv = icmp ule i72 %a, %b
1137 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering
1138 %and = select i1 %x_inv, i1 %y, i1 false
1139 %or = select i1 %x, i1 true, i1 %and
1144 ; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp
1146 define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
1147 ; CHECK-LABEL: @or_andn_cmp_4(
1148 ; CHECK-NEXT: [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
1149 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
1150 ; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[Y]], [[X]]
1151 ; CHECK-NEXT: ret <3 x i1> [[OR]]
1153 %x = icmp eq <3 x i32> %a, %b
1154 %x_inv = icmp ne <3 x i32> %a, %b
1155 %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1> ; thwart complexity-based ordering
1156 %and = and <3 x i1> %x_inv, %y
1157 %or = or <3 x i1> %and, %x
1161 ; In the next 4 tests, vary the types and predicates for extra coverage.
1162 ; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp
1164 define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) {
1165 ; CHECK-LABEL: @orn_and_cmp_1(
1166 ; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1167 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1168 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_INV]], [[Y]]
1169 ; CHECK-NEXT: ret i1 [[OR]]
1171 %x = icmp sgt i37 %a, %b
1172 %x_inv = icmp sle i37 %a, %b
1173 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering
1174 %and = and i1 %y, %x
1175 %or = or i1 %x_inv, %and
1179 define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i37 %c) {
1180 ; CHECK-LABEL: @orn_and_cmp_1_logical(
1181 ; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1182 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1183 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1184 ; CHECK-NEXT: ret i1 [[OR]]
1186 %x = icmp sgt i37 %a, %b
1187 %x_inv = icmp sle i37 %a, %b
1188 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering
1189 %and = select i1 %y, i1 %x, i1 false
1190 %or = select i1 %x_inv, i1 true, i1 %and
1195 ; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1197 define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) {
1198 ; CHECK-LABEL: @orn_and_cmp_2(
1199 ; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1200 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1201 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1202 ; CHECK-NEXT: ret i1 [[OR]]
1204 %x = icmp sge i16 %a, %b
1205 %x_inv = icmp slt i16 %a, %b
1206 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering
1207 %and = and i1 %y, %x
1208 %or = or i1 %and, %x_inv
1212 define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i16 %c) {
1213 ; CHECK-LABEL: @orn_and_cmp_2_logical(
1214 ; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1215 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1216 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y]], i1 true, i1 [[X_INV]]
1217 ; CHECK-NEXT: ret i1 [[OR]]
1219 %x = icmp sge i16 %a, %b
1220 %x_inv = icmp slt i16 %a, %b
1221 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering
1222 %and = select i1 %y, i1 %x, i1 false
1223 %or = select i1 %and, i1 true, i1 %x_inv
1227 ; Commute the 'and':
1228 ; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp
1230 define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
1231 ; CHECK-LABEL: @orn_and_cmp_3(
1232 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
1233 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
1234 ; CHECK-NEXT: [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]]
1235 ; CHECK-NEXT: ret <4 x i1> [[OR]]
1237 %x = icmp ugt <4 x i32> %a, %b
1238 %x_inv = icmp ule <4 x i32> %a, %b
1239 %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1> ; thwart complexity-based ordering
1240 %and = and <4 x i1> %x, %y
1241 %or = or <4 x i1> %x_inv, %and
1246 ; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1248 define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) {
1249 ; CHECK-LABEL: @orn_and_cmp_4(
1250 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1251 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1252 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1253 ; CHECK-NEXT: ret i1 [[OR]]
1255 %x = icmp eq i32 %a, %b
1256 %x_inv = icmp ne i32 %a, %b
1257 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1258 %and = and i1 %x, %y
1259 %or = or i1 %and, %x_inv
1263 define i1 @orn_and_cmp_4_logical(i32 %a, i32 %b, i32 %c) {
1264 ; CHECK-LABEL: @orn_and_cmp_4_logical(
1265 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1266 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1267 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1268 ; CHECK-NEXT: ret i1 [[OR]]
1270 %x = icmp eq i32 %a, %b
1271 %x_inv = icmp ne i32 %a, %b
1272 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1273 %and = select i1 %x, i1 %y, i1 false
1274 %or = select i1 %and, i1 true, i1 %x_inv
1278 ; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1.
1279 define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {
1280 ; CHECK-LABEL: @test51(
1281 ; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <16 x i1> [[ARG:%.*]], <16 x i1> [[ARG1:%.*]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 20, i32 5, i32 6, i32 23, i32 24, i32 9, i32 10, i32 27, i32 28, i32 29, i32 30, i32 31>
1282 ; CHECK-NEXT: ret <16 x i1> [[TMP3]]
1284 %tmp = and <16 x i1> %arg, <i1 true, i1 true, i1 true, i1 true, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false>
1285 %tmp2 = and <16 x i1> %arg1, <i1 false, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 true, i1 true, i1 true>
1286 %tmp3 = or <16 x i1> %tmp, %tmp2
1290 ; This would infinite loop because it reaches a transform
1291 ; that was not expecting a constant-foldable value.
1293 define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) {
1294 ; CHECK-LABEL: @PR46712(
1295 ; CHECK-NEXT: entry:
1296 ; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1298 ; CHECK-NEXT: [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 0
1299 ; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[BOOL5_NOT]] to i32
1300 ; CHECK-NEXT: br label [[END]]
1302 ; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0]], [[TRUE]] ]
1303 ; CHECK-NEXT: ret i32 [[T5]]
1307 %conv = sext i1 %t2 to i32
1308 %cmp = icmp sge i32 %conv, 1
1309 %conv2 = zext i1 %cmp to i64
1310 br i1 %b, label %true, label %end
1313 %bool4 = icmp eq i64 %conv2, 0
1314 %bool5 = icmp ne i64 %z, 0
1315 %and = and i1 %bool4, %bool5
1316 %sel = select i1 %and, i1 false, i1 true
1320 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1321 %conv8 = zext i1 %t5 to i32
1325 define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) {
1326 ; CHECK-LABEL: @PR46712_logical(
1327 ; CHECK-NEXT: entry:
1328 ; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1330 ; CHECK-NEXT: [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 0
1331 ; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[BOOL5_NOT]] to i32
1332 ; CHECK-NEXT: br label [[END]]
1334 ; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0]], [[TRUE]] ]
1335 ; CHECK-NEXT: ret i32 [[T5]]
1338 %t2 = select i1 %x, i1 true, i1 %y
1339 %conv = sext i1 %t2 to i32
1340 %cmp = icmp sge i32 %conv, 1
1341 %conv2 = zext i1 %cmp to i64
1342 br i1 %b, label %true, label %end
1345 %bool4 = icmp eq i64 %conv2, 0
1346 %bool5 = icmp ne i64 %z, 0
1347 %and = select i1 %bool4, i1 %bool5, i1 false
1348 %sel = select i1 %and, i1 false, i1 true
1352 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1353 %conv8 = zext i1 %t5 to i32
1357 ; (~x & y) | ~(x | y) --> ~x
1358 define i32 @PR38929(i32 %0, i32 %1) {
1359 ; CHECK-LABEL: @PR38929(
1360 ; CHECK-NEXT: [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], -1
1361 ; CHECK-NEXT: ret i32 [[TMP3]]
1371 define i32 @test1(i32 %x, i32 %y) {
1372 ; CHECK-LABEL: @test1(
1373 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1374 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1375 ; CHECK-NEXT: ret i32 [[OR1]]
1377 %xor = xor i32 %y, %x
1379 %neg = xor i32 %or, -1
1380 %or1 = or i32 %xor, %neg
1384 define i32 @test2(i32 %x, i32 %y) {
1385 ; CHECK-LABEL: @test2(
1386 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1387 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1388 ; CHECK-NEXT: ret i32 [[OR1]]
1391 %neg = xor i32 %or, -1
1392 %xor = xor i32 %y, %x
1393 %or1 = or i32 %xor, %neg
1397 define i32 @test3(i32 %x, i32 %y) {
1398 ; CHECK-LABEL: @test3(
1399 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
1400 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1401 ; CHECK-NEXT: ret i32 [[OR1]]
1404 %neg = xor i32 %or, -1
1405 %xor = xor i32 %x, %y
1406 %or1 = or i32 %xor, %neg
1410 define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) {
1411 ; CHECK-LABEL: @test4_vec(
1412 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]]
1413 ; CHECK-NEXT: [[OR1:%.*]] = xor <2 x i32> [[TMP1]], splat (i32 -1)
1414 ; CHECK-NEXT: ret <2 x i32> [[OR1]]
1416 %or = or <2 x i32> %y, %x
1417 %neg = xor <2 x i32> %or, <i32 -1, i32 -1>
1418 %xor = xor <2 x i32> %y, %x
1419 %or1 = or <2 x i32> %xor, %neg
1423 define i32 @test5_use(i32 %x, i32 %y) {
1424 ; CHECK-LABEL: @test5_use(
1425 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1426 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -1
1427 ; CHECK-NEXT: call void @use(i32 [[NEG]])
1428 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1429 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1430 ; CHECK-NEXT: ret i32 [[OR1]]
1433 %neg = xor i32 %or, -1
1434 %xor = xor i32 %y, %x
1435 call void @use(i32 %neg)
1436 %or1 = or i32 %xor, %neg
1440 define i32 @test5_use2(i32 %x, i32 %y) {
1441 ; CHECK-LABEL: @test5_use2(
1442 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1443 ; CHECK-NEXT: call void @use(i32 [[XOR]])
1444 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1445 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1446 ; CHECK-NEXT: ret i32 [[OR1]]
1449 %neg = xor i32 %or, -1
1450 %xor = xor i32 %y, %x
1451 call void @use(i32 %xor)
1452 %or1 = or i32 %xor, %neg
1455 define i32 @test5_use3(i32 %x, i32 %y) {
1456 ; CHECK-LABEL: @test5_use3(
1457 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1458 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -1
1459 ; CHECK-NEXT: call void @use(i32 [[NEG]])
1460 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]]
1461 ; CHECK-NEXT: call void @use(i32 [[XOR]])
1462 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
1463 ; CHECK-NEXT: ret i32 [[OR1]]
1466 %neg = xor i32 %or, -1
1467 call void @use(i32 %neg)
1468 %xor = xor i32 %y, %x
1469 call void @use(i32 %xor)
1470 %or1 = or i32 %xor, %neg
1474 define i8 @ashr_bitwidth_mask(i8 %x, i8 %y) {
1475 ; CHECK-LABEL: @ashr_bitwidth_mask(
1476 ; CHECK-NEXT: [[SIGN:%.*]] = ashr i8 [[X:%.*]], 7
1477 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1478 ; CHECK-NEXT: ret i8 [[R]]
1480 %sign = ashr i8 %x, 7
1481 %r = or i8 %sign, %y
1485 define <2 x i8> @ashr_bitwidth_mask_vec_commute(<2 x i8> %x, <2 x i8> %py) {
1486 ; CHECK-LABEL: @ashr_bitwidth_mask_vec_commute(
1487 ; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], <i8 42, i8 2>
1488 ; CHECK-NEXT: [[SIGN:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 7)
1489 ; CHECK-NEXT: [[R:%.*]] = or <2 x i8> [[Y]], [[SIGN]]
1490 ; CHECK-NEXT: ret <2 x i8> [[R]]
1492 %y = mul <2 x i8> %py, <i8 42, i8 2> ; thwart complexity-based ordering
1493 %sign = ashr <2 x i8> %x, <i8 7, i8 7>
1494 %r = or <2 x i8> %y, %sign
1498 define i32 @ashr_bitwidth_mask_use(i32 %x, i32 %y) {
1499 ; CHECK-LABEL: @ashr_bitwidth_mask_use(
1500 ; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X:%.*]], 7
1501 ; CHECK-NEXT: call void @use(i32 [[SIGN]])
1502 ; CHECK-NEXT: [[R:%.*]] = or i32 [[SIGN]], [[Y:%.*]]
1503 ; CHECK-NEXT: ret i32 [[R]]
1505 %sign = ashr i32 %x, 7
1506 call void @use(i32 %sign)
1507 %r = or i32 %sign, %y
1511 define i8 @ashr_not_bitwidth_mask(i8 %x, i8 %y) {
1512 ; CHECK-LABEL: @ashr_not_bitwidth_mask(
1513 ; CHECK-NEXT: [[SIGN:%.*]] = ashr i8 [[X:%.*]], 6
1514 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1515 ; CHECK-NEXT: ret i8 [[R]]
1517 %sign = ashr i8 %x, 6
1518 %r = or i8 %sign, %y
1522 define i8 @lshr_bitwidth_mask(i8 %x, i8 %y) {
1523 ; CHECK-LABEL: @lshr_bitwidth_mask(
1524 ; CHECK-NEXT: [[SIGN:%.*]] = lshr i8 [[X:%.*]], 7
1525 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1526 ; CHECK-NEXT: ret i8 [[R]]
1528 %sign = lshr i8 %x, 7
1529 %r = or i8 %sign, %y
1533 define i1 @cmp_overlap(i32 %x) {
1534 ; CHECK-LABEL: @cmp_overlap(
1535 ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[X:%.*]], 1
1536 ; CHECK-NEXT: ret i1 [[R]]
1538 %isneg = icmp slt i32 %x, 0
1539 %negx = sub i32 0, %x
1540 %isnotneg = icmp sgt i32 %negx, -1
1541 %r = or i1 %isneg, %isnotneg
1545 define <2 x i1> @cmp_overlap_splat(<2 x i5> %x) {
1546 ; CHECK-LABEL: @cmp_overlap_splat(
1547 ; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i5> [[X:%.*]], splat (i5 1)
1548 ; CHECK-NEXT: ret <2 x i1> [[R]]
1550 %isneg = icmp slt <2 x i5> %x, zeroinitializer
1551 %negx = sub <2 x i5> zeroinitializer, %x
1552 %isnotneg = icmp sgt <2 x i5> %negx, <i5 -1, i5 -1>
1553 %r = or <2 x i1> %isneg, %isnotneg
1557 define i32 @mul_no_common_bits(i32 %p1, i32 %p2) {
1558 ; CHECK-LABEL: @mul_no_common_bits(
1559 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 7
1560 ; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1561 ; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i32 [[Y]], 1
1562 ; CHECK-NEXT: [[R:%.*]] = mul i32 [[X]], [[TMP1]]
1563 ; CHECK-NEXT: ret i32 [[R]]
1572 define i32 @mul_no_common_bits_const_op(i32 %p) {
1573 ; CHECK-LABEL: @mul_no_common_bits_const_op(
1574 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7
1575 ; CHECK-NEXT: [[R:%.*]] = mul nuw nsw i32 [[X]], 25
1576 ; CHECK-NEXT: ret i32 [[R]]
1584 define <2 x i12> @mul_no_common_bits_commute(<2 x i12> %p) {
1585 ; CHECK-LABEL: @mul_no_common_bits_commute(
1586 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i12> [[P:%.*]] to <2 x i1>
1587 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP1]], <2 x i12> <i12 15, i12 17>, <2 x i12> zeroinitializer
1588 ; CHECK-NEXT: ret <2 x i12> [[R]]
1590 %x = and <2 x i12> %p, <i12 1, i12 1>
1591 %m = mul <2 x i12> %x, <i12 14, i12 16>
1592 %r = or <2 x i12> %x, %m
1596 define i32 @mul_no_common_bits_commute2(i32 %p1, i32 %p2) {
1597 ; CHECK-LABEL: @mul_no_common_bits_commute2(
1598 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 7
1599 ; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1600 ; CHECK-NEXT: [[M:%.*]] = mul i32 [[Y]], [[X]]
1601 ; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[M]], [[X]]
1602 ; CHECK-NEXT: ret i32 [[R]]
1611 define i32 @mul_no_common_bits_disjoint(i32 %x, i32 %y) {
1612 ; CHECK-LABEL: @mul_no_common_bits_disjoint(
1613 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], 1
1614 ; CHECK-NEXT: [[R:%.*]] = mul i32 [[X:%.*]], [[TMP1]]
1615 ; CHECK-NEXT: ret i32 [[R]]
1618 %r = or disjoint i32 %m, %x
1622 define i32 @mul_no_common_bits_const_op_disjoint(i32 %x, i32 %y) {
1623 ; CHECK-LABEL: @mul_no_common_bits_const_op_disjoint(
1624 ; CHECK-NEXT: [[R:%.*]] = mul i32 [[X:%.*]], 25
1625 ; CHECK-NEXT: ret i32 [[R]]
1628 %r = or disjoint i32 %m, %x
1632 ; negative test - extra use requires extra instructions
1634 define i32 @mul_no_common_bits_uses(i32 %p1, i32 %p2) {
1635 ; CHECK-LABEL: @mul_no_common_bits_uses(
1636 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 7
1637 ; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1638 ; CHECK-NEXT: [[M:%.*]] = mul i32 [[X]], [[Y]]
1639 ; CHECK-NEXT: call void @use(i32 [[M]])
1640 ; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[M]], [[X]]
1641 ; CHECK-NEXT: ret i32 [[R]]
1646 call void @use(i32 %m)
1651 ; negative test - probably not good to create an extra mul
1653 define i32 @mul_no_common_bits_const_op_uses(i32 %p) {
1654 ; CHECK-LABEL: @mul_no_common_bits_const_op_uses(
1655 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7
1656 ; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X]], 24
1657 ; CHECK-NEXT: call void @use(i32 [[M]])
1658 ; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[M]], [[X]]
1659 ; CHECK-NEXT: ret i32 [[R]]
1663 call void @use(i32 %m)
1668 ; negative test - %x and %m may have set 3rd bit
1670 define i32 @mul_common_bits(i32 %p) {
1671 ; CHECK-LABEL: @mul_common_bits(
1672 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7
1673 ; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X]], 12
1674 ; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[X]]
1675 ; CHECK-NEXT: ret i32 [[R]]
1683 define <4 x i1> @and_or_not_or_logical_vec(<4 x i32> %ap, <4 x i32> %bp) {
1684 ; CHECK-LABEL: @and_or_not_or_logical_vec(
1685 ; CHECK-NEXT: [[A:%.*]] = icmp ne <4 x i32> [[AP:%.*]], zeroinitializer
1686 ; CHECK-NEXT: ret <4 x i1> [[A]]
1688 %A = icmp eq <4 x i32> %ap, zeroinitializer
1689 %B = icmp eq <4 x i32> %bp, zeroinitializer
1690 %V = xor <4 x i1> %A, <i1 true, i1 true, i1 true, i1 true>
1691 %X = select <4 x i1> %B, <4 x i1> %V, <4 x i1> zeroinitializer
1692 %W = or <4 x i1> %B, %A
1693 %Y = xor <4 x i1> %W, <i1 true, i1 true, i1 true, i1 true>
1694 %Z = or <4 x i1> %X, %Y
1698 ; Make sure SimplifyDemandedBits drops the disjoint flag.
1699 define i8 @drop_disjoint(i8 %x) {
1700 ; CHECK-LABEL: @drop_disjoint(
1701 ; CHECK-NEXT: [[B:%.*]] = or i8 [[X:%.*]], 1
1702 ; CHECK-NEXT: ret i8 [[B]]
1705 %b = or disjoint i8 %a, 1
1709 ; Make sure we drop disjoint when combining the Ors.
1710 define i32 @assoc_cast_assoc_disjoint(i16 %x) {
1711 ; CHECK-LABEL: @assoc_cast_assoc_disjoint(
1712 ; CHECK-NEXT: [[B:%.*]] = zext i16 [[X:%.*]] to i32
1713 ; CHECK-NEXT: [[C:%.*]] = or i32 [[B]], 65537
1714 ; CHECK-NEXT: ret i32 [[C]]
1717 %b = zext i16 %a to i32
1718 %c = or disjoint i32 %b, 65536
1722 ; (X & C1) | C2 -> X & (C1 | C2) iff (X & C2) == C2
1723 define i32 @test_or_and_disjoint(i32 %a) {
1724 ; CHECK-LABEL: @test_or_and_disjoint(
1725 ; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 24
1726 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 8
1727 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1729 ; CHECK-NEXT: [[A2:%.*]] = and i32 [[A]], 15
1730 ; CHECK-NEXT: ret i32 [[A2]]
1732 ; CHECK-NEXT: ret i32 0
1734 %a0 = and i32 %a, 24
1735 %cmp = icmp eq i32 %a0, 8
1736 br i1 %cmp, label %if.then, label %if.else
1745 define i32 @test_or_and_mixed(i32 %a) {
1746 ; CHECK-LABEL: @test_or_and_mixed(
1747 ; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 27
1748 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 11
1749 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1751 ; CHECK-NEXT: [[A2:%.*]] = and i32 [[A]], 15
1752 ; CHECK-NEXT: ret i32 [[A2]]
1754 ; CHECK-NEXT: ret i32 0
1756 %a0 = and i32 %a, 27
1757 %cmp = icmp eq i32 %a0, 11
1758 br i1 %cmp, label %if.then, label %if.else
1761 %a2 = or i32 %a1, 11
1769 define i32 @test_or_and_disjoint_fail(i32 %a) {
1770 ; CHECK-LABEL: @test_or_and_disjoint_fail(
1771 ; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 24
1772 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 16
1773 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1775 ; CHECK-NEXT: [[A1:%.*]] = and i32 [[A]], 7
1776 ; CHECK-NEXT: [[A2:%.*]] = or disjoint i32 [[A1]], 8
1777 ; CHECK-NEXT: ret i32 [[A2]]
1779 ; CHECK-NEXT: ret i32 0
1781 %a0 = and i32 %a, 24
1782 %cmp = icmp eq i32 %a0, 16
1783 br i1 %cmp, label %if.then, label %if.else
1792 define i32 @test_or_and_disjoint_multiuse(i32 %a) {
1793 ; CHECK-LABEL: @test_or_and_disjoint_multiuse(
1794 ; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 24
1795 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 8
1796 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1798 ; CHECK-NEXT: [[A1:%.*]] = and i32 [[A]], 7
1799 ; CHECK-NEXT: call void @use(i32 [[A1]])
1800 ; CHECK-NEXT: [[A2:%.*]] = or disjoint i32 [[A1]], 8
1801 ; CHECK-NEXT: ret i32 [[A2]]
1803 ; CHECK-NEXT: ret i32 0
1805 %a0 = and i32 %a, 24
1806 %cmp = icmp eq i32 %a0, 8
1807 br i1 %cmp, label %if.then, label %if.else
1810 call void @use(i32 %a1)
1817 ; Tests from PR76554
1818 define i32 @test_or_and_xor_constant(i32 %x, i32 %y) {
1819 ; CHECK-LABEL: @test_or_and_xor_constant(
1820 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1821 ; CHECK-NEXT: [[D:%.*]] = and i32 [[TMP1]], -2147483648
1822 ; CHECK-NEXT: ret i32 [[D]]
1824 %a = and i32 %x, -2147483648
1825 %b = xor i32 %a, -2147483648
1831 define i32 @test_or_and_xor(i32 %a, i32 %b, i32 %c) {
1832 ; CHECK-LABEL: @test_or_and_xor(
1833 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
1834 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1835 ; CHECK-NEXT: ret i32 [[OR]]
1837 %xor = xor i32 %a, %b
1838 %and = and i32 %xor, %c
1839 %or = or i32 %and, %a
1843 define i32 @test_or_and_xor_commuted1(i32 %a, i32 %b, i32 %c) {
1844 ; CHECK-LABEL: @test_or_and_xor_commuted1(
1845 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
1846 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1847 ; CHECK-NEXT: ret i32 [[OR]]
1849 %xor = xor i32 %b, %a
1850 %and = and i32 %xor, %c
1851 %or = or i32 %and, %a
1855 define i32 @test_or_and_xor_commuted2(i32 %a, i32 %b, i32 %c) {
1856 ; CHECK-LABEL: @test_or_and_xor_commuted2(
1857 ; CHECK-NEXT: [[CC:%.*]] = mul i32 [[C:%.*]], [[C]]
1858 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[CC]], [[B:%.*]]
1859 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1860 ; CHECK-NEXT: ret i32 [[OR]]
1862 %cc = mul i32 %c, %c
1863 %xor = xor i32 %a, %b
1864 %and = and i32 %cc, %xor
1865 %or = or i32 %and, %a
1869 define i32 @test_or_and_xor_commuted3(i32 %a, i32 %b, i32 %c) {
1870 ; CHECK-LABEL: @test_or_and_xor_commuted3(
1871 ; CHECK-NEXT: [[AA:%.*]] = mul i32 [[A:%.*]], [[A]]
1872 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
1873 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[AA]], [[TMP1]]
1874 ; CHECK-NEXT: ret i32 [[OR]]
1876 %aa = mul i32 %a, %a
1877 %xor = xor i32 %aa, %b
1878 %and = and i32 %xor, %c
1879 %or = or i32 %aa, %and
1883 define i32 @test_or_and_xor_multiuse1(i32 %a, i32 %b, i32 %c) {
1884 ; CHECK-LABEL: @test_or_and_xor_multiuse1(
1885 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
1886 ; CHECK-NEXT: call void @use(i32 [[XOR]])
1887 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C:%.*]]
1888 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A]]
1889 ; CHECK-NEXT: ret i32 [[OR]]
1891 %xor = xor i32 %a, %b
1892 call void @use(i32 %xor)
1893 %and = and i32 %xor, %c
1894 %or = or i32 %and, %a
1900 define i32 @test_or_and_xor_mismatched_op(i32 %a, i32 %b, i32 %c, i32 %d) {
1901 ; CHECK-LABEL: @test_or_and_xor_mismatched_op(
1902 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
1903 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[C:%.*]]
1904 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[D:%.*]]
1905 ; CHECK-NEXT: ret i32 [[OR]]
1907 %xor = xor i32 %a, %b
1908 %and = and i32 %xor, %c
1909 %or = or i32 %and, %d
1913 define i32 @test_or_and_xor_multiuse2(i32 %a, i32 %b, i32 %c) {
1914 ; CHECK-LABEL: @test_or_and_xor_multiuse2(
1915 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
1916 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[C:%.*]]
1917 ; CHECK-NEXT: call void @use(i32 [[AND]])
1918 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[A]]
1919 ; CHECK-NEXT: ret i32 [[OR]]
1921 %xor = xor i32 %a, %b
1922 %and = and i32 %xor, %c
1923 call void @use(i32 %and)
1924 %or = or i32 %and, %a
1928 define i32 @test_or_add_xor(i32 %a, i32 %b, i32 %c) {
1929 ; CHECK-LABEL: @test_or_add_xor(
1930 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
1931 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[XOR]], [[C:%.*]]
1932 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[ADD]], [[A]]
1933 ; CHECK-NEXT: ret i32 [[OR]]
1935 %xor = xor i32 %a, %b
1936 %add = add i32 %xor, %c
1937 %or = or i32 %add, %a
1941 define i32 @test_or_and_and_multiuse(i32 %a, i32 %b, i32 %c) {
1942 ; CHECK-LABEL: @test_or_and_and_multiuse(
1943 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
1944 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]
1945 ; CHECK-NEXT: call void @use(i32 [[AND1]])
1946 ; CHECK-NEXT: call void @use(i32 [[AND2]])
1947 ; CHECK-NEXT: ret i32 [[A]]
1949 %and1 = and i32 %a, %b
1950 %and2 = and i32 %and1, %c
1951 call void @use(i32 %and1)
1952 call void @use(i32 %and2)
1953 %or = or i32 %and2, %a
1957 define i32 @or_xor_and(i32 %x, i32 %y, i32 %z) {
1958 ; CHECK-LABEL: @or_xor_and(
1959 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
1960 ; CHECK-NEXT: ret i32 [[OR1]]
1962 %and = and i32 %y, %z
1963 %xor = xor i32 %x, %and
1964 %or1 = or i32 %xor, %y
1968 define i32 @or_xor_and_uses1(i32 %x, i32 %y, i32 %z) {
1969 ; CHECK-LABEL: @or_xor_and_uses1(
1970 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[Z:%.*]]
1971 ; CHECK-NEXT: call void @use(i32 [[AND]])
1972 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[Y]]
1973 ; CHECK-NEXT: ret i32 [[OR1]]
1975 %and = and i32 %y, %z
1976 call void @use(i32 %and)
1977 %xor = xor i32 %x, %and
1978 %or1 = or i32 %xor, %y
1982 define i32 @or_xor_and_uses2(i32 %x, i32 %y, i32 %z) {
1983 ; CHECK-LABEL: @or_xor_and_uses2(
1984 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[Z:%.*]]
1985 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[AND]]
1986 ; CHECK-NEXT: call void @use(i32 [[XOR]])
1987 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X]], [[Y]]
1988 ; CHECK-NEXT: ret i32 [[OR1]]
1990 %and = and i32 %y, %z
1991 %xor = xor i32 %x, %and
1992 call void @use(i32 %xor)
1993 %or1 = or i32 %xor, %y
1997 define i32 @or_xor_and_commuted1(i32 %x, i32 %y, i32 %z) {
1998 ; CHECK-LABEL: @or_xor_and_commuted1(
1999 ; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
2000 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[X:%.*]]
2001 ; CHECK-NEXT: ret i32 [[OR1]]
2003 %yy = mul i32 %y, %y ; thwart complexity-based ordering
2004 %and = and i32 %yy, %z
2005 %xor = xor i32 %and, %x
2006 %or1 = or i32 %yy, %xor
2010 define i32 @or_xor_and_commuted2(i32 %x, i32 %y, i32 %z) {
2011 ; CHECK-LABEL: @or_xor_and_commuted2(
2012 ; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
2013 ; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]
2014 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XX]], [[YY]]
2015 ; CHECK-NEXT: ret i32 [[OR1]]
2017 %yy = mul i32 %y, %y ; thwart complexity-based ordering
2018 %xx = mul i32 %x, %x ; thwart complexity-based ordering
2019 %and = and i32 %yy, %z
2020 %xor = xor i32 %xx, %and
2021 %or1 = or i32 %xor, %yy
2025 define i32 @or_xor_and_commuted3(i32 %x, i32 %y, i32 %z) {
2026 ; CHECK-LABEL: @or_xor_and_commuted3(
2027 ; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
2028 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[YY]]
2029 ; CHECK-NEXT: ret i32 [[OR1]]
2031 %yy = mul i32 %y, %y ; thwart complexity-based ordering
2032 %zz = mul i32 %z, %z ; thwart complexity-based ordering
2033 %and = and i32 %zz, %yy
2034 %xor = xor i32 %and, %x
2035 %or1 = or i32 %xor, %yy