1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -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_logical(i32 %A, i32 %B) {
41 ; CHECK-LABEL: @test14_logical(
42 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
43 ; CHECK-NEXT: ret i1 [[TMP1]]
45 %C1 = icmp ult i32 %A, %B
46 %C2 = icmp ugt i32 %A, %B
47 ; (A < B) | (A > B) === A != B
48 %D = select i1 %C1, i1 true, i1 %C2
52 define i1 @test15(i32 %A, i32 %B) {
53 ; CHECK-LABEL: @test15(
54 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
55 ; CHECK-NEXT: ret i1 [[TMP1]]
57 %C1 = icmp ult i32 %A, %B
58 %C2 = icmp eq i32 %A, %B
59 ; (A < B) | (A == B) === A <= B
64 define i1 @test15_logical(i32 %A, i32 %B) {
65 ; CHECK-LABEL: @test15_logical(
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
72 %D = select i1 %C1, i1 true, i1 %C2
76 define i32 @test16(i32 %A) {
77 ; CHECK-LABEL: @test16(
78 ; CHECK-NEXT: ret i32 [[A:%.*]]
83 ; %D = and int %B, -1 == %B
88 define i32 @test17(i32 %A) {
89 ; CHECK-LABEL: @test17(
90 ; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], 5
91 ; CHECK-NEXT: ret i32 [[D]]
100 define i1 @test18(i32 %A) {
101 ; CHECK-LABEL: @test18(
102 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100
103 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -50
104 ; CHECK-NEXT: ret i1 [[TMP2]]
106 %B = icmp sge i32 %A, 100
107 %C = icmp slt i32 %A, 50
112 define i1 @test18_logical(i32 %A) {
113 ; CHECK-LABEL: @test18_logical(
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
120 %D = select i1 %B, i1 true, i1 %C
124 define <2 x i1> @test18vec(<2 x i32> %A) {
125 ; CHECK-LABEL: @test18vec(
126 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], <i32 -100, i32 -100>
127 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 -50, i32 -50>
128 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
130 %B = icmp sge <2 x i32> %A, <i32 100, i32 100>
131 %C = icmp slt <2 x i32> %A, <i32 50, i32 50>
132 %D = or <2 x i1> %B, %C
136 define i32 @test20(i32 %x) {
137 ; CHECK-LABEL: @test20(
138 ; CHECK-NEXT: ret i32 [[X:%.*]]
145 define i32 @test21(i32 %t1) {
146 ; CHECK-LABEL: @test21(
147 ; CHECK-NEXT: [[T1_MASK1:%.*]] = add i32 [[T1:%.*]], 2
148 ; CHECK-NEXT: ret i32 [[T1_MASK1]]
150 %t1.mask1 = add i32 %t1, 2
151 %t3 = and i32 %t1.mask1, -2
154 %t6 = or i32 %t5, %t3
158 define i32 @test22(i32 %B) {
159 ; CHECK-LABEL: @test22(
160 ; CHECK-NEXT: ret i32 [[B:%.*]]
162 %ELIM41 = and i32 %B, 1
163 %ELIM7 = and i32 %B, -2
164 %ELIM5 = or i32 %ELIM41, %ELIM7
168 define i16 @test23(i16 %A) {
169 ; CHECK-LABEL: @test23(
170 ; CHECK-NEXT: [[B:%.*]] = lshr i16 [[A:%.*]], 1
171 ; CHECK-NEXT: [[D:%.*]] = xor i16 [[B]], -24575
172 ; CHECK-NEXT: ret i16 [[D]]
176 %C = or i16 %B, -32768
177 %D = xor i16 %C, 8193
181 define <2 x i16> @test23vec(<2 x i16> %A) {
182 ; CHECK-LABEL: @test23vec(
183 ; CHECK-NEXT: [[B:%.*]] = lshr <2 x i16> [[A:%.*]], <i16 1, i16 1>
184 ; CHECK-NEXT: [[D:%.*]] = xor <2 x i16> [[B]], <i16 -24575, i16 -24575>
185 ; CHECK-NEXT: ret <2 x i16> [[D]]
187 %B = lshr <2 x i16> %A, <i16 1, i16 1>
189 %C = or <2 x i16> %B, <i16 -32768, i16 -32768>
190 %D = xor <2 x i16> %C, <i16 8193, i16 8193>
195 define i1 @test25(i32 %A, i32 %B) {
196 ; CHECK-LABEL: @test25(
197 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
198 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
199 ; CHECK-NEXT: [[F:%.*]] = and i1 [[C]], [[D]]
200 ; CHECK-NEXT: ret i1 [[F]]
202 %C = icmp eq i32 %A, 0
203 %D = icmp eq i32 %B, 57
209 define i1 @test25_logical(i32 %A, i32 %B) {
210 ; CHECK-LABEL: @test25_logical(
211 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
212 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
213 ; CHECK-NEXT: [[E:%.*]] = select i1 [[C]], i1 [[D]], i1 false
214 ; CHECK-NEXT: ret i1 [[E]]
216 %C = icmp eq i32 %A, 0
217 %D = icmp eq i32 %B, 57
218 %E = select i1 %C, i1 true, i1 %D
224 define i1 @and_icmp_eq_0(i32 %A, i32 %B) {
225 ; CHECK-LABEL: @and_icmp_eq_0(
226 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
227 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
228 ; CHECK-NEXT: ret i1 [[TMP2]]
230 %C1 = icmp eq i32 %A, 0
231 %C2 = icmp eq i32 %B, 0
232 ; (A == 0) & (A == 0) --> (A|B) == 0
237 define <2 x i1> @and_icmp_eq_0_vector(<2 x i32> %A, <2 x i32> %B) {
238 ; CHECK-LABEL: @and_icmp_eq_0_vector(
239 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
240 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
241 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
243 %C1 = icmp eq <2 x i32> %A, zeroinitializer
244 %C2 = icmp eq <2 x i32> %B, zeroinitializer
245 %D = and <2 x i1> %C1, %C2
249 define <2 x i1> @and_icmp_eq_0_vector_undef1(<2 x i32> %A, <2 x i32> %B) {
250 ; CHECK-LABEL: @and_icmp_eq_0_vector_undef1(
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, <i32 0, i32 undef>
256 %C2 = icmp eq <2 x i32> %B, <i32 0, i32 undef>
257 %D = and <2 x i1> %C1, %C2
261 define <2 x i1> @and_icmp_eq_0_vector_undef2(<2 x i32> %A, <2 x i32> %B) {
262 ; CHECK-LABEL: @and_icmp_eq_0_vector_undef2(
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 undef, i32 0>
269 %D = and <2 x i1> %C1, %C2
273 define i1 @and_icmp_eq_0_logical(i32 %A, i32 %B) {
274 ; CHECK-LABEL: @and_icmp_eq_0_logical(
275 ; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[A:%.*]], 0
276 ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[B:%.*]], 0
277 ; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
278 ; CHECK-NEXT: ret i1 [[D]]
280 %C1 = icmp eq i32 %A, 0
281 %C2 = icmp eq i32 %B, 0
282 ; (A == 0) & (A == 0) --> (A|B) == 0
283 %D = select i1 %C1, i1 %C2, i1 false
287 define i1 @test27(i32* %A, i32* %B) {
288 ; CHECK-LABEL: @test27(
289 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32* [[A:%.*]], null
290 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32* [[B:%.*]], null
291 ; CHECK-NEXT: [[E:%.*]] = and i1 [[TMP1]], [[TMP2]]
292 ; CHECK-NEXT: ret i1 [[E]]
294 %C1 = ptrtoint i32* %A to i32
295 %C2 = ptrtoint i32* %B to i32
297 %E = icmp eq i32 %D, 0
301 define <2 x i1> @test27vec(<2 x i32*> %A, <2 x i32*> %B) {
302 ; CHECK-LABEL: @test27vec(
303 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32*> [[A:%.*]], zeroinitializer
304 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32*> [[B:%.*]], zeroinitializer
305 ; CHECK-NEXT: [[E:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]]
306 ; CHECK-NEXT: ret <2 x i1> [[E]]
308 %C1 = ptrtoint <2 x i32*> %A to <2 x i32>
309 %C2 = ptrtoint <2 x i32*> %B to <2 x i32>
310 %D = or <2 x i32> %C1, %C2
311 %E = icmp eq <2 x i32> %D, zeroinitializer
316 define i1 @test28(i32 %A, i32 %B) {
317 ; CHECK-LABEL: @test28(
318 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
319 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
320 ; CHECK-NEXT: ret i1 [[TMP2]]
322 %C1 = icmp ne i32 %A, 0
323 %C2 = icmp ne i32 %B, 0
324 ; (A != 0) | (A != 0) --> (A|B) != 0
329 define i1 @test28_logical(i32 %A, i32 %B) {
330 ; CHECK-LABEL: @test28_logical(
331 ; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[A:%.*]], 0
332 ; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 [[B:%.*]], 0
333 ; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
334 ; CHECK-NEXT: ret i1 [[D]]
336 %C1 = icmp ne i32 %A, 0
337 %C2 = icmp ne i32 %B, 0
338 ; (A != 0) | (A != 0) --> (A|B) != 0
339 %D = select i1 %C1, i1 true, i1 %C2
343 define i1 @test29(i32* %A, i32* %B) {
344 ; CHECK-LABEL: @test29(
345 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32* [[A:%.*]], null
346 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32* [[B:%.*]], null
347 ; CHECK-NEXT: [[E:%.*]] = or i1 [[TMP1]], [[TMP2]]
348 ; CHECK-NEXT: ret i1 [[E]]
350 %C1 = ptrtoint i32* %A to i32
351 %C2 = ptrtoint i32* %B to i32
353 %E = icmp ne i32 %D, 0
357 define <2 x i1> @test29vec(<2 x i32*> %A, <2 x i32*> %B) {
358 ; CHECK-LABEL: @test29vec(
359 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32*> [[A:%.*]], zeroinitializer
360 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32*> [[B:%.*]], zeroinitializer
361 ; CHECK-NEXT: [[E:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
362 ; CHECK-NEXT: ret <2 x i1> [[E]]
364 %C1 = ptrtoint <2 x i32*> %A to <2 x i32>
365 %C2 = ptrtoint <2 x i32*> %B to <2 x i32>
366 %D = or <2 x i32> %C1, %C2
367 %E = icmp ne <2 x i32> %D, zeroinitializer
372 define i32 @test30(i32 %A) {
373 ; CHECK-LABEL: @test30(
374 ; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], -58312
375 ; CHECK-NEXT: [[E:%.*]] = or i32 [[D]], 32962
376 ; CHECK-NEXT: ret i32 [[E]]
378 %B = or i32 %A, 32962 ; 0b1000_0000_1100_0010
379 %C = and i32 %A, -65536 ; 0xffff0000
380 %D = and i32 %B, 40186 ; 0b1001_1100_1111_1010
385 define <2 x i32> @test30vec(<2 x i32> %A) {
386 ; CHECK-LABEL: @test30vec(
387 ; CHECK-NEXT: [[C:%.*]] = and <2 x i32> [[A:%.*]], <i32 -65536, i32 -65536>
388 ; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[A]], <i32 7224, i32 7224>
389 ; CHECK-NEXT: [[D:%.*]] = or <2 x i32> [[B]], <i32 32962, i32 32962>
390 ; CHECK-NEXT: [[E:%.*]] = or <2 x i32> [[D]], [[C]]
391 ; CHECK-NEXT: ret <2 x i32> [[E]]
393 %B = or <2 x i32> %A, <i32 32962, i32 32962>
394 %C = and <2 x i32> %A, <i32 -65536, i32 -65536>
395 %D = and <2 x i32> %B, <i32 40186, i32 40186>
396 %E = or <2 x i32> %D, %C
401 define i64 @test31(i64 %A) {
402 ; CHECK-LABEL: @test31(
403 ; CHECK-NEXT: [[E:%.*]] = and i64 [[A:%.*]], 4294908984
404 ; CHECK-NEXT: [[F:%.*]] = or i64 [[E]], 32962
405 ; CHECK-NEXT: ret i64 [[F]]
410 %C = or i64 %A, 32768
411 %E = and i64 %C, 4294941696
417 define <2 x i64> @test31vec(<2 x i64> %A) {
418 ; CHECK-LABEL: @test31vec(
419 ; CHECK-NEXT: [[E:%.*]] = and <2 x i64> [[A:%.*]], <i64 4294908984, i64 4294908984>
420 ; CHECK-NEXT: [[F:%.*]] = or <2 x i64> [[E]], <i64 32962, i64 32962>
421 ; CHECK-NEXT: ret <2 x i64> [[F]]
423 %B = or <2 x i64> %A, <i64 194, i64 194>
424 %D = and <2 x i64> %B, <i64 250, i64 250>
426 %C = or <2 x i64> %A, <i64 32768, i64 32768>
427 %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696>
429 %F = or <2 x i64> %D, %E
433 ; codegen is mature enough to handle vector selects.
434 define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) {
435 ; CHECK-LABEL: @test32(
436 ; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[AND_I1352:%.*]], <4 x i32> [[VECINIT6_I176:%.*]], <4 x i32> [[VECINIT6_I191:%.*]]
437 ; CHECK-NEXT: ret <4 x i32> [[TMP1]]
439 %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32>
440 %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135
441 %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1>
442 %and.i = and <4 x i32> %vecinit6.i191, %neg.i
443 %or.i = or <4 x i32> %and.i, %and.i129
447 define i1 @test33(i1 %X, i1 %Y) {
448 ; CHECK-LABEL: @test33(
449 ; CHECK-NEXT: [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
450 ; CHECK-NEXT: ret i1 [[A]]
457 define i1 @test33_logical(i1 %X, i1 %Y) {
458 ; CHECK-LABEL: @test33_logical(
459 ; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]
460 ; CHECK-NEXT: ret i1 [[A]]
462 %a = select i1 %X, i1 true, i1 %Y
463 %b = select i1 %a, i1 true, i1 %X
467 define i32 @test34(i32 %X, i32 %Y) {
468 ; CHECK-LABEL: @test34(
469 ; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
470 ; CHECK-NEXT: ret i32 [[A]]
477 define i32 @test35(i32 %a, i32 %b) {
478 ; CHECK-LABEL: @test35(
479 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
480 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 1135
481 ; CHECK-NEXT: ret i32 [[TMP2]]
488 define i1 @test36(i32 %x) {
489 ; CHECK-LABEL: @test36(
490 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23
491 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
492 ; CHECK-NEXT: ret i1 [[TMP2]]
494 %cmp1 = icmp eq i32 %x, 23
495 %cmp2 = icmp eq i32 %x, 24
496 %ret1 = or i1 %cmp1, %cmp2
497 %cmp3 = icmp eq i32 %x, 25
498 %ret2 = or i1 %ret1, %cmp3
502 define i1 @test36_logical(i32 %x) {
503 ; CHECK-LABEL: @test36_logical(
504 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23
505 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
506 ; CHECK-NEXT: ret i1 [[TMP2]]
508 %cmp1 = icmp eq i32 %x, 23
509 %cmp2 = icmp eq i32 %x, 24
510 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
511 %cmp3 = icmp eq i32 %x, 25
512 %ret2 = select i1 %ret1, i1 true, i1 %cmp3
516 define i1 @test37(i32 %x) {
517 ; CHECK-LABEL: @test37(
518 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
519 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
520 ; CHECK-NEXT: ret i1 [[TMP2]]
522 %add1 = add i32 %x, 7
523 %cmp1 = icmp ult i32 %add1, 30
524 %cmp2 = icmp eq i32 %x, 23
525 %ret1 = or i1 %cmp1, %cmp2
529 define i1 @test37_logical(i32 %x) {
530 ; CHECK-LABEL: @test37_logical(
531 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
532 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
533 ; CHECK-NEXT: ret i1 [[TMP2]]
535 %add1 = add i32 %x, 7
536 %cmp1 = icmp ult i32 %add1, 30
537 %cmp2 = icmp eq i32 %x, 23
538 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
542 define <2 x i1> @test37_uniform(<2 x i32> %x) {
543 ; CHECK-LABEL: @test37_uniform(
544 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 7>
545 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 31, i32 31>
546 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
548 %add1 = add <2 x i32> %x, <i32 7, i32 7>
549 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 30>
550 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 23>
551 %ret1 = or <2 x i1> %cmp1, %cmp2
555 define <2 x i1> @test37_undef(<2 x i32> %x) {
556 ; CHECK-LABEL: @test37_undef(
557 ; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 undef>
558 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 undef>
559 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 undef>
560 ; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
561 ; CHECK-NEXT: ret <2 x i1> [[RET1]]
563 %add1 = add <2 x i32> %x, <i32 7, i32 undef>
564 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 undef>
565 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 undef>
566 %ret1 = or <2 x i1> %cmp1, %cmp2
570 define i1 @test38(i32 %x) {
571 ; CHECK-LABEL: @test38(
572 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
573 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
574 ; CHECK-NEXT: ret i1 [[TMP2]]
576 %add1 = add i32 %x, 7
577 %cmp1 = icmp eq i32 %x, 23
578 %cmp2 = icmp ult i32 %add1, 30
579 %ret1 = or i1 %cmp1, %cmp2
583 define i1 @test38_logical(i32 %x) {
584 ; CHECK-LABEL: @test38_logical(
585 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7
586 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
587 ; CHECK-NEXT: ret i1 [[TMP2]]
589 %add1 = add i32 %x, 7
590 %cmp1 = icmp eq i32 %x, 23
591 %cmp2 = icmp ult i32 %add1, 30
592 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
596 define <2 x i1> @test38_nonuniform(<2 x i32> %x) {
597 ; CHECK-LABEL: @test38_nonuniform(
598 ; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 24>
599 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 8>
600 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 32>
601 ; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
602 ; CHECK-NEXT: ret <2 x i1> [[RET1]]
604 %add1 = add <2 x i32> %x, <i32 7, i32 24>
605 %cmp1 = icmp eq <2 x i32> %x, <i32 23, i32 8>
606 %cmp2 = icmp ult <2 x i32> %add1, <i32 30, i32 32>
607 %ret1 = or <2 x i1> %cmp1, %cmp2
611 ; (~A & B) | A --> A | B
613 define i32 @test39a(i32 %a, float %b) {
614 ; CHECK-LABEL: @test39a(
615 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
616 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
617 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
618 ; CHECK-NEXT: ret i32 [[OR]]
620 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
621 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
622 %nota = xor i32 %a1, -1
623 %and = and i32 %nota, %b1
624 %or = or i32 %and, %a1
628 ; Commute 'and' operands:
629 ; (B & ~A) | A --> A | B
631 define i32 @test39b(i32 %a, float %b) {
632 ; CHECK-LABEL: @test39b(
633 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
634 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
635 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
636 ; CHECK-NEXT: ret i32 [[OR]]
638 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
639 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
640 %nota = xor i32 %a1, -1
641 %and = and i32 %b1, %nota
642 %or = or i32 %and, %a1
646 ; Commute 'or' operands:
647 ; A | (~A & B) --> A | B
649 define i32 @test39c(i32 %a, float %b) {
650 ; CHECK-LABEL: @test39c(
651 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
652 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
653 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
654 ; CHECK-NEXT: ret i32 [[OR]]
656 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
657 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
658 %nota = xor i32 %a1, -1
659 %and = and i32 %nota, %b1
660 %or = or i32 %a1, %and
664 ; Commute 'and' operands:
665 ; A | (B & ~A) --> A | B
667 define i32 @test39d(i32 %a, float %b) {
668 ; CHECK-LABEL: @test39d(
669 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
670 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
671 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
672 ; CHECK-NEXT: ret i32 [[OR]]
674 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
675 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
676 %nota = xor i32 %a1, -1
677 %and = and i32 %b1, %nota
678 %or = or i32 %a1, %and
682 define i32 @test40(i32 %a, i32 %b) {
683 ; CHECK-LABEL: @test40(
684 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
685 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
686 ; CHECK-NEXT: ret i32 [[OR]]
688 %and = and i32 %a, %b
689 %xor = xor i32 %a, -1
690 %or = or i32 %and, %xor
694 define i32 @test40b(i32 %a, i32 %b) {
695 ; CHECK-LABEL: @test40b(
696 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
697 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
698 ; CHECK-NEXT: ret i32 [[OR]]
700 %and = and i32 %b, %a
701 %xor = xor i32 %a, -1
702 %or = or i32 %and, %xor
706 define i32 @test40c(i32 %a, i32 %b) {
707 ; CHECK-LABEL: @test40c(
708 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
709 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
710 ; CHECK-NEXT: ret i32 [[OR]]
712 %and = and i32 %b, %a
713 %xor = xor i32 %a, -1
714 %or = or i32 %xor, %and
718 define i32 @test40d(i32 %a, i32 %b) {
719 ; CHECK-LABEL: @test40d(
720 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
721 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
722 ; CHECK-NEXT: ret i32 [[OR]]
724 %and = and i32 %a, %b
725 %xor = xor i32 %a, -1
726 %or = or i32 %xor, %and
730 define i32 @test45(i32 %x, i32 %y, i32 %z) {
731 ; CHECK-LABEL: @test45(
732 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
733 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]]
734 ; CHECK-NEXT: ret i32 [[OR1]]
737 %and = and i32 %x, %or
738 %or1 = or i32 %and, %y
742 define i1 @test46(i8 signext %c) {
743 ; CHECK-LABEL: @test46(
744 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
745 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
746 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
747 ; CHECK-NEXT: ret i1 [[TMP3]]
749 %c.off = add i8 %c, -97
750 %cmp1 = icmp ult i8 %c.off, 26
751 %c.off17 = add i8 %c, -65
752 %cmp2 = icmp ult i8 %c.off17, 26
753 %or = or i1 %cmp1, %cmp2
757 define i1 @test46_logical(i8 signext %c) {
758 ; CHECK-LABEL: @test46_logical(
759 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
760 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
761 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
762 ; CHECK-NEXT: ret i1 [[TMP3]]
764 %c.off = add i8 %c, -97
765 %cmp1 = icmp ult i8 %c.off, 26
766 %c.off17 = add i8 %c, -65
767 %cmp2 = icmp ult i8 %c.off17, 26
768 %or = select i1 %cmp1, i1 true, i1 %cmp2
772 define <2 x i1> @test46_uniform(<2 x i8> %c) {
773 ; CHECK-LABEL: @test46_uniform(
774 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[C:%.*]], <i8 -33, i8 -33>
775 ; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[TMP1]], <i8 -65, i8 -65>
776 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult <2 x i8> [[TMP2]], <i8 26, i8 26>
777 ; CHECK-NEXT: ret <2 x i1> [[TMP3]]
779 %c.off = add <2 x i8> %c, <i8 -97, i8 -97>
780 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 26>
781 %c.off17 = add <2 x i8> %c, <i8 -65, i8 -65>
782 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 26>
783 %or = or <2 x i1> %cmp1, %cmp2
787 define <2 x i1> @test46_undef(<2 x i8> %c) {
788 ; CHECK-LABEL: @test46_undef(
789 ; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 undef>
790 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 26, i8 undef>
791 ; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -65, i8 undef>
792 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 26, i8 undef>
793 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
794 ; CHECK-NEXT: ret <2 x i1> [[OR]]
796 %c.off = add <2 x i8> %c, <i8 -97, i8 undef>
797 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 undef>
798 %c.off17 = add <2 x i8> %c, <i8 -65, i8 undef>
799 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 undef>
800 %or = or <2 x i1> %cmp1, %cmp2
804 define i1 @test47(i8 signext %c) {
805 ; CHECK-LABEL: @test47(
806 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
807 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
808 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
809 ; CHECK-NEXT: ret i1 [[TMP3]]
811 %c.off = add i8 %c, -65
812 %cmp1 = icmp ule i8 %c.off, 26
813 %c.off17 = add i8 %c, -97
814 %cmp2 = icmp ule i8 %c.off17, 26
815 %or = or i1 %cmp1, %cmp2
819 define i1 @test47_logical(i8 signext %c) {
820 ; CHECK-LABEL: @test47_logical(
821 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
822 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
823 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
824 ; CHECK-NEXT: ret i1 [[TMP3]]
826 %c.off = add i8 %c, -65
827 %cmp1 = icmp ule i8 %c.off, 26
828 %c.off17 = add i8 %c, -97
829 %cmp2 = icmp ule i8 %c.off17, 26
830 %or = select i1 %cmp1, i1 true, i1 %cmp2
834 define <2 x i1> @test47_nonuniform(<2 x i8> %c) {
835 ; CHECK-LABEL: @test47_nonuniform(
836 ; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -65, i8 -97>
837 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 27, i8 27>
838 ; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -97, i8 -65>
839 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 27, i8 27>
840 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
841 ; CHECK-NEXT: ret <2 x i1> [[OR]]
843 %c.off = add <2 x i8> %c, <i8 -65, i8 -97>
844 %cmp1 = icmp ule <2 x i8> %c.off, <i8 26, i8 26>
845 %c.off17 = add <2 x i8> %c, <i8 -97, i8 -65>
846 %cmp2 = icmp ule <2 x i8> %c.off17, <i8 26, i8 26>
847 %or = or <2 x i1> %cmp1, %cmp2
851 define i32 @test49(i1 %C) {
852 ; CHECK-LABEL: @test49(
853 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1019, i32 123
854 ; CHECK-NEXT: ret i32 [[V]]
856 %A = select i1 %C, i32 1000, i32 10
861 define <2 x i32> @test49vec(i1 %C) {
862 ; CHECK-LABEL: @test49vec(
863 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 1019>, <2 x i32> <i32 123, i32 123>
864 ; CHECK-NEXT: ret <2 x i32> [[V]]
866 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
867 %V = or <2 x i32> %A, <i32 123, i32 123>
871 define <2 x i32> @test49vec2(i1 %C) {
872 ; CHECK-LABEL: @test49vec2(
873 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 2509>, <2 x i32> <i32 123, i32 351>
874 ; CHECK-NEXT: ret <2 x i32> [[V]]
876 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
877 %V = or <2 x i32> %A, <i32 123, i32 333>
881 define i32 @test50(i1 %which) {
882 ; CHECK-LABEL: @test50(
884 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
886 ; CHECK-NEXT: br label [[FINAL]]
888 ; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1019, [[ENTRY:%.*]] ], [ 123, [[DELAY]] ]
889 ; CHECK-NEXT: ret i32 [[A]]
892 br i1 %which, label %final, label %delay
898 %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
899 %value = or i32 %A, 123
903 define <2 x i32> @test50vec(i1 %which) {
904 ; CHECK-LABEL: @test50vec(
906 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
908 ; CHECK-NEXT: br label [[FINAL]]
910 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 1019>, [[ENTRY:%.*]] ], [ <i32 123, i32 123>, [[DELAY]] ]
911 ; CHECK-NEXT: ret <2 x i32> [[A]]
914 br i1 %which, label %final, label %delay
920 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
921 %value = or <2 x i32> %A, <i32 123, i32 123>
925 define <2 x i32> @test50vec2(i1 %which) {
926 ; CHECK-LABEL: @test50vec2(
928 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
930 ; CHECK-NEXT: br label [[FINAL]]
932 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 2509>, [[ENTRY:%.*]] ], [ <i32 123, i32 351>, [[DELAY]] ]
933 ; CHECK-NEXT: ret <2 x i32> [[A]]
936 br i1 %which, label %final, label %delay
942 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
943 %value = or <2 x i32> %A, <i32 123, i32 333>
947 ; In the next 4 tests, vary the types and predicates for extra coverage.
948 ; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp
950 define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) {
951 ; CHECK-LABEL: @or_andn_cmp_1(
952 ; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
953 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
954 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]
955 ; CHECK-NEXT: ret i1 [[OR]]
957 %x = icmp sgt i32 %a, %b
958 %x_inv = icmp sle i32 %a, %b
959 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
960 %and = and i1 %y, %x_inv
965 define i1 @or_andn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {
966 ; CHECK-LABEL: @or_andn_cmp_1_logical(
967 ; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
968 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
969 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
970 ; CHECK-NEXT: ret i1 [[OR]]
972 %x = icmp sgt i32 %a, %b
973 %x_inv = icmp sle i32 %a, %b
974 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
975 %and = select i1 %y, i1 %x_inv, i1 false
976 %or = select i1 %x, i1 true, i1 %and
981 ; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp
983 define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
984 ; CHECK-LABEL: @or_andn_cmp_2(
985 ; CHECK-NEXT: [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
986 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
987 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[Y]], [[X]]
988 ; CHECK-NEXT: ret <2 x i1> [[OR]]
990 %x = icmp sge <2 x i32> %a, %b
991 %x_inv = icmp slt <2 x i32> %a, %b
992 %y = icmp ugt <2 x i32> %c, <i32 42, i32 47> ; thwart complexity-based ordering
993 %and = and <2 x i1> %y, %x_inv
994 %or = or <2 x i1> %and, %x
999 ; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp
1001 define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) {
1002 ; CHECK-LABEL: @or_andn_cmp_3(
1003 ; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1004 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1005 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]
1006 ; CHECK-NEXT: ret i1 [[OR]]
1008 %x = icmp ugt i72 %a, %b
1009 %x_inv = icmp ule i72 %a, %b
1010 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering
1011 %and = and i1 %x_inv, %y
1012 %or = or i1 %x, %and
1016 define i1 @or_andn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {
1017 ; CHECK-LABEL: @or_andn_cmp_3_logical(
1018 ; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1019 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1020 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
1021 ; CHECK-NEXT: ret i1 [[OR]]
1023 %x = icmp ugt i72 %a, %b
1024 %x_inv = icmp ule i72 %a, %b
1025 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering
1026 %and = select i1 %x_inv, i1 %y, i1 false
1027 %or = select i1 %x, i1 true, i1 %and
1032 ; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp
1034 define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
1035 ; CHECK-LABEL: @or_andn_cmp_4(
1036 ; CHECK-NEXT: [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
1037 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
1038 ; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[Y]], [[X]]
1039 ; CHECK-NEXT: ret <3 x i1> [[OR]]
1041 %x = icmp eq <3 x i32> %a, %b
1042 %x_inv = icmp ne <3 x i32> %a, %b
1043 %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1> ; thwart complexity-based ordering
1044 %and = and <3 x i1> %x_inv, %y
1045 %or = or <3 x i1> %and, %x
1049 ; In the next 4 tests, vary the types and predicates for extra coverage.
1050 ; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp
1052 define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) {
1053 ; CHECK-LABEL: @orn_and_cmp_1(
1054 ; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1055 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1056 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_INV]], [[Y]]
1057 ; CHECK-NEXT: ret i1 [[OR]]
1059 %x = icmp sgt i37 %a, %b
1060 %x_inv = icmp sle i37 %a, %b
1061 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering
1062 %and = and i1 %y, %x
1063 %or = or i1 %x_inv, %and
1067 define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i37 %c) {
1068 ; CHECK-LABEL: @orn_and_cmp_1_logical(
1069 ; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1070 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1071 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1072 ; CHECK-NEXT: ret i1 [[OR]]
1074 %x = icmp sgt i37 %a, %b
1075 %x_inv = icmp sle i37 %a, %b
1076 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering
1077 %and = select i1 %y, i1 %x, i1 false
1078 %or = select i1 %x_inv, i1 true, i1 %and
1083 ; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1085 define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) {
1086 ; CHECK-LABEL: @orn_and_cmp_2(
1087 ; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1088 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1089 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1090 ; CHECK-NEXT: ret i1 [[OR]]
1092 %x = icmp sge i16 %a, %b
1093 %x_inv = icmp slt i16 %a, %b
1094 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering
1095 %and = and i1 %y, %x
1096 %or = or i1 %and, %x_inv
1100 define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i16 %c) {
1101 ; CHECK-LABEL: @orn_and_cmp_2_logical(
1102 ; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1103 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1104 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y]], i1 true, i1 [[X_INV]]
1105 ; CHECK-NEXT: ret i1 [[OR]]
1107 %x = icmp sge i16 %a, %b
1108 %x_inv = icmp slt i16 %a, %b
1109 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering
1110 %and = select i1 %y, i1 %x, i1 false
1111 %or = select i1 %and, i1 true, i1 %x_inv
1115 ; Commute the 'and':
1116 ; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp
1118 define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
1119 ; CHECK-LABEL: @orn_and_cmp_3(
1120 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
1121 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
1122 ; CHECK-NEXT: [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]]
1123 ; CHECK-NEXT: ret <4 x i1> [[OR]]
1125 %x = icmp ugt <4 x i32> %a, %b
1126 %x_inv = icmp ule <4 x i32> %a, %b
1127 %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1> ; thwart complexity-based ordering
1128 %and = and <4 x i1> %x, %y
1129 %or = or <4 x i1> %x_inv, %and
1134 ; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1136 define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) {
1137 ; CHECK-LABEL: @orn_and_cmp_4(
1138 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1139 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1140 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1141 ; CHECK-NEXT: ret i1 [[OR]]
1143 %x = icmp eq i32 %a, %b
1144 %x_inv = icmp ne i32 %a, %b
1145 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1146 %and = and i1 %x, %y
1147 %or = or i1 %and, %x_inv
1151 define i1 @orn_and_cmp_4_logical(i32 %a, i32 %b, i32 %c) {
1152 ; CHECK-LABEL: @orn_and_cmp_4_logical(
1153 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1154 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1155 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1156 ; CHECK-NEXT: ret i1 [[OR]]
1158 %x = icmp eq i32 %a, %b
1159 %x_inv = icmp ne i32 %a, %b
1160 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1161 %and = select i1 %x, i1 %y, i1 false
1162 %or = select i1 %and, i1 true, i1 %x_inv
1166 ; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1.
1167 define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {
1168 ; CHECK-LABEL: @test51(
1169 ; 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>
1170 ; CHECK-NEXT: ret <16 x i1> [[TMP1]]
1172 %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>
1173 %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>
1174 %tmp3 = or <16 x i1> %tmp, %tmp2
1178 ; This would infinite loop because it reaches a transform
1179 ; that was not expecting a constant-foldable value.
1181 define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) {
1182 ; CHECK-LABEL: @PR46712(
1183 ; CHECK-NEXT: entry:
1184 ; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1186 ; CHECK-NEXT: [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
1187 ; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
1188 ; CHECK-NEXT: br label [[END]]
1190 ; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
1191 ; CHECK-NEXT: ret i32 [[T5]]
1195 %conv = sext i1 %t2 to i32
1196 %cmp = icmp sge i32 %conv, 1
1197 %conv2 = zext i1 %cmp to i64
1198 br i1 %b, label %true, label %end
1201 %bool4 = icmp eq i64 %conv2, 0
1202 %bool5 = icmp ne i64 %z, 0
1203 %and = and i1 %bool4, %bool5
1204 %sel = select i1 %and, i1 false, i1 true
1208 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1209 %conv8 = zext i1 %t5 to i32
1213 define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) {
1214 ; CHECK-LABEL: @PR46712_logical(
1215 ; CHECK-NEXT: entry:
1216 ; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1218 ; CHECK-NEXT: [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
1219 ; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
1220 ; CHECK-NEXT: br label [[END]]
1222 ; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
1223 ; CHECK-NEXT: ret i32 [[T5]]
1226 %t2 = select i1 %x, i1 true, i1 %y
1227 %conv = sext i1 %t2 to i32
1228 %cmp = icmp sge i32 %conv, 1
1229 %conv2 = zext i1 %cmp to i64
1230 br i1 %b, label %true, label %end
1233 %bool4 = icmp eq i64 %conv2, 0
1234 %bool5 = icmp ne i64 %z, 0
1235 %and = select i1 %bool4, i1 %bool5, i1 false
1236 %sel = select i1 %and, i1 false, i1 true
1240 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1241 %conv8 = zext i1 %t5 to i32
1245 ; (~x & y) | ~(x | y) --> ~x
1246 define i32 @PR38929(i32 %0, i32 %1) {
1247 ; CHECK-LABEL: @PR38929(
1248 ; CHECK-NEXT: [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], -1
1249 ; CHECK-NEXT: ret i32 [[TMP3]]
1259 define i32 @test1(i32 %x, i32 %y) {
1260 ; CHECK-LABEL: @test1(
1261 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1262 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1263 ; CHECK-NEXT: ret i32 [[OR1]]
1265 %xor = xor i32 %y, %x
1267 %neg = xor i32 %or, -1
1268 %or1 = or i32 %xor, %neg
1272 define i32 @test2(i32 %x, i32 %y) {
1273 ; CHECK-LABEL: @test2(
1274 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1275 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1276 ; CHECK-NEXT: ret i32 [[OR1]]
1279 %neg = xor i32 %or, -1
1280 %xor = xor i32 %y, %x
1281 %or1 = or i32 %xor, %neg
1285 define i32 @test3(i32 %x, i32 %y) {
1286 ; CHECK-LABEL: @test3(
1287 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
1288 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1289 ; CHECK-NEXT: ret i32 [[OR1]]
1292 %neg = xor i32 %or, -1
1293 %xor = xor i32 %x, %y
1294 %or1 = or i32 %xor, %neg
1298 define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) {
1299 ; CHECK-LABEL: @test4_vec(
1300 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]]
1301 ; CHECK-NEXT: [[OR1:%.*]] = xor <2 x i32> [[TMP1]], <i32 -1, i32 -1>
1302 ; CHECK-NEXT: ret <2 x i32> [[OR1]]
1304 %or = or <2 x i32> %y, %x
1305 %neg = xor <2 x i32> %or, <i32 -1, i32 -1>
1306 %xor = xor <2 x i32> %y, %x
1307 %or1 = or <2 x i32> %xor, %neg
1311 define i32 @test5_use(i32 %x, i32 %y) {
1312 ; CHECK-LABEL: @test5_use(
1313 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1314 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -1
1315 ; CHECK-NEXT: call void @use(i32 [[NEG]])
1316 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1317 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1318 ; CHECK-NEXT: ret i32 [[OR1]]
1321 %neg = xor i32 %or, -1
1322 %xor = xor i32 %y, %x
1323 call void @use(i32 %neg)
1324 %or1 = or i32 %xor, %neg
1328 define i32 @test5_use2(i32 %x, i32 %y) {
1329 ; CHECK-LABEL: @test5_use2(
1330 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1331 ; CHECK-NEXT: call void @use(i32 [[XOR]])
1332 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1333 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1334 ; CHECK-NEXT: ret i32 [[OR1]]
1337 %neg = xor i32 %or, -1
1338 %xor = xor i32 %y, %x
1339 call void @use(i32 %xor)
1340 %or1 = or i32 %xor, %neg
1343 define i32 @test5_use3(i32 %x, i32 %y) {
1344 ; CHECK-LABEL: @test5_use3(
1345 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1346 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -1
1347 ; CHECK-NEXT: call void @use(i32 [[NEG]])
1348 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]]
1349 ; CHECK-NEXT: call void @use(i32 [[XOR]])
1350 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
1351 ; CHECK-NEXT: ret i32 [[OR1]]
1354 %neg = xor i32 %or, -1
1355 call void @use(i32 %neg)
1356 %xor = xor i32 %y, %x
1357 call void @use(i32 %xor)
1358 %or1 = or i32 %xor, %neg
1362 define i8 @ashr_bitwidth_mask(i8 %x, i8 %y) {
1363 ; CHECK-LABEL: @ashr_bitwidth_mask(
1364 ; CHECK-NEXT: [[SIGN:%.*]] = ashr i8 [[X:%.*]], 7
1365 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1366 ; CHECK-NEXT: ret i8 [[R]]
1368 %sign = ashr i8 %x, 7
1369 %r = or i8 %sign, %y
1373 define <2 x i8> @ashr_bitwidth_mask_vec_commute(<2 x i8> %x, <2 x i8> %py) {
1374 ; CHECK-LABEL: @ashr_bitwidth_mask_vec_commute(
1375 ; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], <i8 42, i8 2>
1376 ; CHECK-NEXT: [[SIGN:%.*]] = ashr <2 x i8> [[X:%.*]], <i8 7, i8 7>
1377 ; CHECK-NEXT: [[R:%.*]] = or <2 x i8> [[Y]], [[SIGN]]
1378 ; CHECK-NEXT: ret <2 x i8> [[R]]
1380 %y = mul <2 x i8> %py, <i8 42, i8 2> ; thwart complexity-based ordering
1381 %sign = ashr <2 x i8> %x, <i8 7, i8 7>
1382 %r = or <2 x i8> %y, %sign
1386 define i32 @ashr_bitwidth_mask_use(i32 %x, i32 %y) {
1387 ; CHECK-LABEL: @ashr_bitwidth_mask_use(
1388 ; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X:%.*]], 7
1389 ; CHECK-NEXT: call void @use(i32 [[SIGN]])
1390 ; CHECK-NEXT: [[R:%.*]] = or i32 [[SIGN]], [[Y:%.*]]
1391 ; CHECK-NEXT: ret i32 [[R]]
1393 %sign = ashr i32 %x, 7
1394 call void @use(i32 %sign)
1395 %r = or i32 %sign, %y
1399 define i8 @ashr_not_bitwidth_mask(i8 %x, i8 %y) {
1400 ; CHECK-LABEL: @ashr_not_bitwidth_mask(
1401 ; CHECK-NEXT: [[SIGN:%.*]] = ashr i8 [[X:%.*]], 6
1402 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1403 ; CHECK-NEXT: ret i8 [[R]]
1405 %sign = ashr i8 %x, 6
1406 %r = or i8 %sign, %y
1410 define i8 @lshr_bitwidth_mask(i8 %x, i8 %y) {
1411 ; CHECK-LABEL: @lshr_bitwidth_mask(
1412 ; CHECK-NEXT: [[SIGN:%.*]] = lshr i8 [[X:%.*]], 7
1413 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1414 ; CHECK-NEXT: ret i8 [[R]]
1416 %sign = lshr i8 %x, 7
1417 %r = or i8 %sign, %y
1421 define i1 @cmp_overlap(i32 %x) {
1422 ; CHECK-LABEL: @cmp_overlap(
1423 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 1
1424 ; CHECK-NEXT: ret i1 [[TMP1]]
1426 %isneg = icmp slt i32 %x, 0
1427 %negx = sub i32 0, %x
1428 %isnotneg = icmp sgt i32 %negx, -1
1429 %r = or i1 %isneg, %isnotneg
1433 define <2 x i1> @cmp_overlap_splat(<2 x i5> %x) {
1434 ; CHECK-LABEL: @cmp_overlap_splat(
1435 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i5> [[X:%.*]], <i5 1, i5 1>
1436 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
1438 %isneg = icmp slt <2 x i5> %x, zeroinitializer
1439 %negx = sub <2 x i5> zeroinitializer, %x
1440 %isnotneg = icmp sgt <2 x i5> %negx, <i5 -1, i5 -1>
1441 %r = or <2 x i1> %isneg, %isnotneg
1445 define i32 @mul_no_common_bits(i32 %p1, i32 %p2) {
1446 ; CHECK-LABEL: @mul_no_common_bits(
1447 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 7
1448 ; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1449 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[Y]], 1
1450 ; CHECK-NEXT: [[R:%.*]] = mul i32 [[X]], [[TMP1]]
1451 ; CHECK-NEXT: ret i32 [[R]]
1460 define i32 @mul_no_common_bits_const_op(i32 %p) {
1461 ; CHECK-LABEL: @mul_no_common_bits_const_op(
1462 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7
1463 ; CHECK-NEXT: [[R:%.*]] = mul nuw nsw i32 [[X]], 25
1464 ; CHECK-NEXT: ret i32 [[R]]
1472 define <2 x i12> @mul_no_common_bits_commute(<2 x i12> %p) {
1473 ; CHECK-LABEL: @mul_no_common_bits_commute(
1474 ; CHECK-NEXT: [[X:%.*]] = and <2 x i12> [[P:%.*]], <i12 1, i12 1>
1475 ; CHECK-NEXT: [[R:%.*]] = mul nuw nsw <2 x i12> [[X]], <i12 15, i12 17>
1476 ; CHECK-NEXT: ret <2 x i12> [[R]]
1478 %x = and <2 x i12> %p, <i12 1, i12 1>
1479 %m = mul <2 x i12> %x, <i12 14, i12 16>
1480 %r = or <2 x i12> %x, %m
1484 ; negative test - extra use requires extra instructions
1486 define i32 @mul_no_common_bits_uses(i32 %p1, i32 %p2) {
1487 ; CHECK-LABEL: @mul_no_common_bits_uses(
1488 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 7
1489 ; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1490 ; CHECK-NEXT: [[M:%.*]] = mul i32 [[X]], [[Y]]
1491 ; CHECK-NEXT: call void @use(i32 [[M]])
1492 ; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[X]]
1493 ; CHECK-NEXT: ret i32 [[R]]
1498 call void @use(i32 %m)
1503 ; negative test - probably not good to create an extra mul
1505 define i32 @mul_no_common_bits_const_op_uses(i32 %p) {
1506 ; CHECK-LABEL: @mul_no_common_bits_const_op_uses(
1507 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7
1508 ; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X]], 24
1509 ; CHECK-NEXT: call void @use(i32 [[M]])
1510 ; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[X]]
1511 ; CHECK-NEXT: ret i32 [[R]]
1515 call void @use(i32 %m)
1520 ; negative test - %x and %m may have set 3rd bit
1522 define i32 @mul_common_bits(i32 %p) {
1523 ; CHECK-LABEL: @mul_common_bits(
1524 ; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7
1525 ; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X]], 12
1526 ; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[X]]
1527 ; CHECK-NEXT: ret i32 [[R]]