1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 define i32 @select_0_or_1_from_bool(i1 %x) {
5 ; CHECK-LABEL: @select_0_or_1_from_bool(
6 ; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true
7 ; CHECK-NEXT: [[ADD:%.*]] = zext i1 [[TMP1]] to i32
8 ; CHECK-NEXT: ret i32 [[ADD]]
10 %ext = sext i1 %x to i32
11 %add = add i32 %ext, 1
15 define <2 x i32> @select_0_or_1_from_bool_vec(<2 x i1> %x) {
16 ; CHECK-LABEL: @select_0_or_1_from_bool_vec(
17 ; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[X:%.*]], <i1 true, i1 true>
18 ; CHECK-NEXT: [[ADD:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>
19 ; CHECK-NEXT: ret <2 x i32> [[ADD]]
21 %ext = sext <2 x i1> %x to <2 x i32>
22 %add = add <2 x i32> %ext, <i32 1, i32 1>
26 define i32 @select_C_minus_1_or_C_from_bool(i1 %x) {
27 ; CHECK-LABEL: @select_C_minus_1_or_C_from_bool(
28 ; CHECK-NEXT: [[ADD:%.*]] = select i1 [[X:%.*]], i32 41, i32 42
29 ; CHECK-NEXT: ret i32 [[ADD]]
31 %ext = sext i1 %x to i32
32 %add = add i32 %ext, 42
36 define <2 x i32> @select_C_minus_1_or_C_from_bool_vec(<2 x i1> %x) {
37 ; CHECK-LABEL: @select_C_minus_1_or_C_from_bool_vec(
38 ; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 41, i32 42>, <2 x i32> <i32 42, i32 43>
39 ; CHECK-NEXT: ret <2 x i32> [[ADD]]
41 %ext = sext <2 x i1> %x to <2 x i32>
42 %add = add <2 x i32> %ext, <i32 42, i32 43>
46 ; This is an 'andn' of the low bit.
48 define i32 @flip_and_mask(i32 %x) {
49 ; CHECK-LABEL: @flip_and_mask(
50 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 1
51 ; CHECK-NEXT: [[INC:%.*]] = xor i32 [[TMP1]], 1
52 ; CHECK-NEXT: ret i32 [[INC]]
55 %shr = ashr i32 %shl, 31
56 %inc = add i32 %shr, 1
60 define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) {
61 ; CHECK-LABEL: @flip_and_mask_splat(
62 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 1, i8 1>
63 ; CHECK-NEXT: [[INC:%.*]] = xor <2 x i8> [[TMP1]], <i8 1, i8 1>
64 ; CHECK-NEXT: ret <2 x i8> [[INC]]
66 %shl = shl <2 x i8> %x, <i8 7, i8 7>
67 %shr = ashr <2 x i8> %shl, <i8 7, i8 7>
68 %inc = add <2 x i8> %shr, <i8 1, i8 1>
72 define i32 @test1(i32 %A) {
73 ; CHECK-LABEL: @test1(
74 ; CHECK-NEXT: ret i32 [[A:%.*]]
80 define i32 @test2(i32 %A) {
81 ; CHECK-LABEL: @test2(
82 ; CHECK-NEXT: ret i32 [[A:%.*]]
89 define i32 @test3(i32 %A) {
90 ; CHECK-LABEL: @test3(
91 ; CHECK-NEXT: ret i32 [[A:%.*]]
99 define i32 @test4(i32 %A, i32 %B) {
100 ; CHECK-LABEL: @test4(
101 ; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
102 ; CHECK-NEXT: ret i32 [[D]]
110 define i32 @test5(i32 %A, i32 %B) {
111 ; CHECK-LABEL: @test5(
112 ; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
113 ; CHECK-NEXT: ret i32 [[D]]
120 define <2 x i8> @neg_op0_vec_undef_elt(<2 x i8> %a, <2 x i8> %b) {
121 ; CHECK-LABEL: @neg_op0_vec_undef_elt(
122 ; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[B:%.*]], [[A:%.*]]
123 ; CHECK-NEXT: ret <2 x i8> [[R]]
125 %nega = sub <2 x i8> <i8 0, i8 undef>, %a
126 %r = add <2 x i8> %nega, %b
130 define <2 x i8> @neg_neg_vec_undef_elt(<2 x i8> %a, <2 x i8> %b) {
131 ; CHECK-LABEL: @neg_neg_vec_undef_elt(
132 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]]
133 ; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
134 ; CHECK-NEXT: ret <2 x i8> [[R]]
136 %nega = sub <2 x i8> <i8 undef, i8 0>, %a
137 %negb = sub <2 x i8> <i8 undef, i8 0>, %b
138 %r = add <2 x i8> %nega, %negb
142 ; C = 7*A+A == 8*A == A << 3
143 define i32 @test6(i32 %A) {
144 ; CHECK-LABEL: @test6(
145 ; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3
146 ; CHECK-NEXT: ret i32 [[C]]
153 ; C = A+7*A == 8*A == A << 3
154 define i32 @test7(i32 %A) {
155 ; CHECK-LABEL: @test7(
156 ; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3
157 ; CHECK-NEXT: ret i32 [[C]]
164 ; (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
165 define i32 @test8(i32 %A, i32 %B) {
166 ; CHECK-LABEL: @test8(
167 ; CHECK-NEXT: [[A1:%.*]] = and i32 [[A:%.*]], 7
168 ; CHECK-NEXT: [[B1:%.*]] = and i32 [[B:%.*]], 128
169 ; CHECK-NEXT: [[C:%.*]] = or i32 [[A1]], [[B1]]
170 ; CHECK-NEXT: ret i32 [[C]]
173 %B1 = and i32 %B, 128
174 %C = add i32 %A1, %B1
178 define i32 @test9(i32 %A) {
179 ; CHECK-LABEL: @test9(
180 ; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 5
181 ; CHECK-NEXT: ret i32 [[C]]
189 define i1 @test10(i8 %a, i8 %b) {
190 ; CHECK-LABEL: @test10(
191 ; CHECK-NEXT: [[ADD:%.*]] = sub i8 0, [[B:%.*]]
192 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[ADD]], [[A:%.*]]
193 ; CHECK-NEXT: ret i1 [[C]]
196 %c = icmp ne i8 %add, 0
200 define <2 x i1> @test10vec(<2 x i8> %a, <2 x i8> %b) {
201 ; CHECK-LABEL: @test10vec(
202 ; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> zeroinitializer, [[B:%.*]]
203 ; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> [[C]], [[A:%.*]]
204 ; CHECK-NEXT: ret <2 x i1> [[D]]
206 %c = add <2 x i8> %a, %b
207 %d = icmp ne <2 x i8> %c, zeroinitializer
211 define i1 @test11(i8 %A) {
212 ; CHECK-LABEL: @test11(
213 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], 1
214 ; CHECK-NEXT: ret i1 [[C]]
217 %c = icmp ne i8 %B, 0
221 define <2 x i1> @test11vec(<2 x i8> %a) {
222 ; CHECK-LABEL: @test11vec(
223 ; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], <i8 1, i8 1>
224 ; CHECK-NEXT: ret <2 x i1> [[C]]
226 %b = add <2 x i8> %a, <i8 -1, i8 -1>
227 %c = icmp ne <2 x i8> %b, zeroinitializer
231 ; Should be transformed into shl A, 1?
233 define i32 @test12(i32 %A, i32 %B) {
234 ; CHECK-LABEL: @test12(
235 ; CHECK-NEXT: br label [[X:%.*]]
237 ; CHECK-NEXT: [[C_OK:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
238 ; CHECK-NEXT: [[D:%.*]] = add i32 [[C_OK]], [[A]]
239 ; CHECK-NEXT: ret i32 [[D]]
241 %C_OK = add i32 %B, %A
245 %D = add i32 %C_OK, %A
250 define i32 @test13(i32 %A, i32 %B, i32 %C) {
251 ; CHECK-LABEL: @test13(
252 ; CHECK-NEXT: [[D_OK:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
253 ; CHECK-NEXT: [[E_OK:%.*]] = add i32 [[D_OK]], [[C:%.*]]
254 ; CHECK-NEXT: [[F:%.*]] = add i32 [[E_OK]], [[A]]
255 ; CHECK-NEXT: ret i32 [[F]]
257 %D_OK = add i32 %A, %B
258 %E_OK = add i32 %D_OK, %C
259 %F = add i32 %E_OK, %A
263 define i32 @test14(i32 %offset, i32 %difference) {
264 ; CHECK-LABEL: @test14(
265 ; CHECK-NEXT: [[TMP_2:%.*]] = and i32 [[DIFFERENCE:%.*]], 3
266 ; CHECK-NEXT: [[TMP_3_OK:%.*]] = add i32 [[TMP_2]], [[OFFSET:%.*]]
267 ; CHECK-NEXT: [[TMP_5_MASK:%.*]] = and i32 [[DIFFERENCE]], -4
268 ; CHECK-NEXT: [[TMP_8:%.*]] = add i32 [[TMP_3_OK]], [[TMP_5_MASK]]
269 ; CHECK-NEXT: ret i32 [[TMP_8]]
271 %tmp.2 = and i32 %difference, 3
272 %tmp.3_OK = add i32 %tmp.2, %offset
273 %tmp.5.mask = and i32 %difference, -4
274 ; == add %offset, %difference
275 %tmp.8 = add i32 %tmp.3_OK, %tmp.5.mask
280 define i8 @test15(i8 %A) {
281 ; CHECK-LABEL: @test15(
282 ; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 16
283 ; CHECK-NEXT: ret i8 [[C]]
291 define i8 @test16(i8 %A) {
292 ; CHECK-LABEL: @test16(
293 ; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 16
294 ; CHECK-NEXT: [[C:%.*]] = xor i8 [[B]], 16
295 ; CHECK-NEXT: ret i8 [[C]]
302 define i32 @test17(i32 %A) {
303 ; CHECK-LABEL: @test17(
304 ; CHECK-NEXT: [[C:%.*]] = sub i32 0, [[A:%.*]]
305 ; CHECK-NEXT: ret i32 [[C]]
312 define i8 @test18(i8 %A) {
313 ; CHECK-LABEL: @test18(
314 ; CHECK-NEXT: [[C:%.*]] = sub i8 16, [[A:%.*]]
315 ; CHECK-NEXT: ret i8 [[C]]
322 define <2 x i64> @test18vec(<2 x i64> %A) {
323 ; CHECK-LABEL: @test18vec(
324 ; CHECK-NEXT: [[ADD:%.*]] = sub <2 x i64> <i64 1, i64 2>, [[A:%.*]]
325 ; CHECK-NEXT: ret <2 x i64> [[ADD]]
327 %xor = xor <2 x i64> %A, <i64 -1, i64 -1>
328 %add = add <2 x i64> %xor, <i64 2, i64 3>
332 define i32 @test19(i1 %C) {
333 ; CHECK-LABEL: @test19(
334 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
335 ; CHECK-NEXT: ret i32 [[V]]
337 %A = select i1 %C, i32 1000, i32 10
342 define <2 x i32> @test19vec(i1 %C) {
343 ; CHECK-LABEL: @test19vec(
344 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133>
345 ; CHECK-NEXT: ret <2 x i32> [[V]]
347 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
348 %V = add <2 x i32> %A, <i32 123, i32 123>
352 ; This is an InstSimplify fold, but test it here to make sure that
353 ; InstCombine does not prevent the fold.
354 ; With NSW, add of sign bit -> or of sign bit.
356 define i32 @test20(i32 %x) {
357 ; CHECK-LABEL: @test20(
358 ; CHECK-NEXT: ret i32 [[X:%.*]]
360 %y = xor i32 %x, -2147483648
361 %z = add nsw i32 %y, -2147483648
365 define i32 @xor_sign_bit(i32 %x) {
366 ; CHECK-LABEL: @xor_sign_bit(
367 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], -2147483606
368 ; CHECK-NEXT: ret i32 [[ADD]]
370 %xor = xor i32 %x, 2147483648
371 %add = add i32 %xor, 42
375 ; No-wrap info allows converting the add to 'or'.
377 define i8 @add_nsw_signbit(i8 %x) {
378 ; CHECK-LABEL: @add_nsw_signbit(
379 ; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128
380 ; CHECK-NEXT: ret i8 [[Y]]
382 %y = add nsw i8 %x, -128
386 ; No-wrap info allows converting the add to 'or'.
388 define i8 @add_nuw_signbit(i8 %x) {
389 ; CHECK-LABEL: @add_nuw_signbit(
390 ; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128
391 ; CHECK-NEXT: ret i8 [[Y]]
393 %y = add nuw i8 %x, 128
397 define i32 @add_nsw_sext_add(i8 %x) {
398 ; CHECK-LABEL: @add_nsw_sext_add(
399 ; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
400 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 398
401 ; CHECK-NEXT: ret i32 [[R]]
403 %add = add nsw i8 %x, 42
404 %ext = sext i8 %add to i32
405 %r = add i32 %ext, 356
409 ; Negative test - extra use of the sext means increase of instructions.
411 define i32 @add_nsw_sext_add_extra_use_1(i8 %x, i32* %p) {
412 ; CHECK-LABEL: @add_nsw_sext_add_extra_use_1(
413 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], 42
414 ; CHECK-NEXT: [[EXT:%.*]] = sext i8 [[ADD]] to i32
415 ; CHECK-NEXT: store i32 [[EXT]], i32* [[P:%.*]], align 4
416 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[EXT]], 356
417 ; CHECK-NEXT: ret i32 [[R]]
419 %add = add nsw i8 %x, 42
420 %ext = sext i8 %add to i32
421 store i32 %ext, i32* %p
422 %r = add i32 %ext, 356
426 define <2 x i32> @add_nsw_sext_add_vec_extra_use_2(<2 x i8> %x, <2 x i8>* %p) {
427 ; CHECK-LABEL: @add_nsw_sext_add_vec_extra_use_2(
428 ; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i8> [[X:%.*]], <i8 42, i8 -5>
429 ; CHECK-NEXT: store <2 x i8> [[ADD]], <2 x i8>* [[P:%.*]], align 2
430 ; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32>
431 ; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 398, i32 7>
432 ; CHECK-NEXT: ret <2 x i32> [[R]]
434 %add = add nsw <2 x i8> %x, <i8 42, i8 -5>
435 store <2 x i8> %add, <2 x i8>* %p
436 %ext = sext <2 x i8> %add to <2 x i32>
437 %r = add <2 x i32> %ext, <i32 356, i32 12>
441 define <2 x i32> @add_nuw_zext_add_vec(<2 x i16> %x) {
442 ; CHECK-LABEL: @add_nuw_zext_add_vec(
443 ; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i32>
444 ; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 65850, i32 -7>
445 ; CHECK-NEXT: ret <2 x i32> [[R]]
447 %add = add nuw <2 x i16> %x, <i16 -42, i16 5>
448 %ext = zext <2 x i16> %add to <2 x i32>
449 %r = add <2 x i32> %ext, <i32 356, i32 -12>
453 ; Negative test - extra use of the zext means increase of instructions.
455 define i64 @add_nuw_zext_add_extra_use_1(i8 %x, i64* %p) {
456 ; CHECK-LABEL: @add_nuw_zext_add_extra_use_1(
457 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42
458 ; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[ADD]] to i64
459 ; CHECK-NEXT: store i64 [[EXT]], i64* [[P:%.*]], align 4
460 ; CHECK-NEXT: [[R:%.*]] = add nuw nsw i64 [[EXT]], 356
461 ; CHECK-NEXT: ret i64 [[R]]
463 %add = add nuw i8 %x, 42
464 %ext = zext i8 %add to i64
465 store i64 %ext, i64* %p
466 %r = add i64 %ext, 356
470 define i64 @add_nuw_zext_add_extra_use_2(i8 %x, i8* %p) {
471 ; CHECK-LABEL: @add_nuw_zext_add_extra_use_2(
472 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42
473 ; CHECK-NEXT: store i8 [[ADD]], i8* [[P:%.*]], align 1
474 ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i64
475 ; CHECK-NEXT: [[R:%.*]] = add nuw nsw i64 [[TMP1]], -314
476 ; CHECK-NEXT: ret i64 [[R]]
478 %add = add nuw i8 %x, 42
479 store i8 %add, i8* %p
480 %ext = zext i8 %add to i64
481 %r = add i64 %ext, -356
485 define i1 @test21(i32 %x) {
486 ; CHECK-LABEL: @test21(
487 ; CHECK-NEXT: [[Y:%.*]] = icmp eq i32 [[X:%.*]], 119
488 ; CHECK-NEXT: ret i1 [[Y]]
491 %y = icmp eq i32 %t, 123
495 define <2 x i1> @test21vec(<2 x i32> %x) {
496 ; CHECK-LABEL: @test21vec(
497 ; CHECK-NEXT: [[Y:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 119, i32 119>
498 ; CHECK-NEXT: ret <2 x i1> [[Y]]
500 %t = add <2 x i32> %x, <i32 4, i32 4>
501 %y = icmp eq <2 x i32> %t, <i32 123, i32 123>
505 define i32 @test22(i32 %V) {
506 ; CHECK-LABEL: @test22(
507 ; CHECK-NEXT: switch i32 [[V:%.*]], label [[DEFAULT:%.*]] [
508 ; CHECK-NEXT: i32 10, label [[LAB1:%.*]]
509 ; CHECK-NEXT: i32 20, label [[LAB2:%.*]]
512 ; CHECK-NEXT: ret i32 123
514 ; CHECK-NEXT: ret i32 12312
516 ; CHECK-NEXT: ret i32 1231231
519 switch i32 %V2, label %Default [
524 Default: ; preds = %0
534 define i32 @test23(i1 %C, i32 %a) {
535 ; CHECK-LABEL: @test23(
537 ; CHECK-NEXT: br i1 [[C:%.*]], label [[ENDIF:%.*]], label [[ELSE:%.*]]
539 ; CHECK-NEXT: br label [[ENDIF]]
541 ; CHECK-NEXT: [[B_0:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[ELSE]] ]
542 ; CHECK-NEXT: ret i32 [[B_0]]
545 br i1 %C, label %endif, label %else
547 else: ; preds = %entry
550 endif: ; preds = %else, %entry
551 %b.0 = phi i32 [ 0, %entry ], [ 1, %else ]
552 %tmp.4 = add i32 %b.0, 1
556 define i32 @test24(i32 %A) {
557 ; CHECK-LABEL: @test24(
558 ; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1
559 ; CHECK-NEXT: ret i32 [[B]]
567 define i64 @test25(i64 %Y) {
568 ; CHECK-LABEL: @test25(
569 ; CHECK-NEXT: [[TMP_8:%.*]] = shl i64 [[Y:%.*]], 3
570 ; CHECK-NEXT: ret i64 [[TMP_8]]
572 %tmp.4 = shl i64 %Y, 2
573 %tmp.12 = shl i64 %Y, 2
574 %tmp.8 = add i64 %tmp.4, %tmp.12
578 define i32 @test26(i32 %A, i32 %B) {
579 ; CHECK-LABEL: @test26(
580 ; CHECK-NEXT: ret i32 [[A:%.*]]
587 ; Fold add through select.
588 define i32 @test27(i1 %C, i32 %X, i32 %Y) {
589 ; CHECK-LABEL: @test27(
590 ; CHECK-NEXT: [[C_UPGRD_1_V:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 123
591 ; CHECK-NEXT: ret i32 [[C_UPGRD_1_V]]
595 %C.upgrd.1 = select i1 %C, i32 %A, i32 %B
596 %D = sub i32 %C.upgrd.1, %Y
600 define i32 @test28(i32 %X) {
601 ; CHECK-LABEL: @test28(
602 ; CHECK-NEXT: [[Z:%.*]] = sub i32 -1192, [[X:%.*]]
603 ; CHECK-NEXT: ret i32 [[Z]]
605 %Y = add i32 %X, 1234
610 define i32 @test29(i32 %x, i32 %y) {
611 ; CHECK-LABEL: @test29(
612 ; CHECK-NEXT: [[TMP_2:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
613 ; CHECK-NEXT: [[TMP_7:%.*]] = and i32 [[X]], 63
614 ; CHECK-NEXT: [[TMP_9:%.*]] = and i32 [[TMP_2]], -64
615 ; CHECK-NEXT: [[TMP_10:%.*]] = or i32 [[TMP_7]], [[TMP_9]]
616 ; CHECK-NEXT: ret i32 [[TMP_10]]
618 %tmp.2 = sub i32 %x, %y
619 %tmp.2.mask = and i32 %tmp.2, 63
620 %tmp.6 = add i32 %tmp.2.mask, %y
621 %tmp.7 = and i32 %tmp.6, 63
622 %tmp.9 = and i32 %tmp.2, -64
623 %tmp.10 = or i32 %tmp.7, %tmp.9
627 ; Add of sign bit -> xor of sign bit.
628 define i64 @test30(i64 %x) {
629 ; CHECK-LABEL: @test30(
630 ; CHECK-NEXT: ret i64 [[X:%.*]]
632 %tmp.2 = xor i64 %x, -9223372036854775808
633 %tmp.4 = add i64 %tmp.2, -9223372036854775808
637 define i32 @test31(i32 %A) {
638 ; CHECK-LABEL: @test31(
639 ; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[A:%.*]], 5
640 ; CHECK-NEXT: ret i32 [[TMP1]]
648 define i32 @test32(i32 %A) {
649 ; CHECK-LABEL: @test32(
650 ; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 2
651 ; CHECK-NEXT: ret i32 [[B]]
659 define i8 @test33(i8 %A) {
660 ; CHECK-LABEL: @test33(
661 ; CHECK-NEXT: [[C:%.*]] = or i8 [[A:%.*]], 1
662 ; CHECK-NEXT: ret i8 [[C]]
669 define i8 @test34(i8 %A) {
670 ; CHECK-LABEL: @test34(
671 ; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 12
672 ; CHECK-NEXT: ret i8 [[C]]
679 ; If all bits affected by the add are included
680 ; in the mask, do the add before the mask op.
682 define i8 @masked_add(i8 %x) {
683 ; CHECK-LABEL: @masked_add(
684 ; CHECK-NEXT: [[AND1:%.*]] = add i8 [[X:%.*]], 96
685 ; CHECK-NEXT: [[R:%.*]] = and i8 [[AND1]], -16
686 ; CHECK-NEXT: ret i8 [[R]]
688 %and = and i8 %x, 240 ; 0xf0
689 %r = add i8 %and, 96 ; 0x60
693 define <2 x i8> @masked_add_splat(<2 x i8> %x) {
694 ; CHECK-LABEL: @masked_add_splat(
695 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], <i8 -64, i8 -64>
696 ; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[AND]], <i8 64, i8 64>
697 ; CHECK-NEXT: ret <2 x i8> [[R]]
699 %and = and <2 x i8> %x, <i8 192, i8 192> ; 0xc0
700 %r = add <2 x i8> %and, <i8 64, i8 64> ; 0x40
704 define i8 @not_masked_add(i8 %x) {
705 ; CHECK-LABEL: @not_masked_add(
706 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 112
707 ; CHECK-NEXT: [[R:%.*]] = add nuw i8 [[AND]], 96
708 ; CHECK-NEXT: ret i8 [[R]]
710 %and = and i8 %x, 112 ; 0x70
711 %r = add i8 %and, 96 ; 0x60
715 define i32 @test35(i32 %a) {
716 ; CHECK-LABEL: @test35(
717 ; CHECK-NEXT: ret i32 -1
719 %tmpnot = xor i32 %a, -1
720 %tmp2 = add i32 %tmpnot, %a
724 define i32 @test36(i32 %a) {
725 ; CHECK-LABEL: @test36(
726 ; CHECK-NEXT: ret i32 0
729 %y = and i32 %a, -126
731 %q = and i32 %z, 1 ; always zero
735 define i1 @test37(i32 %a, i32 %b) {
736 ; CHECK-LABEL: @test37(
737 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0
738 ; CHECK-NEXT: ret i1 [[CMP]]
740 %add = add i32 %a, %b
741 %cmp = icmp eq i32 %add, %a
745 define i1 @test38(i32 %a, i32 %b) {
746 ; CHECK-LABEL: @test38(
747 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
748 ; CHECK-NEXT: ret i1 [[CMP]]
750 %add = add i32 %a, %b
751 %cmp = icmp eq i32 %add, %b
755 define i1 @test39(i32 %a, i32 %b) {
756 ; CHECK-LABEL: @test39(
757 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0
758 ; CHECK-NEXT: ret i1 [[CMP]]
760 %add = add i32 %b, %a
761 %cmp = icmp eq i32 %add, %a
765 define i1 @test40(i32 %a, i32 %b) {
766 ; CHECK-LABEL: @test40(
767 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
768 ; CHECK-NEXT: ret i1 [[CMP]]
770 %add = add i32 %b, %a
771 %cmp = icmp eq i32 %add, %b
775 ; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
777 define i64 @test41(i32 %a) {
778 ; CHECK-LABEL: @test41(
779 ; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[A:%.*]], 15
780 ; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[TMP1]] to i64
781 ; CHECK-NEXT: ret i64 [[SUB]]
783 %add = add nuw i32 %a, 16
784 %zext = zext i32 %add to i64
785 %sub = add i64 %zext, -1
789 ; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
791 define <2 x i64> @test41vec(<2 x i32> %a) {
792 ; CHECK-LABEL: @test41vec(
793 ; CHECK-NEXT: [[TMP1:%.*]] = add nuw <2 x i32> [[A:%.*]], <i32 15, i32 15>
794 ; CHECK-NEXT: [[SUB:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
795 ; CHECK-NEXT: ret <2 x i64> [[SUB]]
797 %add = add nuw <2 x i32> %a, <i32 16, i32 16>
798 %zext = zext <2 x i32> %add to <2 x i64>
799 %sub = add <2 x i64> %zext, <i64 -1, i64 -1>
803 define <2 x i64> @test41vec_and_multiuse(<2 x i32> %a) {
804 ; CHECK-LABEL: @test41vec_and_multiuse(
805 ; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i32> [[A:%.*]], <i32 16, i32 16>
806 ; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i32> [[ADD]] to <2 x i64>
807 ; CHECK-NEXT: [[SUB:%.*]] = add nsw <2 x i64> [[ZEXT]], <i64 -1, i64 -1>
808 ; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nsw <2 x i64> [[SUB]], [[ZEXT]]
809 ; CHECK-NEXT: ret <2 x i64> [[EXTRAUSE]]
811 %add = add nuw <2 x i32> %a, <i32 16, i32 16>
812 %zext = zext <2 x i32> %add to <2 x i64>
813 %sub = add <2 x i64> %zext, <i64 -1, i64 -1>
814 %extrause = add <2 x i64> %zext, %sub
815 ret <2 x i64> %extrause
818 define i32 @test42(i1 %C) {
819 ; CHECK-LABEL: @test42(
820 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
821 ; CHECK-NEXT: ret i32 [[V]]
823 %A = select i1 %C, i32 1000, i32 10
828 define <2 x i32> @test42vec(i1 %C) {
829 ; CHECK-LABEL: @test42vec(
830 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133>
831 ; CHECK-NEXT: ret <2 x i32> [[V]]
833 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
834 %V = add <2 x i32> <i32 123, i32 123>, %A
838 define <2 x i32> @test42vec2(i1 %C) {
839 ; CHECK-LABEL: @test42vec2(
840 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 2833>, <2 x i32> <i32 133, i32 363>
841 ; CHECK-NEXT: ret <2 x i32> [[V]]
843 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
844 %V = add <2 x i32> <i32 123, i32 333>, %A
848 define i32 @test55(i1 %which) {
849 ; CHECK-LABEL: @test55(
851 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
853 ; CHECK-NEXT: br label [[FINAL]]
855 ; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1123, [[ENTRY:%.*]] ], [ 133, [[DELAY]] ]
856 ; CHECK-NEXT: ret i32 [[A]]
859 br i1 %which, label %final, label %delay
865 %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
866 %value = add i32 123, %A
870 define <2 x i32> @test43vec(i1 %which) {
871 ; CHECK-LABEL: @test43vec(
873 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
875 ; CHECK-NEXT: br label [[FINAL]]
877 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 1123>, [[ENTRY:%.*]] ], [ <i32 133, i32 133>, [[DELAY]] ]
878 ; CHECK-NEXT: ret <2 x i32> [[A]]
881 br i1 %which, label %final, label %delay
887 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
888 %value = add <2 x i32> <i32 123, i32 123>, %A
892 define <2 x i32> @test43vec2(i1 %which) {
893 ; CHECK-LABEL: @test43vec2(
895 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
897 ; CHECK-NEXT: br label [[FINAL]]
899 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 2833>, [[ENTRY:%.*]] ], [ <i32 133, i32 363>, [[DELAY]] ]
900 ; CHECK-NEXT: ret <2 x i32> [[A]]
903 br i1 %which, label %final, label %delay
909 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
910 %value = add <2 x i32> <i32 123, i32 333>, %A
914 ; E = (A + 1) + ~B = A - B
915 define i32 @add_not_increment(i32 %A, i32 %B) {
916 ; CHECK-LABEL: @add_not_increment(
917 ; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
918 ; CHECK-NEXT: ret i32 [[E]]
926 ; E = (A + 1) + ~B = A - B
927 define <2 x i32> @add_not_increment_vec(<2 x i32> %A, <2 x i32> %B) {
928 ; CHECK-LABEL: @add_not_increment_vec(
929 ; CHECK-NEXT: [[E:%.*]] = sub <2 x i32> [[A:%.*]], [[B:%.*]]
930 ; CHECK-NEXT: ret <2 x i32> [[E]]
932 %C = xor <2 x i32> %B, <i32 -1, i32 -1>
933 %D = add <2 x i32> %A, <i32 1, i32 1>
934 %E = add <2 x i32> %D, %C
938 ; E = ~B + (1 + A) = A - B
939 define i32 @add_not_increment_commuted(i32 %A, i32 %B) {
940 ; CHECK-LABEL: @add_not_increment_commuted(
941 ; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
942 ; CHECK-NEXT: ret i32 [[E]]
950 ; E = (A + ~B) + 1 = A - B
951 define i32 @add_to_sub(i32 %M, i32 %B) {
952 ; CHECK-LABEL: @add_to_sub(
953 ; CHECK-NEXT: [[A:%.*]] = mul i32 [[M:%.*]], 42
954 ; CHECK-NEXT: [[E:%.*]] = sub i32 [[A]], [[B:%.*]]
955 ; CHECK-NEXT: ret i32 [[E]]
957 %A = mul i32 %M, 42 ; thwart complexity-based ordering
964 ; E = (~B + A) + 1 = A - B
965 define i32 @add_to_sub2(i32 %A, i32 %M) {
966 ; CHECK-LABEL: @add_to_sub2(
967 ; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[M:%.*]], -42
968 ; CHECK-NEXT: [[E:%.*]] = add i32 [[TMP1]], [[A:%.*]]
969 ; CHECK-NEXT: ret i32 [[E]]
971 %B = mul i32 %M, 42 ; thwart complexity-based ordering
978 ; (X | C1) + C2 --> (X | C1) ^ C1 iff (C1 == -C2)
979 define i32 @test44(i32 %A) {
980 ; CHECK-LABEL: @test44(
981 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], -124
982 ; CHECK-NEXT: ret i32 [[TMP1]]
985 %C = add i32 %B, -123
989 define i32 @test44_extra_use(i32 %A) {
990 ; CHECK-LABEL: @test44_extra_use(
991 ; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 123
992 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A]], -124
993 ; CHECK-NEXT: [[D:%.*]] = mul i32 [[B]], [[TMP1]]
994 ; CHECK-NEXT: ret i32 [[D]]
997 %C = add i32 %B, -123
1002 define i32 @test44_non_matching(i32 %A) {
1003 ; CHECK-LABEL: @test44_non_matching(
1004 ; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 123
1005 ; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], -321
1006 ; CHECK-NEXT: ret i32 [[C]]
1009 %C = add i32 %B, -321
1013 define <2 x i32> @test44_vec(<2 x i32> %A) {
1014 ; CHECK-LABEL: @test44_vec(
1015 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], <i32 -124, i32 -124>
1016 ; CHECK-NEXT: ret <2 x i32> [[TMP1]]
1018 %B = or <2 x i32> %A, <i32 123, i32 123>
1019 %C = add <2 x i32> %B, <i32 -123, i32 -123>
1023 define <2 x i32> @test44_vec_non_matching(<2 x i32> %A) {
1024 ; CHECK-LABEL: @test44_vec_non_matching(
1025 ; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 123>
1026 ; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], <i32 -321, i32 -321>
1027 ; CHECK-NEXT: ret <2 x i32> [[C]]
1029 %B = or <2 x i32> %A, <i32 123, i32 123>
1030 %C = add <2 x i32> %B, <i32 -321, i32 -321>
1034 define <2 x i32> @test44_vec_undef(<2 x i32> %A) {
1035 ; CHECK-LABEL: @test44_vec_undef(
1036 ; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 undef>
1037 ; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], <i32 -123, i32 undef>
1038 ; CHECK-NEXT: ret <2 x i32> [[C]]
1040 %B = or <2 x i32> %A, <i32 123, i32 undef>
1041 %C = add <2 x i32> %B, <i32 -123, i32 undef>
1045 define <2 x i32> @test44_vec_non_splat(<2 x i32> %A) {
1046 ; CHECK-LABEL: @test44_vec_non_splat(
1047 ; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 456>
1048 ; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], <i32 -123, i32 -456>
1049 ; CHECK-NEXT: ret <2 x i32> [[C]]
1051 %B = or <2 x i32> %A, <i32 123, i32 456>
1052 %C = add <2 x i32> %B, <i32 -123, i32 -456>