1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 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"
8 define i32 @test12(i32 %A) {
9 ; CHECK-LABEL: @test12(
10 ; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], 8
11 ; CHECK-NEXT: ret i32 [[C]]
18 define i32 @test13(i32 %A) {
19 ; CHECK-LABEL: @test13(
20 ; CHECK-NEXT: ret i32 8
28 define i1 @test14(i32 %A, i32 %B) {
29 ; CHECK-LABEL: @test14(
30 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
31 ; CHECK-NEXT: ret i1 [[TMP1]]
33 %C1 = icmp ult i32 %A, %B
34 %C2 = icmp ugt i32 %A, %B
35 ; (A < B) | (A > B) === A != B
40 define i1 @test14_commuted(i32 %A, i32 %B) {
41 ; CHECK-LABEL: @test14_commuted(
42 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[B:%.*]], [[A:%.*]]
43 ; CHECK-NEXT: ret i1 [[TMP1]]
45 %C1 = icmp ult i32 %A, %B
46 %C2 = icmp ult i32 %B, %A
47 ; (A < B) | (A > B) === A != B
52 define i1 @test14_logical(i32 %A, i32 %B) {
53 ; CHECK-LABEL: @test14_logical(
54 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
55 ; CHECK-NEXT: ret i1 [[TMP1]]
57 %C1 = icmp ult i32 %A, %B
58 %C2 = icmp ugt i32 %A, %B
59 ; (A < B) | (A > B) === A != B
60 %D = select i1 %C1, i1 true, i1 %C2
64 define i1 @test15(i32 %A, i32 %B) {
65 ; CHECK-LABEL: @test15(
66 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
67 ; CHECK-NEXT: ret i1 [[TMP1]]
69 %C1 = icmp ult i32 %A, %B
70 %C2 = icmp eq i32 %A, %B
71 ; (A < B) | (A == B) === A <= B
76 define i1 @test15_logical(i32 %A, i32 %B) {
77 ; CHECK-LABEL: @test15_logical(
78 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
79 ; CHECK-NEXT: ret i1 [[TMP1]]
81 %C1 = icmp ult i32 %A, %B
82 %C2 = icmp eq i32 %A, %B
83 ; (A < B) | (A == B) === A <= B
84 %D = select i1 %C1, i1 true, i1 %C2
88 define i32 @test16(i32 %A) {
89 ; CHECK-LABEL: @test16(
90 ; CHECK-NEXT: ret i32 [[A:%.*]]
95 ; %D = and int %B, -1 == %B
100 define i32 @test17(i32 %A) {
101 ; CHECK-LABEL: @test17(
102 ; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], 5
103 ; CHECK-NEXT: ret i32 [[D]]
112 define i1 @test18(i32 %A) {
113 ; CHECK-LABEL: @test18(
114 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100
115 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -50
116 ; CHECK-NEXT: ret i1 [[TMP2]]
118 %B = icmp sge i32 %A, 100
119 %C = icmp slt i32 %A, 50
124 define i1 @test18_logical(i32 %A) {
125 ; CHECK-LABEL: @test18_logical(
126 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100
127 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -50
128 ; CHECK-NEXT: ret i1 [[TMP2]]
130 %B = icmp sge i32 %A, 100
131 %C = icmp slt i32 %A, 50
132 %D = select i1 %B, i1 true, i1 %C
136 define <2 x i1> @test18vec(<2 x i32> %A) {
137 ; CHECK-LABEL: @test18vec(
138 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], <i32 -100, i32 -100>
139 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 -50, i32 -50>
140 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
142 %B = icmp sge <2 x i32> %A, <i32 100, i32 100>
143 %C = icmp slt <2 x i32> %A, <i32 50, i32 50>
144 %D = or <2 x i1> %B, %C
148 define i32 @test20(i32 %x) {
149 ; CHECK-LABEL: @test20(
150 ; CHECK-NEXT: ret i32 [[X:%.*]]
157 define i32 @test21(i32 %t1) {
158 ; CHECK-LABEL: @test21(
159 ; CHECK-NEXT: [[T1_MASK1:%.*]] = add i32 [[T1:%.*]], 2
160 ; CHECK-NEXT: ret i32 [[T1_MASK1]]
162 %t1.mask1 = add i32 %t1, 2
163 %t3 = and i32 %t1.mask1, -2
166 %t6 = or i32 %t5, %t3
170 define i32 @test22(i32 %B) {
171 ; CHECK-LABEL: @test22(
172 ; CHECK-NEXT: ret i32 [[B:%.*]]
174 %ELIM41 = and i32 %B, 1
175 %ELIM7 = and i32 %B, -2
176 %ELIM5 = or i32 %ELIM41, %ELIM7
180 define i16 @test23(i16 %A) {
181 ; CHECK-LABEL: @test23(
182 ; CHECK-NEXT: [[B:%.*]] = lshr i16 [[A:%.*]], 1
183 ; CHECK-NEXT: [[D:%.*]] = xor i16 [[B]], -24575
184 ; CHECK-NEXT: ret i16 [[D]]
188 %C = or i16 %B, -32768
189 %D = xor i16 %C, 8193
193 define <2 x i16> @test23vec(<2 x i16> %A) {
194 ; CHECK-LABEL: @test23vec(
195 ; CHECK-NEXT: [[B:%.*]] = lshr <2 x i16> [[A:%.*]], <i16 1, i16 1>
196 ; CHECK-NEXT: [[D:%.*]] = xor <2 x i16> [[B]], <i16 -24575, i16 -24575>
197 ; CHECK-NEXT: ret <2 x i16> [[D]]
199 %B = lshr <2 x i16> %A, <i16 1, i16 1>
201 %C = or <2 x i16> %B, <i16 -32768, i16 -32768>
202 %D = xor <2 x i16> %C, <i16 8193, i16 8193>
207 define i1 @test25(i32 %A, i32 %B) {
208 ; CHECK-LABEL: @test25(
209 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
210 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
211 ; CHECK-NEXT: [[F:%.*]] = and i1 [[C]], [[D]]
212 ; CHECK-NEXT: ret i1 [[F]]
214 %C = icmp eq i32 %A, 0
215 %D = icmp eq i32 %B, 57
221 define i1 @test25_logical(i32 %A, i32 %B) {
222 ; CHECK-LABEL: @test25_logical(
223 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
224 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
225 ; CHECK-NEXT: [[E:%.*]] = select i1 [[C]], i1 [[D]], i1 false
226 ; CHECK-NEXT: ret i1 [[E]]
228 %C = icmp eq i32 %A, 0
229 %D = icmp eq i32 %B, 57
230 %E = select i1 %C, i1 true, i1 %D
236 define i1 @and_icmp_eq_0(i32 %A, i32 %B) {
237 ; CHECK-LABEL: @and_icmp_eq_0(
238 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
239 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
240 ; CHECK-NEXT: ret i1 [[TMP2]]
242 %C1 = icmp eq i32 %A, 0
243 %C2 = icmp eq i32 %B, 0
244 ; (A == 0) & (A == 0) --> (A|B) == 0
249 define <2 x i1> @and_icmp_eq_0_vector(<2 x i32> %A, <2 x i32> %B) {
250 ; CHECK-LABEL: @and_icmp_eq_0_vector(
251 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
252 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
253 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
255 %C1 = icmp eq <2 x i32> %A, zeroinitializer
256 %C2 = icmp eq <2 x i32> %B, zeroinitializer
257 %D = and <2 x i1> %C1, %C2
261 define <2 x i1> @and_icmp_eq_0_vector_undef1(<2 x i32> %A, <2 x i32> %B) {
262 ; CHECK-LABEL: @and_icmp_eq_0_vector_undef1(
263 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
264 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
265 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
267 %C1 = icmp eq <2 x i32> %A, <i32 0, i32 undef>
268 %C2 = icmp eq <2 x i32> %B, <i32 0, i32 undef>
269 %D = and <2 x i1> %C1, %C2
273 define <2 x i1> @and_icmp_eq_0_vector_undef2(<2 x i32> %A, <2 x i32> %B) {
274 ; CHECK-LABEL: @and_icmp_eq_0_vector_undef2(
275 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
276 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
277 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
279 %C1 = icmp eq <2 x i32> %A, <i32 0, i32 undef>
280 %C2 = icmp eq <2 x i32> %B, <i32 undef, i32 0>
281 %D = and <2 x i1> %C1, %C2
285 define i1 @and_icmp_eq_0_logical(i32 %A, i32 %B) {
286 ; CHECK-LABEL: @and_icmp_eq_0_logical(
287 ; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[A:%.*]], 0
288 ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[B:%.*]], 0
289 ; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
290 ; CHECK-NEXT: ret i1 [[D]]
292 %C1 = icmp eq i32 %A, 0
293 %C2 = icmp eq i32 %B, 0
294 ; (A == 0) & (A == 0) --> (A|B) == 0
295 %D = select i1 %C1, i1 %C2, i1 false
299 define i1 @test27(i32* %A, i32* %B) {
300 ; CHECK-LABEL: @test27(
301 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32* [[A:%.*]], null
302 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32* [[B:%.*]], null
303 ; CHECK-NEXT: [[E:%.*]] = and i1 [[TMP1]], [[TMP2]]
304 ; CHECK-NEXT: ret i1 [[E]]
306 %C1 = ptrtoint i32* %A to i32
307 %C2 = ptrtoint i32* %B to i32
309 %E = icmp eq i32 %D, 0
313 define <2 x i1> @test27vec(<2 x i32*> %A, <2 x i32*> %B) {
314 ; CHECK-LABEL: @test27vec(
315 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32*> [[A:%.*]], zeroinitializer
316 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32*> [[B:%.*]], zeroinitializer
317 ; CHECK-NEXT: [[E:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]]
318 ; CHECK-NEXT: ret <2 x i1> [[E]]
320 %C1 = ptrtoint <2 x i32*> %A to <2 x i32>
321 %C2 = ptrtoint <2 x i32*> %B to <2 x i32>
322 %D = or <2 x i32> %C1, %C2
323 %E = icmp eq <2 x i32> %D, zeroinitializer
328 define i1 @test28(i32 %A, i32 %B) {
329 ; CHECK-LABEL: @test28(
330 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
331 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
332 ; CHECK-NEXT: ret i1 [[TMP2]]
334 %C1 = icmp ne i32 %A, 0
335 %C2 = icmp ne i32 %B, 0
336 ; (A != 0) | (A != 0) --> (A|B) != 0
341 define i1 @test28_logical(i32 %A, i32 %B) {
342 ; CHECK-LABEL: @test28_logical(
343 ; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[A:%.*]], 0
344 ; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 [[B:%.*]], 0
345 ; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
346 ; CHECK-NEXT: ret i1 [[D]]
348 %C1 = icmp ne i32 %A, 0
349 %C2 = icmp ne i32 %B, 0
350 ; (A != 0) | (A != 0) --> (A|B) != 0
351 %D = select i1 %C1, i1 true, i1 %C2
355 define i1 @test29(i32* %A, i32* %B) {
356 ; CHECK-LABEL: @test29(
357 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32* [[A:%.*]], null
358 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32* [[B:%.*]], null
359 ; CHECK-NEXT: [[E:%.*]] = or i1 [[TMP1]], [[TMP2]]
360 ; CHECK-NEXT: ret i1 [[E]]
362 %C1 = ptrtoint i32* %A to i32
363 %C2 = ptrtoint i32* %B to i32
365 %E = icmp ne i32 %D, 0
369 define <2 x i1> @test29vec(<2 x i32*> %A, <2 x i32*> %B) {
370 ; CHECK-LABEL: @test29vec(
371 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32*> [[A:%.*]], zeroinitializer
372 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32*> [[B:%.*]], zeroinitializer
373 ; CHECK-NEXT: [[E:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
374 ; CHECK-NEXT: ret <2 x i1> [[E]]
376 %C1 = ptrtoint <2 x i32*> %A to <2 x i32>
377 %C2 = ptrtoint <2 x i32*> %B to <2 x i32>
378 %D = or <2 x i32> %C1, %C2
379 %E = icmp ne <2 x i32> %D, zeroinitializer
384 define i32 @test30(i32 %A) {
385 ; CHECK-LABEL: @test30(
386 ; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], -58312
387 ; CHECK-NEXT: [[E:%.*]] = or i32 [[D]], 32962
388 ; CHECK-NEXT: ret i32 [[E]]
390 %B = or i32 %A, 32962 ; 0b1000_0000_1100_0010
391 %C = and i32 %A, -65536 ; 0xffff0000
392 %D = and i32 %B, 40186 ; 0b1001_1100_1111_1010
397 define <2 x i32> @test30vec(<2 x i32> %A) {
398 ; CHECK-LABEL: @test30vec(
399 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], <i32 -58312, i32 -58312>
400 ; CHECK-NEXT: [[E:%.*]] = or <2 x i32> [[TMP1]], <i32 32962, i32 32962>
401 ; CHECK-NEXT: ret <2 x i32> [[E]]
403 %B = or <2 x i32> %A, <i32 32962, i32 32962>
404 %C = and <2 x i32> %A, <i32 -65536, i32 -65536>
405 %D = and <2 x i32> %B, <i32 40186, i32 40186>
406 %E = or <2 x i32> %D, %C
411 define i64 @test31(i64 %A) {
412 ; CHECK-LABEL: @test31(
413 ; CHECK-NEXT: [[E:%.*]] = and i64 [[A:%.*]], 4294908984
414 ; CHECK-NEXT: [[F:%.*]] = or i64 [[E]], 32962
415 ; CHECK-NEXT: ret i64 [[F]]
420 %C = or i64 %A, 32768
421 %E = and i64 %C, 4294941696
427 define <2 x i64> @test31vec(<2 x i64> %A) {
428 ; CHECK-LABEL: @test31vec(
429 ; CHECK-NEXT: [[E:%.*]] = and <2 x i64> [[A:%.*]], <i64 4294908984, i64 4294908984>
430 ; CHECK-NEXT: [[F:%.*]] = or <2 x i64> [[E]], <i64 32962, i64 32962>
431 ; CHECK-NEXT: ret <2 x i64> [[F]]
433 %B = or <2 x i64> %A, <i64 194, i64 194>
434 %D = and <2 x i64> %B, <i64 250, i64 250>
436 %C = or <2 x i64> %A, <i64 32768, i64 32768>
437 %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696>
439 %F = or <2 x i64> %D, %E
443 ; codegen is mature enough to handle vector selects.
444 define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) {
445 ; CHECK-LABEL: @test32(
446 ; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[AND_I1352:%.*]], <4 x i32> [[VECINIT6_I176:%.*]], <4 x i32> [[VECINIT6_I191:%.*]]
447 ; CHECK-NEXT: ret <4 x i32> [[TMP1]]
449 %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32>
450 %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135
451 %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1>
452 %and.i = and <4 x i32> %vecinit6.i191, %neg.i
453 %or.i = or <4 x i32> %and.i, %and.i129
457 define i1 @test33(i1 %X, i1 %Y) {
458 ; CHECK-LABEL: @test33(
459 ; CHECK-NEXT: [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
460 ; CHECK-NEXT: ret i1 [[A]]
467 define i1 @test33_logical(i1 %X, i1 %Y) {
468 ; CHECK-LABEL: @test33_logical(
469 ; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]
470 ; CHECK-NEXT: ret i1 [[A]]
472 %a = select i1 %X, i1 true, i1 %Y
473 %b = select i1 %a, i1 true, i1 %X
477 define i32 @test34(i32 %X, i32 %Y) {
478 ; CHECK-LABEL: @test34(
479 ; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
480 ; CHECK-NEXT: ret i32 [[A]]
487 define i32 @test35(i32 %a, i32 %b) {
488 ; CHECK-LABEL: @test35(
489 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
490 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 1135
491 ; CHECK-NEXT: ret i32 [[TMP2]]
498 define i1 @test36(i32 %x) {
499 ; CHECK-LABEL: @test36(
500 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23
501 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
502 ; CHECK-NEXT: ret i1 [[TMP2]]
504 %cmp1 = icmp eq i32 %x, 23
505 %cmp2 = icmp eq i32 %x, 24
506 %ret1 = or i1 %cmp1, %cmp2
507 %cmp3 = icmp eq i32 %x, 25
508 %ret2 = or i1 %ret1, %cmp3
512 define i1 @test36_logical(i32 %x) {
513 ; CHECK-LABEL: @test36_logical(
514 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23
515 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
516 ; CHECK-NEXT: ret i1 [[TMP2]]
518 %cmp1 = icmp eq i32 %x, 23
519 %cmp2 = icmp eq i32 %x, 24
520 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
521 %cmp3 = icmp eq i32 %x, 25
522 %ret2 = select i1 %ret1, i1 true, i1 %cmp3
526 define i1 @test37(i32 %x) {
527 ; CHECK-LABEL: @test37(
528 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
529 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
530 ; CHECK-NEXT: ret i1 [[TMP2]]
532 %add1 = add i32 %x, 7
533 %cmp1 = icmp ult i32 %add1, 30
534 %cmp2 = icmp eq i32 %x, 23
535 %ret1 = or i1 %cmp1, %cmp2
539 define i1 @test37_logical(i32 %x) {
540 ; CHECK-LABEL: @test37_logical(
541 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
542 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
543 ; CHECK-NEXT: ret i1 [[TMP2]]
545 %add1 = add i32 %x, 7
546 %cmp1 = icmp ult i32 %add1, 30
547 %cmp2 = icmp eq i32 %x, 23
548 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
552 define <2 x i1> @test37_uniform(<2 x i32> %x) {
553 ; CHECK-LABEL: @test37_uniform(
554 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 7>
555 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 31, i32 31>
556 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
558 %add1 = add <2 x i32> %x, <i32 7, i32 7>
559 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 30>
560 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 23>
561 %ret1 = or <2 x i1> %cmp1, %cmp2
565 define <2 x i1> @test37_undef(<2 x i32> %x) {
566 ; CHECK-LABEL: @test37_undef(
567 ; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 undef>
568 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 undef>
569 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 undef>
570 ; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
571 ; CHECK-NEXT: ret <2 x i1> [[RET1]]
573 %add1 = add <2 x i32> %x, <i32 7, i32 undef>
574 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 undef>
575 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 undef>
576 %ret1 = or <2 x i1> %cmp1, %cmp2
580 define i1 @test38(i32 %x) {
581 ; CHECK-LABEL: @test38(
582 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
583 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
584 ; CHECK-NEXT: ret i1 [[TMP2]]
586 %add1 = add i32 %x, 7
587 %cmp1 = icmp eq i32 %x, 23
588 %cmp2 = icmp ult i32 %add1, 30
589 %ret1 = or i1 %cmp1, %cmp2
593 define i1 @test38_logical(i32 %x) {
594 ; CHECK-LABEL: @test38_logical(
595 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
596 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
597 ; CHECK-NEXT: ret i1 [[TMP2]]
599 %add1 = add i32 %x, 7
600 %cmp1 = icmp eq i32 %x, 23
601 %cmp2 = icmp ult i32 %add1, 30
602 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
606 define <2 x i1> @test38_nonuniform(<2 x i32> %x) {
607 ; CHECK-LABEL: @test38_nonuniform(
608 ; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 24>
609 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 8>
610 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 32>
611 ; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
612 ; CHECK-NEXT: ret <2 x i1> [[RET1]]
614 %add1 = add <2 x i32> %x, <i32 7, i32 24>
615 %cmp1 = icmp eq <2 x i32> %x, <i32 23, i32 8>
616 %cmp2 = icmp ult <2 x i32> %add1, <i32 30, i32 32>
617 %ret1 = or <2 x i1> %cmp1, %cmp2
621 ; (~A & B) | A --> A | B
623 define i32 @test39a(i32 %a, float %b) {
624 ; CHECK-LABEL: @test39a(
625 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
626 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
627 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
628 ; CHECK-NEXT: ret i32 [[OR]]
630 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
631 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
632 %nota = xor i32 %a1, -1
633 %and = and i32 %nota, %b1
634 %or = or i32 %and, %a1
638 ; Commute 'and' operands:
639 ; (B & ~A) | A --> A | B
641 define i32 @test39b(i32 %a, float %b) {
642 ; CHECK-LABEL: @test39b(
643 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
644 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
645 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
646 ; CHECK-NEXT: ret i32 [[OR]]
648 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
649 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
650 %nota = xor i32 %a1, -1
651 %and = and i32 %b1, %nota
652 %or = or i32 %and, %a1
656 ; Commute 'or' operands:
657 ; A | (~A & B) --> A | B
659 define i32 @test39c(i32 %a, float %b) {
660 ; CHECK-LABEL: @test39c(
661 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
662 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
663 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
664 ; CHECK-NEXT: ret i32 [[OR]]
666 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
667 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
668 %nota = xor i32 %a1, -1
669 %and = and i32 %nota, %b1
670 %or = or i32 %a1, %and
674 ; Commute 'and' operands:
675 ; A | (B & ~A) --> A | B
677 define i32 @test39d(i32 %a, float %b) {
678 ; CHECK-LABEL: @test39d(
679 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
680 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
681 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
682 ; CHECK-NEXT: ret i32 [[OR]]
684 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
685 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
686 %nota = xor i32 %a1, -1
687 %and = and i32 %b1, %nota
688 %or = or i32 %a1, %and
692 define i32 @test40(i32 %a, i32 %b) {
693 ; CHECK-LABEL: @test40(
694 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
695 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
696 ; CHECK-NEXT: ret i32 [[OR]]
698 %and = and i32 %a, %b
699 %xor = xor i32 %a, -1
700 %or = or i32 %and, %xor
704 define i32 @test40b(i32 %a, i32 %b) {
705 ; CHECK-LABEL: @test40b(
706 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
707 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
708 ; CHECK-NEXT: ret i32 [[OR]]
710 %and = and i32 %b, %a
711 %xor = xor i32 %a, -1
712 %or = or i32 %and, %xor
716 define i32 @test40c(i32 %a, i32 %b) {
717 ; CHECK-LABEL: @test40c(
718 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
719 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
720 ; CHECK-NEXT: ret i32 [[OR]]
722 %and = and i32 %b, %a
723 %xor = xor i32 %a, -1
724 %or = or i32 %xor, %and
728 define i32 @test40d(i32 %a, i32 %b) {
729 ; CHECK-LABEL: @test40d(
730 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
731 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
732 ; CHECK-NEXT: ret i32 [[OR]]
734 %and = and i32 %a, %b
735 %xor = xor i32 %a, -1
736 %or = or i32 %xor, %and
740 define i32 @test45(i32 %x, i32 %y, i32 %z) {
741 ; CHECK-LABEL: @test45(
742 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
743 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]]
744 ; CHECK-NEXT: ret i32 [[OR1]]
747 %and = and i32 %x, %or
748 %or1 = or i32 %and, %y
752 define i1 @test46(i8 signext %c) {
753 ; CHECK-LABEL: @test46(
754 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
755 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
756 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
757 ; CHECK-NEXT: ret i1 [[TMP3]]
759 %c.off = add i8 %c, -97
760 %cmp1 = icmp ult i8 %c.off, 26
761 %c.off17 = add i8 %c, -65
762 %cmp2 = icmp ult i8 %c.off17, 26
763 %or = or i1 %cmp1, %cmp2
767 define i1 @test46_logical(i8 signext %c) {
768 ; CHECK-LABEL: @test46_logical(
769 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
770 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
771 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
772 ; CHECK-NEXT: ret i1 [[TMP3]]
774 %c.off = add i8 %c, -97
775 %cmp1 = icmp ult i8 %c.off, 26
776 %c.off17 = add i8 %c, -65
777 %cmp2 = icmp ult i8 %c.off17, 26
778 %or = select i1 %cmp1, i1 true, i1 %cmp2
782 define <2 x i1> @test46_uniform(<2 x i8> %c) {
783 ; CHECK-LABEL: @test46_uniform(
784 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[C:%.*]], <i8 -33, i8 -33>
785 ; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[TMP1]], <i8 -65, i8 -65>
786 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult <2 x i8> [[TMP2]], <i8 26, i8 26>
787 ; CHECK-NEXT: ret <2 x i1> [[TMP3]]
789 %c.off = add <2 x i8> %c, <i8 -97, i8 -97>
790 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 26>
791 %c.off17 = add <2 x i8> %c, <i8 -65, i8 -65>
792 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 26>
793 %or = or <2 x i1> %cmp1, %cmp2
797 define <2 x i1> @test46_undef(<2 x i8> %c) {
798 ; CHECK-LABEL: @test46_undef(
799 ; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 undef>
800 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 26, i8 undef>
801 ; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -65, i8 undef>
802 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 26, i8 undef>
803 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
804 ; CHECK-NEXT: ret <2 x i1> [[OR]]
806 %c.off = add <2 x i8> %c, <i8 -97, i8 undef>
807 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 undef>
808 %c.off17 = add <2 x i8> %c, <i8 -65, i8 undef>
809 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 undef>
810 %or = or <2 x i1> %cmp1, %cmp2
814 ; This is the variant of the above pattern where one of the ranges is
815 ; represented with an add.
816 define i1 @two_ranges_to_mask_and_range_degenerate(i16 %x) {
817 ; CHECK-LABEL: @two_ranges_to_mask_and_range_degenerate(
818 ; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], -20
819 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i16 [[TMP1]], 12
820 ; CHECK-NEXT: ret i1 [[TMP2]]
822 %cmp1 = icmp ult i16 %x, 12
823 %cmp2 = icmp uge i16 %x, 16
824 %cmp3 = icmp ult i16 %x, 28
825 %and = and i1 %cmp2, %cmp3
826 %or = or i1 %cmp1, %and
830 define i1 @test47(i8 signext %c) {
831 ; CHECK-LABEL: @test47(
832 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
833 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
834 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
835 ; CHECK-NEXT: ret i1 [[TMP3]]
837 %c.off = add i8 %c, -65
838 %cmp1 = icmp ule i8 %c.off, 26
839 %c.off17 = add i8 %c, -97
840 %cmp2 = icmp ule i8 %c.off17, 26
841 %or = or i1 %cmp1, %cmp2
845 define i1 @test47_logical(i8 signext %c) {
846 ; CHECK-LABEL: @test47_logical(
847 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
848 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
849 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
850 ; CHECK-NEXT: ret i1 [[TMP3]]
852 %c.off = add i8 %c, -65
853 %cmp1 = icmp ule i8 %c.off, 26
854 %c.off17 = add i8 %c, -97
855 %cmp2 = icmp ule i8 %c.off17, 26
856 %or = select i1 %cmp1, i1 true, i1 %cmp2
860 define <2 x i1> @test47_nonuniform(<2 x i8> %c) {
861 ; CHECK-LABEL: @test47_nonuniform(
862 ; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -65, i8 -97>
863 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 27, i8 27>
864 ; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -97, i8 -65>
865 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 27, i8 27>
866 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
867 ; CHECK-NEXT: ret <2 x i1> [[OR]]
869 %c.off = add <2 x i8> %c, <i8 -65, i8 -97>
870 %cmp1 = icmp ule <2 x i8> %c.off, <i8 26, i8 26>
871 %c.off17 = add <2 x i8> %c, <i8 -97, i8 -65>
872 %cmp2 = icmp ule <2 x i8> %c.off17, <i8 26, i8 26>
873 %or = or <2 x i1> %cmp1, %cmp2
877 define i32 @test49(i1 %C) {
878 ; CHECK-LABEL: @test49(
879 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1019, i32 123
880 ; CHECK-NEXT: ret i32 [[V]]
882 %A = select i1 %C, i32 1000, i32 10
887 define <2 x i32> @test49vec(i1 %C) {
888 ; CHECK-LABEL: @test49vec(
889 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 1019>, <2 x i32> <i32 123, i32 123>
890 ; CHECK-NEXT: ret <2 x i32> [[V]]
892 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
893 %V = or <2 x i32> %A, <i32 123, i32 123>
897 define <2 x i32> @test49vec2(i1 %C) {
898 ; CHECK-LABEL: @test49vec2(
899 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 2509>, <2 x i32> <i32 123, i32 351>
900 ; CHECK-NEXT: ret <2 x i32> [[V]]
902 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
903 %V = or <2 x i32> %A, <i32 123, i32 333>
907 define i32 @test50(i1 %which) {
908 ; CHECK-LABEL: @test50(
910 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
912 ; CHECK-NEXT: br label [[FINAL]]
914 ; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1019, [[ENTRY:%.*]] ], [ 123, [[DELAY]] ]
915 ; CHECK-NEXT: ret i32 [[A]]
918 br i1 %which, label %final, label %delay
924 %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
925 %value = or i32 %A, 123
929 define <2 x i32> @test50vec(i1 %which) {
930 ; CHECK-LABEL: @test50vec(
932 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
934 ; CHECK-NEXT: br label [[FINAL]]
936 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 1019>, [[ENTRY:%.*]] ], [ <i32 123, i32 123>, [[DELAY]] ]
937 ; CHECK-NEXT: ret <2 x i32> [[A]]
940 br i1 %which, label %final, label %delay
946 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
947 %value = or <2 x i32> %A, <i32 123, i32 123>
951 define <2 x i32> @test50vec2(i1 %which) {
952 ; CHECK-LABEL: @test50vec2(
954 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
956 ; CHECK-NEXT: br label [[FINAL]]
958 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 2509>, [[ENTRY:%.*]] ], [ <i32 123, i32 351>, [[DELAY]] ]
959 ; CHECK-NEXT: ret <2 x i32> [[A]]
962 br i1 %which, label %final, label %delay
968 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
969 %value = or <2 x i32> %A, <i32 123, i32 333>
973 ; In the next 4 tests, vary the types and predicates for extra coverage.
974 ; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp
976 define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) {
977 ; CHECK-LABEL: @or_andn_cmp_1(
978 ; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
979 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
980 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]
981 ; CHECK-NEXT: ret i1 [[OR]]
983 %x = icmp sgt i32 %a, %b
984 %x_inv = icmp sle i32 %a, %b
985 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
986 %and = and i1 %y, %x_inv
991 define i1 @or_andn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {
992 ; CHECK-LABEL: @or_andn_cmp_1_logical(
993 ; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
994 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
995 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
996 ; CHECK-NEXT: ret i1 [[OR]]
998 %x = icmp sgt i32 %a, %b
999 %x_inv = icmp sle i32 %a, %b
1000 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1001 %and = select i1 %y, i1 %x_inv, i1 false
1002 %or = select i1 %x, i1 true, i1 %and
1007 ; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp
1009 define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
1010 ; CHECK-LABEL: @or_andn_cmp_2(
1011 ; CHECK-NEXT: [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
1012 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
1013 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[Y]], [[X]]
1014 ; CHECK-NEXT: ret <2 x i1> [[OR]]
1016 %x = icmp sge <2 x i32> %a, %b
1017 %x_inv = icmp slt <2 x i32> %a, %b
1018 %y = icmp ugt <2 x i32> %c, <i32 42, i32 47> ; thwart complexity-based ordering
1019 %and = and <2 x i1> %y, %x_inv
1020 %or = or <2 x i1> %and, %x
1024 ; Commute the 'and':
1025 ; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp
1027 define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) {
1028 ; CHECK-LABEL: @or_andn_cmp_3(
1029 ; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1030 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1031 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]
1032 ; CHECK-NEXT: ret i1 [[OR]]
1034 %x = icmp ugt i72 %a, %b
1035 %x_inv = icmp ule i72 %a, %b
1036 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering
1037 %and = and i1 %x_inv, %y
1038 %or = or i1 %x, %and
1042 define i1 @or_andn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {
1043 ; CHECK-LABEL: @or_andn_cmp_3_logical(
1044 ; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1045 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1046 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
1047 ; CHECK-NEXT: ret i1 [[OR]]
1049 %x = icmp ugt i72 %a, %b
1050 %x_inv = icmp ule i72 %a, %b
1051 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering
1052 %and = select i1 %x_inv, i1 %y, i1 false
1053 %or = select i1 %x, i1 true, i1 %and
1058 ; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp
1060 define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
1061 ; CHECK-LABEL: @or_andn_cmp_4(
1062 ; CHECK-NEXT: [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
1063 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
1064 ; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[Y]], [[X]]
1065 ; CHECK-NEXT: ret <3 x i1> [[OR]]
1067 %x = icmp eq <3 x i32> %a, %b
1068 %x_inv = icmp ne <3 x i32> %a, %b
1069 %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1> ; thwart complexity-based ordering
1070 %and = and <3 x i1> %x_inv, %y
1071 %or = or <3 x i1> %and, %x
1075 ; In the next 4 tests, vary the types and predicates for extra coverage.
1076 ; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp
1078 define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) {
1079 ; CHECK-LABEL: @orn_and_cmp_1(
1080 ; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1081 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1082 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_INV]], [[Y]]
1083 ; CHECK-NEXT: ret i1 [[OR]]
1085 %x = icmp sgt i37 %a, %b
1086 %x_inv = icmp sle i37 %a, %b
1087 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering
1088 %and = and i1 %y, %x
1089 %or = or i1 %x_inv, %and
1093 define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i37 %c) {
1094 ; CHECK-LABEL: @orn_and_cmp_1_logical(
1095 ; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1096 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1097 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1098 ; CHECK-NEXT: ret i1 [[OR]]
1100 %x = icmp sgt i37 %a, %b
1101 %x_inv = icmp sle i37 %a, %b
1102 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering
1103 %and = select i1 %y, i1 %x, i1 false
1104 %or = select i1 %x_inv, i1 true, i1 %and
1109 ; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1111 define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) {
1112 ; CHECK-LABEL: @orn_and_cmp_2(
1113 ; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1114 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1115 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1116 ; CHECK-NEXT: ret i1 [[OR]]
1118 %x = icmp sge i16 %a, %b
1119 %x_inv = icmp slt i16 %a, %b
1120 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering
1121 %and = and i1 %y, %x
1122 %or = or i1 %and, %x_inv
1126 define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i16 %c) {
1127 ; CHECK-LABEL: @orn_and_cmp_2_logical(
1128 ; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1129 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1130 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y]], i1 true, i1 [[X_INV]]
1131 ; CHECK-NEXT: ret i1 [[OR]]
1133 %x = icmp sge i16 %a, %b
1134 %x_inv = icmp slt i16 %a, %b
1135 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering
1136 %and = select i1 %y, i1 %x, i1 false
1137 %or = select i1 %and, i1 true, i1 %x_inv
1141 ; Commute the 'and':
1142 ; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp
1144 define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
1145 ; CHECK-LABEL: @orn_and_cmp_3(
1146 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
1147 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
1148 ; CHECK-NEXT: [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]]
1149 ; CHECK-NEXT: ret <4 x i1> [[OR]]
1151 %x = icmp ugt <4 x i32> %a, %b
1152 %x_inv = icmp ule <4 x i32> %a, %b
1153 %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1> ; thwart complexity-based ordering
1154 %and = and <4 x i1> %x, %y
1155 %or = or <4 x i1> %x_inv, %and
1160 ; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1162 define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) {
1163 ; CHECK-LABEL: @orn_and_cmp_4(
1164 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1165 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1166 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1167 ; CHECK-NEXT: ret i1 [[OR]]
1169 %x = icmp eq i32 %a, %b
1170 %x_inv = icmp ne i32 %a, %b
1171 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1172 %and = and i1 %x, %y
1173 %or = or i1 %and, %x_inv
1177 define i1 @orn_and_cmp_4_logical(i32 %a, i32 %b, i32 %c) {
1178 ; CHECK-LABEL: @orn_and_cmp_4_logical(
1179 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1180 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1181 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1182 ; CHECK-NEXT: ret i1 [[OR]]
1184 %x = icmp eq i32 %a, %b
1185 %x_inv = icmp ne i32 %a, %b
1186 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1187 %and = select i1 %x, i1 %y, i1 false
1188 %or = select i1 %and, i1 true, i1 %x_inv
1192 ; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1.
1193 define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {
1194 ; CHECK-LABEL: @test51(
1195 ; CHECK-NEXT: [[TMP1:%.*]] = 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>
1196 ; CHECK-NEXT: ret <16 x i1> [[TMP1]]
1198 %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>
1199 %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>
1200 %tmp3 = or <16 x i1> %tmp, %tmp2
1204 ; This would infinite loop because it reaches a transform
1205 ; that was not expecting a constant-foldable value.
1207 define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) {
1208 ; CHECK-LABEL: @PR46712(
1209 ; CHECK-NEXT: entry:
1210 ; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1212 ; CHECK-NEXT: [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
1213 ; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
1214 ; CHECK-NEXT: br label [[END]]
1216 ; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
1217 ; CHECK-NEXT: ret i32 [[T5]]
1221 %conv = sext i1 %t2 to i32
1222 %cmp = icmp sge i32 %conv, 1
1223 %conv2 = zext i1 %cmp to i64
1224 br i1 %b, label %true, label %end
1227 %bool4 = icmp eq i64 %conv2, 0
1228 %bool5 = icmp ne i64 %z, 0
1229 %and = and i1 %bool4, %bool5
1230 %sel = select i1 %and, i1 false, i1 true
1234 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1235 %conv8 = zext i1 %t5 to i32
1239 define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) {
1240 ; CHECK-LABEL: @PR46712_logical(
1241 ; CHECK-NEXT: entry:
1242 ; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1244 ; CHECK-NEXT: [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
1245 ; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
1246 ; CHECK-NEXT: br label [[END]]
1248 ; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
1249 ; CHECK-NEXT: ret i32 [[T5]]
1252 %t2 = select i1 %x, i1 true, i1 %y
1253 %conv = sext i1 %t2 to i32
1254 %cmp = icmp sge i32 %conv, 1
1255 %conv2 = zext i1 %cmp to i64
1256 br i1 %b, label %true, label %end
1259 %bool4 = icmp eq i64 %conv2, 0
1260 %bool5 = icmp ne i64 %z, 0
1261 %and = select i1 %bool4, i1 %bool5, i1 false
1262 %sel = select i1 %and, i1 false, i1 true
1266 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1267 %conv8 = zext i1 %t5 to i32
1271 ; (~x & y) | ~(x | y) --> ~x
1272 define i32 @PR38929(i32 %0, i32 %1) {
1273 ; CHECK-LABEL: @PR38929(
1274 ; CHECK-NEXT: [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], -1
1275 ; CHECK-NEXT: ret i32 [[TMP3]]
1285 define i32 @test1(i32 %x, i32 %y) {
1286 ; CHECK-LABEL: @test1(
1287 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1288 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1289 ; CHECK-NEXT: ret i32 [[OR1]]
1291 %xor = xor i32 %y, %x
1293 %neg = xor i32 %or, -1
1294 %or1 = or i32 %xor, %neg
1298 define i32 @test2(i32 %x, i32 %y) {
1299 ; CHECK-LABEL: @test2(
1300 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1301 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1302 ; CHECK-NEXT: ret i32 [[OR1]]
1305 %neg = xor i32 %or, -1
1306 %xor = xor i32 %y, %x
1307 %or1 = or i32 %xor, %neg
1311 define i32 @test3(i32 %x, i32 %y) {
1312 ; CHECK-LABEL: @test3(
1313 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
1314 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1315 ; CHECK-NEXT: ret i32 [[OR1]]
1318 %neg = xor i32 %or, -1
1319 %xor = xor i32 %x, %y
1320 %or1 = or i32 %xor, %neg
1324 define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) {
1325 ; CHECK-LABEL: @test4_vec(
1326 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]]
1327 ; CHECK-NEXT: [[OR1:%.*]] = xor <2 x i32> [[TMP1]], <i32 -1, i32 -1>
1328 ; CHECK-NEXT: ret <2 x i32> [[OR1]]
1330 %or = or <2 x i32> %y, %x
1331 %neg = xor <2 x i32> %or, <i32 -1, i32 -1>
1332 %xor = xor <2 x i32> %y, %x
1333 %or1 = or <2 x i32> %xor, %neg
1337 define i32 @test5_use(i32 %x, i32 %y) {
1338 ; CHECK-LABEL: @test5_use(
1339 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1340 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -1
1341 ; CHECK-NEXT: call void @use(i32 [[NEG]])
1342 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1343 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1344 ; CHECK-NEXT: ret i32 [[OR1]]
1347 %neg = xor i32 %or, -1
1348 %xor = xor i32 %y, %x
1349 call void @use(i32 %neg)
1350 %or1 = or i32 %xor, %neg
1354 define i32 @test5_use2(i32 %x, i32 %y) {
1355 ; CHECK-LABEL: @test5_use2(
1356 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1357 ; CHECK-NEXT: call void @use(i32 [[XOR]])
1358 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1359 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1360 ; CHECK-NEXT: ret i32 [[OR1]]
1363 %neg = xor i32 %or, -1
1364 %xor = xor i32 %y, %x
1365 call void @use(i32 %xor)
1366 %or1 = or i32 %xor, %neg
1369 define i32 @test5_use3(i32 %x, i32 %y) {
1370 ; CHECK-LABEL: @test5_use3(
1371 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1372 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -1
1373 ; CHECK-NEXT: call void @use(i32 [[NEG]])
1374 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]]
1375 ; CHECK-NEXT: call void @use(i32 [[XOR]])
1376 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
1377 ; CHECK-NEXT: ret i32 [[OR1]]
1380 %neg = xor i32 %or, -1
1381 call void @use(i32 %neg)
1382 %xor = xor i32 %y, %x
1383 call void @use(i32 %xor)
1384 %or1 = or i32 %xor, %neg
1388 define i8 @ashr_bitwidth_mask(i8 %x, i8 %y) {
1389 ; CHECK-LABEL: @ashr_bitwidth_mask(
1390 ; CHECK-NEXT: [[SIGN:%.*]] = ashr i8 [[X:%.*]], 7
1391 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1392 ; CHECK-NEXT: ret i8 [[R]]
1394 %sign = ashr i8 %x, 7
1395 %r = or i8 %sign, %y
1399 define <2 x i8> @ashr_bitwidth_mask_vec_commute(<2 x i8> %x, <2 x i8> %py) {
1400 ; CHECK-LABEL: @ashr_bitwidth_mask_vec_commute(
1401 ; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], <i8 42, i8 2>
1402 ; CHECK-NEXT: [[SIGN:%.*]] = ashr <2 x i8> [[X:%.*]], <i8 7, i8 7>
1403 ; CHECK-NEXT: [[R:%.*]] = or <2 x i8> [[Y]], [[SIGN]]
1404 ; CHECK-NEXT: ret <2 x i8> [[R]]
1406 %y = mul <2 x i8> %py, <i8 42, i8 2> ; thwart complexity-based ordering
1407 %sign = ashr <2 x i8> %x, <i8 7, i8 7>
1408 %r = or <2 x i8> %y, %sign
1412 define i32 @ashr_bitwidth_mask_use(i32 %x, i32 %y) {
1413 ; CHECK-LABEL: @ashr_bitwidth_mask_use(
1414 ; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X:%.*]], 7
1415 ; CHECK-NEXT: call void @use(i32 [[SIGN]])
1416 ; CHECK-NEXT: [[R:%.*]] = or i32 [[SIGN]], [[Y:%.*]]
1417 ; CHECK-NEXT: ret i32 [[R]]
1419 %sign = ashr i32 %x, 7
1420 call void @use(i32 %sign)
1421 %r = or i32 %sign, %y
1425 define i8 @ashr_not_bitwidth_mask(i8 %x, i8 %y) {
1426 ; CHECK-LABEL: @ashr_not_bitwidth_mask(
1427 ; CHECK-NEXT: [[SIGN:%.*]] = ashr i8 [[X:%.*]], 6
1428 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1429 ; CHECK-NEXT: ret i8 [[R]]
1431 %sign = ashr i8 %x, 6
1432 %r = or i8 %sign, %y
1436 define i8 @lshr_bitwidth_mask(i8 %x, i8 %y) {
1437 ; CHECK-LABEL: @lshr_bitwidth_mask(
1438 ; CHECK-NEXT: [[SIGN:%.*]] = lshr i8 [[X:%.*]], 7
1439 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1440 ; CHECK-NEXT: ret i8 [[R]]
1442 %sign = lshr i8 %x, 7
1443 %r = or i8 %sign, %y
1447 define i1 @cmp_overlap(i32 %x) {
1448 ; CHECK-LABEL: @cmp_overlap(
1449 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 1
1450 ; CHECK-NEXT: ret i1 [[TMP1]]
1452 %isneg = icmp slt i32 %x, 0
1453 %negx = sub i32 0, %x
1454 %isnotneg = icmp sgt i32 %negx, -1
1455 %r = or i1 %isneg, %isnotneg
1459 define <2 x i1> @cmp_overlap_splat(<2 x i5> %x) {
1460 ; CHECK-LABEL: @cmp_overlap_splat(
1461 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i5> [[X:%.*]], <i5 1, i5 1>
1462 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
1464 %isneg = icmp slt <2 x i5> %x, zeroinitializer
1465 %negx = sub <2 x i5> zeroinitializer, %x
1466 %isnotneg = icmp sgt <2 x i5> %negx, <i5 -1, i5 -1>
1467 %r = or <2 x i1> %isneg, %isnotneg
1471 define i32 @mul_no_common_bits(i32 %p1, i32 %p2) {
1472 ; CHECK-LABEL: @mul_no_common_bits(
1473 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 7
1474 ; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1475 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[Y]], 1
1476 ; CHECK-NEXT: [[R:%.*]] = mul i32 [[X]], [[TMP1]]
1477 ; CHECK-NEXT: ret i32 [[R]]
1486 define i32 @mul_no_common_bits_const_op(i32 %p) {
1487 ; CHECK-LABEL: @mul_no_common_bits_const_op(
1488 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7
1489 ; CHECK-NEXT: [[R:%.*]] = mul nuw nsw i32 [[X]], 25
1490 ; CHECK-NEXT: ret i32 [[R]]
1498 define <2 x i12> @mul_no_common_bits_commute(<2 x i12> %p) {
1499 ; CHECK-LABEL: @mul_no_common_bits_commute(
1500 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i12> [[P:%.*]] to <2 x i1>
1501 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP1]], <2 x i12> <i12 15, i12 17>, <2 x i12> zeroinitializer
1502 ; CHECK-NEXT: ret <2 x i12> [[R]]
1504 %x = and <2 x i12> %p, <i12 1, i12 1>
1505 %m = mul <2 x i12> %x, <i12 14, i12 16>
1506 %r = or <2 x i12> %x, %m
1510 ; negative test - extra use requires extra instructions
1512 define i32 @mul_no_common_bits_uses(i32 %p1, i32 %p2) {
1513 ; CHECK-LABEL: @mul_no_common_bits_uses(
1514 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 7
1515 ; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1516 ; CHECK-NEXT: [[M:%.*]] = mul i32 [[X]], [[Y]]
1517 ; CHECK-NEXT: call void @use(i32 [[M]])
1518 ; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[X]]
1519 ; CHECK-NEXT: ret i32 [[R]]
1524 call void @use(i32 %m)
1529 ; negative test - probably not good to create an extra mul
1531 define i32 @mul_no_common_bits_const_op_uses(i32 %p) {
1532 ; CHECK-LABEL: @mul_no_common_bits_const_op_uses(
1533 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7
1534 ; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X]], 24
1535 ; CHECK-NEXT: call void @use(i32 [[M]])
1536 ; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[X]]
1537 ; CHECK-NEXT: ret i32 [[R]]
1541 call void @use(i32 %m)
1546 ; negative test - %x and %m may have set 3rd bit
1548 define i32 @mul_common_bits(i32 %p) {
1549 ; CHECK-LABEL: @mul_common_bits(
1550 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7
1551 ; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X]], 12
1552 ; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[X]]
1553 ; CHECK-NEXT: ret i32 [[R]]