1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
5 declare void @use_i1(i1)
7 define i32 @select_0_or_1_from_bool(i1 %x) {
8 ; CHECK-LABEL: @select_0_or_1_from_bool(
9 ; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
10 ; CHECK-NEXT: [[ADD:%.*]] = zext i1 [[NOT_X]] to i32
11 ; CHECK-NEXT: ret i32 [[ADD]]
13 %ext = sext i1 %x to i32
14 %add = add i32 %ext, 1
18 define <2 x i32> @select_0_or_1_from_bool_vec(<2 x i1> %x) {
19 ; CHECK-LABEL: @select_0_or_1_from_bool_vec(
20 ; CHECK-NEXT: [[NOT_X:%.*]] = xor <2 x i1> [[X:%.*]], <i1 true, i1 true>
21 ; CHECK-NEXT: [[ADD:%.*]] = zext <2 x i1> [[NOT_X]] to <2 x i32>
22 ; CHECK-NEXT: ret <2 x i32> [[ADD]]
24 %ext = sext <2 x i1> %x to <2 x i32>
25 %add = add <2 x i32> %ext, <i32 1, i32 1>
29 define i32 @select_C_minus_1_or_C_from_bool(i1 %x) {
30 ; CHECK-LABEL: @select_C_minus_1_or_C_from_bool(
31 ; CHECK-NEXT: [[ADD:%.*]] = select i1 [[X:%.*]], i32 41, i32 42
32 ; CHECK-NEXT: ret i32 [[ADD]]
34 %ext = sext i1 %x to i32
35 %add = add i32 %ext, 42
39 define <2 x i32> @select_C_minus_1_or_C_from_bool_vec(<2 x i1> %x) {
40 ; CHECK-LABEL: @select_C_minus_1_or_C_from_bool_vec(
41 ; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 41, i32 42>, <2 x i32> <i32 42, i32 43>
42 ; CHECK-NEXT: ret <2 x i32> [[ADD]]
44 %ext = sext <2 x i1> %x to <2 x i32>
45 %add = add <2 x i32> %ext, <i32 42, i32 43>
49 ; This is an 'andn' of the low bit.
51 define i32 @flip_and_mask(i32 %x) {
52 ; CHECK-LABEL: @flip_and_mask(
53 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 1
54 ; CHECK-NEXT: [[INC:%.*]] = xor i32 [[TMP1]], 1
55 ; CHECK-NEXT: ret i32 [[INC]]
58 %shr = ashr i32 %shl, 31
59 %inc = add i32 %shr, 1
63 define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) {
64 ; CHECK-LABEL: @flip_and_mask_splat(
65 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 1, i8 1>
66 ; CHECK-NEXT: [[INC:%.*]] = xor <2 x i8> [[TMP1]], <i8 1, i8 1>
67 ; CHECK-NEXT: ret <2 x i8> [[INC]]
69 %shl = shl <2 x i8> %x, <i8 7, i8 7>
70 %shr = ashr <2 x i8> %shl, <i8 7, i8 7>
71 %inc = add <2 x i8> %shr, <i8 1, i8 1>
75 define i32 @test1(i32 %A) {
76 ; CHECK-LABEL: @test1(
77 ; CHECK-NEXT: ret i32 [[A:%.*]]
83 define i32 @test2(i32 %A) {
84 ; CHECK-LABEL: @test2(
85 ; CHECK-NEXT: ret i32 [[A:%.*]]
92 define i32 @test3(i32 %A) {
93 ; CHECK-LABEL: @test3(
94 ; CHECK-NEXT: ret i32 [[A:%.*]]
102 define i32 @test4(i32 %A, i32 %B) {
103 ; CHECK-LABEL: @test4(
104 ; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
105 ; CHECK-NEXT: ret i32 [[D]]
113 define i32 @test5(i32 %A, i32 %B) {
114 ; CHECK-LABEL: @test5(
115 ; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
116 ; CHECK-NEXT: ret i32 [[D]]
123 define i32 @test5_both_nsw(i32 %A, i32 %B) {
124 ; CHECK-LABEL: @test5_both_nsw(
125 ; CHECK-NEXT: [[D:%.*]] = sub nsw i32 [[B:%.*]], [[A:%.*]]
126 ; CHECK-NEXT: ret i32 [[D]]
128 %C = sub nsw i32 0, %A
129 %D = add nsw i32 %C, %B
133 define i32 @test5_neg_nsw(i32 %A, i32 %B) {
134 ; CHECK-LABEL: @test5_neg_nsw(
135 ; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
136 ; CHECK-NEXT: ret i32 [[D]]
138 %C = sub nsw i32 0, %A
143 define i32 @test5_add_nsw(i32 %A, i32 %B) {
144 ; CHECK-LABEL: @test5_add_nsw(
145 ; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
146 ; CHECK-NEXT: ret i32 [[D]]
149 %D = add nsw i32 %C, %B
153 define <2 x i8> @neg_op0_vec_poison_elt(<2 x i8> %a, <2 x i8> %b) {
154 ; CHECK-LABEL: @neg_op0_vec_poison_elt(
155 ; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[B:%.*]], [[A:%.*]]
156 ; CHECK-NEXT: ret <2 x i8> [[R]]
158 %nega = sub <2 x i8> <i8 0, i8 poison>, %a
159 %r = add <2 x i8> %nega, %b
163 define <2 x i8> @neg_neg_vec_poison_elt(<2 x i8> %a, <2 x i8> %b) {
164 ; CHECK-LABEL: @neg_neg_vec_poison_elt(
165 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]]
166 ; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
167 ; CHECK-NEXT: ret <2 x i8> [[R]]
169 %nega = sub <2 x i8> <i8 poison, i8 0>, %a
170 %negb = sub <2 x i8> <i8 poison, i8 0>, %b
171 %r = add <2 x i8> %nega, %negb
175 ; C = 7*A+A == 8*A == A << 3
176 define i32 @test6(i32 %A) {
177 ; CHECK-LABEL: @test6(
178 ; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3
179 ; CHECK-NEXT: ret i32 [[C]]
186 ; C = A+7*A == 8*A == A << 3
187 define i32 @test7(i32 %A) {
188 ; CHECK-LABEL: @test7(
189 ; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3
190 ; CHECK-NEXT: ret i32 [[C]]
197 ; (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
198 define i32 @test8(i32 %A, i32 %B) {
199 ; CHECK-LABEL: @test8(
200 ; CHECK-NEXT: [[A1:%.*]] = and i32 [[A:%.*]], 7
201 ; CHECK-NEXT: [[B1:%.*]] = and i32 [[B:%.*]], 128
202 ; CHECK-NEXT: [[C:%.*]] = or disjoint i32 [[A1]], [[B1]]
203 ; CHECK-NEXT: ret i32 [[C]]
206 %B1 = and i32 %B, 128
207 %C = add i32 %A1, %B1
211 define i32 @test9(i32 %A) {
212 ; CHECK-LABEL: @test9(
213 ; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 5
214 ; CHECK-NEXT: ret i32 [[C]]
222 define i1 @test10(i8 %a, i8 %b) {
223 ; CHECK-LABEL: @test10(
224 ; CHECK-NEXT: [[ADD:%.*]] = sub i8 0, [[B:%.*]]
225 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[ADD]], [[A:%.*]]
226 ; CHECK-NEXT: ret i1 [[C]]
229 %c = icmp ne i8 %add, 0
233 define <2 x i1> @test10vec(<2 x i8> %a, <2 x i8> %b) {
234 ; CHECK-LABEL: @test10vec(
235 ; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> zeroinitializer, [[B:%.*]]
236 ; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> [[C]], [[A:%.*]]
237 ; CHECK-NEXT: ret <2 x i1> [[D]]
239 %c = add <2 x i8> %a, %b
240 %d = icmp ne <2 x i8> %c, zeroinitializer
244 define i1 @test11(i8 %A) {
245 ; CHECK-LABEL: @test11(
246 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], 1
247 ; CHECK-NEXT: ret i1 [[C]]
250 %c = icmp ne i8 %B, 0
254 define <2 x i1> @test11vec(<2 x i8> %a) {
255 ; CHECK-LABEL: @test11vec(
256 ; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], <i8 1, i8 1>
257 ; CHECK-NEXT: ret <2 x i1> [[C]]
259 %b = add <2 x i8> %a, <i8 -1, i8 -1>
260 %c = icmp ne <2 x i8> %b, zeroinitializer
264 define i8 @reassoc_shl1(i8 %x, i8 %y) {
265 ; CHECK-LABEL: @reassoc_shl1(
266 ; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X:%.*]], 1
267 ; CHECK-NEXT: [[R:%.*]] = add i8 [[REASS_ADD]], [[Y:%.*]]
268 ; CHECK-NEXT: ret i8 [[R]]
275 define <2 x i8> @reassoc_shl1_commute1(<2 x i8> %x, <2 x i8> %y) {
276 ; CHECK-LABEL: @reassoc_shl1_commute1(
277 ; CHECK-NEXT: [[REASS_ADD:%.*]] = shl <2 x i8> [[X:%.*]], <i8 1, i8 1>
278 ; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[REASS_ADD]], [[Y:%.*]]
279 ; CHECK-NEXT: ret <2 x i8> [[R]]
281 %a = add <2 x i8> %x, %y
282 %r = add <2 x i8> %a, %x
286 define i8 @reassoc_shl1_commute2(i8 %px, i8 %py) {
287 ; CHECK-LABEL: @reassoc_shl1_commute2(
288 ; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[PX:%.*]]
289 ; CHECK-NEXT: [[Y:%.*]] = sdiv i8 43, [[PY:%.*]]
290 ; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X]], 1
291 ; CHECK-NEXT: [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]]
292 ; CHECK-NEXT: ret i8 [[R]]
294 %x = sdiv i8 42, %px ; thwart complexity-based canonicalization
295 %y = sdiv i8 43, %py ; thwart complexity-based canonicalization
301 define i8 @reassoc_shl1_commute3(i8 %px, i8 %py) {
302 ; CHECK-LABEL: @reassoc_shl1_commute3(
303 ; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[PX:%.*]]
304 ; CHECK-NEXT: [[Y:%.*]] = sdiv i8 43, [[PY:%.*]]
305 ; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X]], 1
306 ; CHECK-NEXT: [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]]
307 ; CHECK-NEXT: ret i8 [[R]]
309 %x = sdiv i8 42, %px ; thwart complexity-based canonicalization
310 %y = sdiv i8 43, %py ; thwart complexity-based canonicalization
316 define i8 @reassoc_shl1_extra_use(i8 %x, i8 %y) {
317 ; CHECK-LABEL: @reassoc_shl1_extra_use(
318 ; CHECK-NEXT: [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]]
319 ; CHECK-NEXT: call void @use(i8 [[A]])
320 ; CHECK-NEXT: [[R:%.*]] = add i8 [[A]], [[X]]
321 ; CHECK-NEXT: ret i8 [[R]]
324 call void @use(i8 %a)
330 define i32 @test13(i32 %A, i32 %B, i32 %C) {
331 ; CHECK-LABEL: @test13(
332 ; CHECK-NEXT: [[D_OK:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
333 ; CHECK-NEXT: [[E_OK:%.*]] = add i32 [[D_OK]], [[C:%.*]]
334 ; CHECK-NEXT: [[F:%.*]] = add i32 [[E_OK]], [[A]]
335 ; CHECK-NEXT: ret i32 [[F]]
337 %D_OK = add i32 %A, %B
338 %E_OK = add i32 %D_OK, %C
339 %F = add i32 %E_OK, %A
343 define i32 @test14(i32 %offset, i32 %difference) {
344 ; CHECK-LABEL: @test14(
345 ; CHECK-NEXT: [[TMP_2:%.*]] = and i32 [[DIFFERENCE:%.*]], 3
346 ; CHECK-NEXT: [[TMP_3_OK:%.*]] = add i32 [[TMP_2]], [[OFFSET:%.*]]
347 ; CHECK-NEXT: [[TMP_5_MASK:%.*]] = and i32 [[DIFFERENCE]], -4
348 ; CHECK-NEXT: [[TMP_8:%.*]] = add i32 [[TMP_3_OK]], [[TMP_5_MASK]]
349 ; CHECK-NEXT: ret i32 [[TMP_8]]
351 %tmp.2 = and i32 %difference, 3
352 %tmp.3_OK = add i32 %tmp.2, %offset
353 %tmp.5.mask = and i32 %difference, -4
354 ; == add %offset, %difference
355 %tmp.8 = add i32 %tmp.3_OK, %tmp.5.mask
360 define i8 @test15(i8 %A) {
361 ; CHECK-LABEL: @test15(
362 ; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 16
363 ; CHECK-NEXT: ret i8 [[C]]
370 define i32 @test17(i32 %A) {
371 ; CHECK-LABEL: @test17(
372 ; CHECK-NEXT: [[C:%.*]] = sub i32 0, [[A:%.*]]
373 ; CHECK-NEXT: ret i32 [[C]]
380 define i8 @test18(i8 %A) {
381 ; CHECK-LABEL: @test18(
382 ; CHECK-NEXT: [[C:%.*]] = sub i8 16, [[A:%.*]]
383 ; CHECK-NEXT: ret i8 [[C]]
390 ; ~X + -127 and (-128) - X with nsw are equally poisonous
391 define i8 @test18_nsw(i8 %A) {
392 ; CHECK-LABEL: @test18_nsw(
393 ; CHECK-NEXT: [[C:%.*]] = sub nsw i8 -128, [[A:%.*]]
394 ; CHECK-NEXT: ret i8 [[C]]
397 %C = add nsw i8 %B, -127
401 ; nuw couldn't propagate as nsw is.
402 define i8 @test18_nuw(i8 %A) {
403 ; CHECK-LABEL: @test18_nuw(
404 ; CHECK-NEXT: [[C:%.*]] = sub i8 -128, [[A:%.*]]
405 ; CHECK-NEXT: ret i8 [[C]]
408 %C = add nuw i8 %B, -127
412 ; 127 - X with nsw will be more poisonous than ~X + -128 with nsw. (see X = -1)
413 define i8 @test18_nsw_overflow(i8 %A) {
414 ; CHECK-LABEL: @test18_nsw_overflow(
415 ; CHECK-NEXT: [[C:%.*]] = sub i8 127, [[A:%.*]]
416 ; CHECK-NEXT: ret i8 [[C]]
419 %C = add nsw i8 %B, -128
423 define <2 x i64> @test18vec(<2 x i64> %A) {
424 ; CHECK-LABEL: @test18vec(
425 ; CHECK-NEXT: [[ADD:%.*]] = sub <2 x i64> <i64 1, i64 2>, [[A:%.*]]
426 ; CHECK-NEXT: ret <2 x i64> [[ADD]]
428 %xor = xor <2 x i64> %A, <i64 -1, i64 -1>
429 %add = add <2 x i64> %xor, <i64 2, i64 3>
433 define <2 x i8> @test18vec_nsw(<2 x i8> %A) {
434 ; CHECK-LABEL: @test18vec_nsw(
435 ; CHECK-NEXT: [[C:%.*]] = sub nsw <2 x i8> <i8 -124, i8 -125>, [[A:%.*]]
436 ; CHECK-NEXT: ret <2 x i8> [[C]]
438 %B = xor <2 x i8> %A, <i8 -1, i8 -1>
439 %C = add nsw <2 x i8> %B, <i8 -123, i8 -124>
443 define <2 x i8> @test18vec_nsw_false(<2 x i8> %A) {
444 ; CHECK-LABEL: @test18vec_nsw_false(
445 ; CHECK-NEXT: [[C:%.*]] = sub nsw <2 x i8> <i8 -125, i8 -126>, [[A:%.*]]
446 ; CHECK-NEXT: ret <2 x i8> [[C]]
448 %B = xor <2 x i8> %A, <i8 -1, i8 -1>
449 %C = add nsw <2 x i8> %B, <i8 -124, i8 -125>
454 define <2 x i8> @test18vec_nuw(<2 x i8> %A) {
455 ; CHECK-LABEL: @test18vec_nuw(
456 ; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> <i8 -128, i8 -127>, [[A:%.*]]
457 ; CHECK-NEXT: ret <2 x i8> [[C]]
459 %B = xor <2 x i8> %A, <i8 -1, i8 -1>
460 %C = add nuw <2 x i8> %B, <i8 -127, i8 -126>
464 define <2 x i8> @test18vec_nsw_overflow(<2 x i8> %A) {
465 ; CHECK-LABEL: @test18vec_nsw_overflow(
466 ; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> <i8 -128, i8 127>, [[A:%.*]]
467 ; CHECK-NEXT: ret <2 x i8> [[C]]
469 %B = xor <2 x i8> %A, <i8 -1, i8 -1>
470 %C = add nsw <2 x i8> %B, <i8 -127, i8 -128>
474 define i32 @test19(i1 %C) {
475 ; CHECK-LABEL: @test19(
476 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
477 ; CHECK-NEXT: ret i32 [[V]]
479 %A = select i1 %C, i32 1000, i32 10
484 define <2 x i32> @test19vec(i1 %C) {
485 ; CHECK-LABEL: @test19vec(
486 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133>
487 ; CHECK-NEXT: ret <2 x i32> [[V]]
489 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
490 %V = add <2 x i32> %A, <i32 123, i32 123>
494 ; This is an InstSimplify fold, but test it here to make sure that
495 ; InstCombine does not prevent the fold.
496 ; With NSW, add of sign bit -> or of sign bit.
498 define i32 @test20(i32 %x) {
499 ; CHECK-LABEL: @test20(
500 ; CHECK-NEXT: ret i32 [[X:%.*]]
502 %y = xor i32 %x, -2147483648
503 %z = add nsw i32 %y, -2147483648
507 define i32 @xor_sign_bit(i32 %x) {
508 ; CHECK-LABEL: @xor_sign_bit(
509 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], -2147483606
510 ; CHECK-NEXT: ret i32 [[ADD]]
512 %xor = xor i32 %x, 2147483648
513 %add = add i32 %xor, 42
517 define <2 x i32> @xor_sign_bit_vec_splat(<2 x i32> %x) {
518 ; CHECK-LABEL: @xor_sign_bit_vec_splat(
519 ; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> [[X:%.*]], <i32 -2147483606, i32 -2147483606>
520 ; CHECK-NEXT: ret <2 x i32> [[ADD]]
522 %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648>
523 %add = add <2 x i32> %xor, <i32 42, i32 42>
527 ; No-wrap info allows converting the add to 'or'.
529 define i8 @add_nsw_signbit(i8 %x) {
530 ; CHECK-LABEL: @add_nsw_signbit(
531 ; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128
532 ; CHECK-NEXT: ret i8 [[Y]]
534 %y = add nsw i8 %x, -128
538 ; No-wrap info allows converting the add to 'or'.
540 define i8 @add_nuw_signbit(i8 %x) {
541 ; CHECK-LABEL: @add_nuw_signbit(
542 ; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128
543 ; CHECK-NEXT: ret i8 [[Y]]
545 %y = add nuw i8 %x, 128
549 define i32 @add_nsw_sext_add(i8 %x) {
550 ; CHECK-LABEL: @add_nsw_sext_add(
551 ; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
552 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 398
553 ; CHECK-NEXT: ret i32 [[R]]
555 %add = add nsw i8 %x, 42
556 %ext = sext i8 %add to i32
557 %r = add i32 %ext, 356
561 ; Negative test - extra use of the sext means increase of instructions.
563 define i32 @add_nsw_sext_add_extra_use_1(i8 %x, ptr %p) {
564 ; CHECK-LABEL: @add_nsw_sext_add_extra_use_1(
565 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], 42
566 ; CHECK-NEXT: [[EXT:%.*]] = sext i8 [[ADD]] to i32
567 ; CHECK-NEXT: store i32 [[EXT]], ptr [[P:%.*]], align 4
568 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[EXT]], 356
569 ; CHECK-NEXT: ret i32 [[R]]
571 %add = add nsw i8 %x, 42
572 %ext = sext i8 %add to i32
573 store i32 %ext, ptr %p
574 %r = add i32 %ext, 356
578 define <2 x i32> @add_nsw_sext_add_vec_extra_use_2(<2 x i8> %x, ptr %p) {
579 ; CHECK-LABEL: @add_nsw_sext_add_vec_extra_use_2(
580 ; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i8> [[X:%.*]], <i8 42, i8 -5>
581 ; CHECK-NEXT: store <2 x i8> [[ADD]], ptr [[P:%.*]], align 2
582 ; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32>
583 ; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 398, i32 7>
584 ; CHECK-NEXT: ret <2 x i32> [[R]]
586 %add = add nsw <2 x i8> %x, <i8 42, i8 -5>
587 store <2 x i8> %add, ptr %p
588 %ext = sext <2 x i8> %add to <2 x i32>
589 %r = add <2 x i32> %ext, <i32 356, i32 12>
593 define <2 x i32> @add_nuw_zext_add_vec(<2 x i16> %x) {
594 ; CHECK-LABEL: @add_nuw_zext_add_vec(
595 ; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i32>
596 ; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 65850, i32 -7>
597 ; CHECK-NEXT: ret <2 x i32> [[R]]
599 %add = add nuw <2 x i16> %x, <i16 -42, i16 5>
600 %ext = zext <2 x i16> %add to <2 x i32>
601 %r = add <2 x i32> %ext, <i32 356, i32 -12>
605 ; Negative test - extra use of the zext means increase of instructions.
607 define i64 @add_nuw_zext_add_extra_use_1(i8 %x, ptr %p) {
608 ; CHECK-LABEL: @add_nuw_zext_add_extra_use_1(
609 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42
610 ; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[ADD]] to i64
611 ; CHECK-NEXT: store i64 [[EXT]], ptr [[P:%.*]], align 4
612 ; CHECK-NEXT: [[R:%.*]] = add nuw nsw i64 [[EXT]], 356
613 ; CHECK-NEXT: ret i64 [[R]]
615 %add = add nuw i8 %x, 42
616 %ext = zext i8 %add to i64
617 store i64 %ext, ptr %p
618 %r = add i64 %ext, 356
622 define i64 @add_nuw_zext_add_extra_use_2(i8 %x, ptr %p) {
623 ; CHECK-LABEL: @add_nuw_zext_add_extra_use_2(
624 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42
625 ; CHECK-NEXT: store i8 [[ADD]], ptr [[P:%.*]], align 1
626 ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i64
627 ; CHECK-NEXT: [[R:%.*]] = add nuw nsw i64 [[TMP1]], -314
628 ; CHECK-NEXT: ret i64 [[R]]
630 %add = add nuw i8 %x, 42
631 store i8 %add, ptr %p
632 %ext = zext i8 %add to i64
633 %r = add i64 %ext, -356
637 define i1 @test21(i32 %x) {
638 ; CHECK-LABEL: @test21(
639 ; CHECK-NEXT: [[Y:%.*]] = icmp eq i32 [[X:%.*]], 119
640 ; CHECK-NEXT: ret i1 [[Y]]
643 %y = icmp eq i32 %t, 123
647 define <2 x i1> @test21vec(<2 x i32> %x) {
648 ; CHECK-LABEL: @test21vec(
649 ; CHECK-NEXT: [[Y:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 119, i32 119>
650 ; CHECK-NEXT: ret <2 x i1> [[Y]]
652 %t = add <2 x i32> %x, <i32 4, i32 4>
653 %y = icmp eq <2 x i32> %t, <i32 123, i32 123>
657 define i32 @test22(i32 %V) {
658 ; CHECK-LABEL: @test22(
659 ; CHECK-NEXT: switch i32 [[V:%.*]], label [[DEFAULT:%.*]] [
660 ; CHECK-NEXT: i32 10, label [[LAB1:%.*]]
661 ; CHECK-NEXT: i32 20, label [[LAB2:%.*]]
664 ; CHECK-NEXT: ret i32 123
666 ; CHECK-NEXT: ret i32 12312
668 ; CHECK-NEXT: ret i32 1231231
671 switch i32 %V2, label %Default [
676 Default: ; preds = %0
686 define i32 @test23(i1 %C, i32 %a) {
687 ; CHECK-LABEL: @test23(
689 ; CHECK-NEXT: br i1 [[C:%.*]], label [[ENDIF:%.*]], label [[ELSE:%.*]]
691 ; CHECK-NEXT: br label [[ENDIF]]
693 ; CHECK-NEXT: [[B_0:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[ELSE]] ]
694 ; CHECK-NEXT: ret i32 [[B_0]]
697 br i1 %C, label %endif, label %else
699 else: ; preds = %entry
702 endif: ; preds = %else, %entry
703 %b.0 = phi i32 [ 0, %entry ], [ 1, %else ]
704 %tmp.4 = add i32 %b.0, 1
708 define i32 @test24(i32 %A) {
709 ; CHECK-LABEL: @test24(
710 ; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1
711 ; CHECK-NEXT: ret i32 [[B]]
719 define i64 @test25(i64 %Y) {
720 ; CHECK-LABEL: @test25(
721 ; CHECK-NEXT: [[TMP_8:%.*]] = shl i64 [[Y:%.*]], 3
722 ; CHECK-NEXT: ret i64 [[TMP_8]]
724 %tmp.4 = shl i64 %Y, 2
725 %tmp.12 = shl i64 %Y, 2
726 %tmp.8 = add i64 %tmp.4, %tmp.12
730 define i32 @test26(i32 %A, i32 %B) {
731 ; CHECK-LABEL: @test26(
732 ; CHECK-NEXT: ret i32 [[A:%.*]]
739 ; Fold add through select.
740 define i32 @test27(i1 %C, i32 %X, i32 %Y) {
741 ; CHECK-LABEL: @test27(
742 ; CHECK-NEXT: [[C_UPGRD_1_V:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 123
743 ; CHECK-NEXT: ret i32 [[C_UPGRD_1_V]]
747 %C.upgrd.1 = select i1 %C, i32 %A, i32 %B
748 %D = sub i32 %C.upgrd.1, %Y
752 define i32 @test28(i32 %X) {
753 ; CHECK-LABEL: @test28(
754 ; CHECK-NEXT: [[Z:%.*]] = sub i32 -1192, [[X:%.*]]
755 ; CHECK-NEXT: ret i32 [[Z]]
757 %Y = add i32 %X, 1234
762 define i32 @test29(i32 %x, i32 %y) {
763 ; CHECK-LABEL: @test29(
764 ; CHECK-NEXT: [[TMP_2:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
765 ; CHECK-NEXT: [[TMP_7:%.*]] = and i32 [[X]], 63
766 ; CHECK-NEXT: [[TMP_9:%.*]] = and i32 [[TMP_2]], -64
767 ; CHECK-NEXT: [[TMP_10:%.*]] = or disjoint i32 [[TMP_7]], [[TMP_9]]
768 ; CHECK-NEXT: ret i32 [[TMP_10]]
770 %tmp.2 = sub i32 %x, %y
771 %tmp.2.mask = and i32 %tmp.2, 63
772 %tmp.6 = add i32 %tmp.2.mask, %y
773 %tmp.7 = and i32 %tmp.6, 63
774 %tmp.9 = and i32 %tmp.2, -64
775 %tmp.10 = or i32 %tmp.7, %tmp.9
779 ; Add of sign bit -> xor of sign bit.
780 define i64 @test30(i64 %x) {
781 ; CHECK-LABEL: @test30(
782 ; CHECK-NEXT: ret i64 [[X:%.*]]
784 %tmp.2 = xor i64 %x, -9223372036854775808
785 %tmp.4 = add i64 %tmp.2, -9223372036854775808
789 define i32 @test31(i32 %A) {
790 ; CHECK-LABEL: @test31(
791 ; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[A:%.*]], 5
792 ; CHECK-NEXT: ret i32 [[TMP1]]
800 define i32 @test32(i32 %A) {
801 ; CHECK-LABEL: @test32(
802 ; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 2
803 ; CHECK-NEXT: ret i32 [[B]]
811 define i8 @test33(i8 %A) {
812 ; CHECK-LABEL: @test33(
813 ; CHECK-NEXT: [[C:%.*]] = or i8 [[A:%.*]], 1
814 ; CHECK-NEXT: ret i8 [[C]]
821 define i8 @test34(i8 %A) {
822 ; CHECK-LABEL: @test34(
823 ; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 12
824 ; CHECK-NEXT: ret i8 [[C]]
831 ; If all bits affected by the add are included
832 ; in the mask, do the mask op before the add.
834 define i8 @masked_add(i8 %x) {
835 ; CHECK-LABEL: @masked_add(
836 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], -16
837 ; CHECK-NEXT: [[R:%.*]] = add i8 [[AND]], 96
838 ; CHECK-NEXT: ret i8 [[R]]
840 %and = and i8 %x, 240 ; 0xf0
841 %r = add i8 %and, 96 ; 0x60
845 define <2 x i8> @masked_add_splat(<2 x i8> %x) {
846 ; CHECK-LABEL: @masked_add_splat(
847 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], <i8 -64, i8 -64>
848 ; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[AND]], <i8 64, i8 64>
849 ; CHECK-NEXT: ret <2 x i8> [[R]]
851 %and = and <2 x i8> %x, <i8 192, i8 192> ; 0xc0
852 %r = add <2 x i8> %and, <i8 64, i8 64> ; 0x40
856 define i8 @not_masked_add(i8 %x) {
857 ; CHECK-LABEL: @not_masked_add(
858 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 112
859 ; CHECK-NEXT: [[R:%.*]] = add nuw i8 [[AND]], 96
860 ; CHECK-NEXT: ret i8 [[R]]
862 %and = and i8 %x, 112 ; 0x70
863 %r = add i8 %and, 96 ; 0x60
867 define i8 @masked_add_multi_use(i8 %x) {
868 ; CHECK-LABEL: @masked_add_multi_use(
869 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], -16
870 ; CHECK-NEXT: [[R:%.*]] = add i8 [[AND]], 96
871 ; CHECK-NEXT: call void @use(i8 [[AND]])
872 ; CHECK-NEXT: ret i8 [[R]]
874 %and = and i8 %x, -16 ; 0xf0
875 %r = add i8 %and, 96 ; 0x60
876 call void @use(i8 %and) ; extra use
880 define i32 @test35(i32 %a) {
881 ; CHECK-LABEL: @test35(
882 ; CHECK-NEXT: ret i32 -1
884 %tmpnot = xor i32 %a, -1
885 %tmp2 = add i32 %tmpnot, %a
889 define i32 @test36(i32 %a) {
890 ; CHECK-LABEL: @test36(
891 ; CHECK-NEXT: ret i32 0
894 %y = and i32 %a, -126
896 %q = and i32 %z, 1 ; always zero
900 define i1 @test37(i32 %a, i32 %b) {
901 ; CHECK-LABEL: @test37(
902 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0
903 ; CHECK-NEXT: ret i1 [[CMP]]
905 %add = add i32 %a, %b
906 %cmp = icmp eq i32 %add, %a
910 define i1 @test38(i32 %a, i32 %b) {
911 ; CHECK-LABEL: @test38(
912 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
913 ; CHECK-NEXT: ret i1 [[CMP]]
915 %add = add i32 %a, %b
916 %cmp = icmp eq i32 %add, %b
920 define i1 @test39(i32 %a, i32 %b) {
921 ; CHECK-LABEL: @test39(
922 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0
923 ; CHECK-NEXT: ret i1 [[CMP]]
925 %add = add i32 %b, %a
926 %cmp = icmp eq i32 %add, %a
930 define i1 @test40(i32 %a, i32 %b) {
931 ; CHECK-LABEL: @test40(
932 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
933 ; CHECK-NEXT: ret i1 [[CMP]]
935 %add = add i32 %b, %a
936 %cmp = icmp eq i32 %add, %b
940 ; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
942 define i64 @test41(i32 %a) {
943 ; CHECK-LABEL: @test41(
944 ; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[A:%.*]], 15
945 ; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[TMP1]] to i64
946 ; CHECK-NEXT: ret i64 [[SUB]]
948 %add = add nuw i32 %a, 16
949 %zext = zext i32 %add to i64
950 %sub = add i64 %zext, -1
954 define i64 @test41_multiuse_constants_cancel(i32 %a) {
955 ; CHECK-LABEL: @test41_multiuse_constants_cancel(
956 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A:%.*]], 1
957 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[ADD]] to i64
958 ; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[A]] to i64
959 ; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nuw nsw i64 [[ZEXT]], [[SUB]]
960 ; CHECK-NEXT: ret i64 [[EXTRAUSE]]
962 %add = add nuw i32 %a, 1
963 %zext = zext i32 %add to i64
964 %sub = add i64 %zext, -1
965 %extrause = add i64 %zext, %sub
969 ; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
971 define <2 x i64> @test41vec(<2 x i32> %a) {
972 ; CHECK-LABEL: @test41vec(
973 ; CHECK-NEXT: [[TMP1:%.*]] = add nuw <2 x i32> [[A:%.*]], <i32 15, i32 15>
974 ; CHECK-NEXT: [[SUB:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
975 ; CHECK-NEXT: ret <2 x i64> [[SUB]]
977 %add = add nuw <2 x i32> %a, <i32 16, i32 16>
978 %zext = zext <2 x i32> %add to <2 x i64>
979 %sub = add <2 x i64> %zext, <i64 -1, i64 -1>
983 define <2 x i64> @test41vec_and_multiuse(<2 x i32> %a) {
984 ; CHECK-LABEL: @test41vec_and_multiuse(
985 ; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i32> [[A:%.*]], <i32 16, i32 16>
986 ; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i32> [[ADD]] to <2 x i64>
987 ; CHECK-NEXT: [[REASS_ADD:%.*]] = shl nuw nsw <2 x i64> [[ZEXT]], <i64 1, i64 1>
988 ; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nsw <2 x i64> [[REASS_ADD]], <i64 -1, i64 -1>
989 ; CHECK-NEXT: ret <2 x i64> [[EXTRAUSE]]
991 %add = add nuw <2 x i32> %a, <i32 16, i32 16>
992 %zext = zext <2 x i32> %add to <2 x i64>
993 %sub = add <2 x i64> %zext, <i64 -1, i64 -1>
994 %extrause = add <2 x i64> %zext, %sub
995 ret <2 x i64> %extrause
998 define i32 @test42(i1 %C) {
999 ; CHECK-LABEL: @test42(
1000 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
1001 ; CHECK-NEXT: ret i32 [[V]]
1003 %A = select i1 %C, i32 1000, i32 10
1004 %V = add i32 123, %A
1008 define <2 x i32> @test42vec(i1 %C) {
1009 ; CHECK-LABEL: @test42vec(
1010 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133>
1011 ; CHECK-NEXT: ret <2 x i32> [[V]]
1013 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
1014 %V = add <2 x i32> <i32 123, i32 123>, %A
1018 define <2 x i32> @test42vec2(i1 %C) {
1019 ; CHECK-LABEL: @test42vec2(
1020 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 2833>, <2 x i32> <i32 133, i32 363>
1021 ; CHECK-NEXT: ret <2 x i32> [[V]]
1023 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
1024 %V = add <2 x i32> <i32 123, i32 333>, %A
1028 define i32 @test55(i1 %which) {
1029 ; CHECK-LABEL: @test55(
1030 ; CHECK-NEXT: entry:
1031 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1033 ; CHECK-NEXT: br label [[FINAL]]
1035 ; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1123, [[ENTRY:%.*]] ], [ 133, [[DELAY]] ]
1036 ; CHECK-NEXT: ret i32 [[A]]
1039 br i1 %which, label %final, label %delay
1045 %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
1046 %value = add i32 123, %A
1050 define <2 x i32> @test43vec(i1 %which) {
1051 ; CHECK-LABEL: @test43vec(
1052 ; CHECK-NEXT: entry:
1053 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1055 ; CHECK-NEXT: br label [[FINAL]]
1057 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 1123>, [[ENTRY:%.*]] ], [ <i32 133, i32 133>, [[DELAY]] ]
1058 ; CHECK-NEXT: ret <2 x i32> [[A]]
1061 br i1 %which, label %final, label %delay
1067 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
1068 %value = add <2 x i32> <i32 123, i32 123>, %A
1069 ret <2 x i32> %value
1072 define <2 x i32> @test43vec2(i1 %which) {
1073 ; CHECK-LABEL: @test43vec2(
1074 ; CHECK-NEXT: entry:
1075 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1077 ; CHECK-NEXT: br label [[FINAL]]
1079 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 2833>, [[ENTRY:%.*]] ], [ <i32 133, i32 363>, [[DELAY]] ]
1080 ; CHECK-NEXT: ret <2 x i32> [[A]]
1083 br i1 %which, label %final, label %delay
1089 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
1090 %value = add <2 x i32> <i32 123, i32 333>, %A
1091 ret <2 x i32> %value
1094 ; E = (A + 1) + ~B = A - B
1095 define i32 @add_not_increment(i32 %A, i32 %B) {
1096 ; CHECK-LABEL: @add_not_increment(
1097 ; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
1098 ; CHECK-NEXT: ret i32 [[E]]
1106 ; E = (A + 1) + ~B = A - B
1107 define <2 x i32> @add_not_increment_vec(<2 x i32> %A, <2 x i32> %B) {
1108 ; CHECK-LABEL: @add_not_increment_vec(
1109 ; CHECK-NEXT: [[E:%.*]] = sub <2 x i32> [[A:%.*]], [[B:%.*]]
1110 ; CHECK-NEXT: ret <2 x i32> [[E]]
1112 %C = xor <2 x i32> %B, <i32 -1, i32 -1>
1113 %D = add <2 x i32> %A, <i32 1, i32 1>
1114 %E = add <2 x i32> %D, %C
1118 ; E = ~B + (1 + A) = A - B
1119 define i32 @add_not_increment_commuted(i32 %A, i32 %B) {
1120 ; CHECK-LABEL: @add_not_increment_commuted(
1121 ; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
1122 ; CHECK-NEXT: ret i32 [[E]]
1130 ; E = (A + ~B) + 1 = A - B
1131 define i32 @add_to_sub(i32 %M, i32 %B) {
1132 ; CHECK-LABEL: @add_to_sub(
1133 ; CHECK-NEXT: [[A:%.*]] = mul i32 [[M:%.*]], 42
1134 ; CHECK-NEXT: [[E:%.*]] = sub i32 [[A]], [[B:%.*]]
1135 ; CHECK-NEXT: ret i32 [[E]]
1137 %A = mul i32 %M, 42 ; thwart complexity-based ordering
1144 ; E = (~B + A) + 1 = A - B
1145 define i32 @add_to_sub2(i32 %A, i32 %M) {
1146 ; CHECK-LABEL: @add_to_sub2(
1147 ; CHECK-NEXT: [[B_NEG:%.*]] = mul i32 [[M:%.*]], -42
1148 ; CHECK-NEXT: [[E:%.*]] = add i32 [[B_NEG]], [[A:%.*]]
1149 ; CHECK-NEXT: ret i32 [[E]]
1151 %B = mul i32 %M, 42 ; thwart complexity-based ordering
1158 ; (X | C1) + C2 --> (X | C1) ^ C1 iff (C1 == -C2)
1159 define i32 @test44(i32 %A) {
1160 ; CHECK-LABEL: @test44(
1161 ; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], -124
1162 ; CHECK-NEXT: ret i32 [[C]]
1165 %C = add i32 %B, -123
1169 define i32 @test44_extra_use(i32 %A) {
1170 ; CHECK-LABEL: @test44_extra_use(
1171 ; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 123
1172 ; CHECK-NEXT: [[C:%.*]] = and i32 [[A]], -124
1173 ; CHECK-NEXT: [[D:%.*]] = mul i32 [[B]], [[C]]
1174 ; CHECK-NEXT: ret i32 [[D]]
1177 %C = add i32 %B, -123
1182 define i32 @test44_non_matching(i32 %A) {
1183 ; CHECK-LABEL: @test44_non_matching(
1184 ; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 123
1185 ; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], -321
1186 ; CHECK-NEXT: ret i32 [[C]]
1189 %C = add i32 %B, -321
1193 define <2 x i32> @test44_vec(<2 x i32> %A) {
1194 ; CHECK-LABEL: @test44_vec(
1195 ; CHECK-NEXT: [[C:%.*]] = and <2 x i32> [[A:%.*]], <i32 -124, i32 -124>
1196 ; CHECK-NEXT: ret <2 x i32> [[C]]
1198 %B = or <2 x i32> %A, <i32 123, i32 123>
1199 %C = add <2 x i32> %B, <i32 -123, i32 -123>
1203 define <2 x i32> @test44_vec_non_matching(<2 x i32> %A) {
1204 ; CHECK-LABEL: @test44_vec_non_matching(
1205 ; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 123>
1206 ; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], <i32 -321, i32 -321>
1207 ; CHECK-NEXT: ret <2 x i32> [[C]]
1209 %B = or <2 x i32> %A, <i32 123, i32 123>
1210 %C = add <2 x i32> %B, <i32 -321, i32 -321>
1214 define <2 x i32> @test44_vec_poison(<2 x i32> %A) {
1215 ; CHECK-LABEL: @test44_vec_poison(
1216 ; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 poison>
1217 ; CHECK-NEXT: [[C:%.*]] = add nsw <2 x i32> [[B]], <i32 -123, i32 poison>
1218 ; CHECK-NEXT: ret <2 x i32> [[C]]
1220 %B = or <2 x i32> %A, <i32 123, i32 poison>
1221 %C = add <2 x i32> %B, <i32 -123, i32 poison>
1225 define <2 x i32> @test44_vec_non_splat(<2 x i32> %A) {
1226 ; CHECK-LABEL: @test44_vec_non_splat(
1227 ; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 456>
1228 ; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], <i32 -123, i32 -456>
1229 ; CHECK-NEXT: ret <2 x i32> [[C]]
1231 %B = or <2 x i32> %A, <i32 123, i32 456>
1232 %C = add <2 x i32> %B, <i32 -123, i32 -456>
1236 define i32 @lshr_add(i1 %x, i1 %y) {
1237 ; CHECK-LABEL: @lshr_add(
1238 ; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true
1239 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[Y:%.*]]
1240 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP2]] to i32
1241 ; CHECK-NEXT: ret i32 [[R]]
1243 %xz = zext i1 %x to i32
1244 %ys = sext i1 %y to i32
1245 %sub = add i32 %xz, %ys
1246 %r = lshr i32 %sub, 31
1250 define i5 @and_add(i1 %x, i1 %y) {
1251 ; CHECK-LABEL: @and_add(
1252 ; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true
1253 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[Y:%.*]]
1254 ; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i5 -2, i5 0
1255 ; CHECK-NEXT: ret i5 [[R]]
1257 %xz = zext i1 %x to i5
1258 %ys = sext i1 %y to i5
1259 %sub = add i5 %xz, %ys
1260 %r = and i5 %sub, 30
1264 define <2 x i8> @ashr_add_commute(<2 x i1> %x, <2 x i1> %y) {
1265 ; CHECK-LABEL: @ashr_add_commute(
1266 ; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[X:%.*]], <i1 true, i1 true>
1267 ; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i1> [[TMP1]], [[Y:%.*]]
1268 ; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i8>
1269 ; CHECK-NEXT: ret <2 x i8> [[TMP3]]
1271 %xz = zext <2 x i1> %x to <2 x i8>
1272 %ys = sext <2 x i1> %y to <2 x i8>
1273 %sub = add nsw <2 x i8> %ys, %xz
1274 %r = ashr <2 x i8> %sub, <i8 1, i8 1>
1278 define i32 @cmp_math(i32 %x, i32 %y) {
1279 ; CHECK-LABEL: @cmp_math(
1280 ; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
1281 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[LT]] to i32
1282 ; CHECK-NEXT: ret i32 [[R]]
1284 %gt = icmp ugt i32 %x, %y
1285 %lt = icmp ult i32 %x, %y
1286 %xz = zext i1 %gt to i32
1287 %yz = zext i1 %lt to i32
1288 %s = sub i32 %xz, %yz
1289 %r = lshr i32 %s, 31
1293 ; Negative test - wrong type
1295 define i32 @lshr_add_nonbool(i2 %x, i1 %y) {
1296 ; CHECK-LABEL: @lshr_add_nonbool(
1297 ; CHECK-NEXT: [[XZ:%.*]] = zext i2 [[X:%.*]] to i32
1298 ; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1299 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1300 ; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
1301 ; CHECK-NEXT: ret i32 [[R]]
1303 %xz = zext i2 %x to i32
1304 %ys = sext i1 %y to i32
1305 %sub = add i32 %xz, %ys
1306 %r = lshr i32 %sub, 31
1310 ; Negative test - wrong demand
1312 define i32 @and31_add(i1 %x, i1 %y) {
1313 ; CHECK-LABEL: @and31_add(
1314 ; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i32
1315 ; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1316 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1317 ; CHECK-NEXT: [[R:%.*]] = and i32 [[SUB]], 31
1318 ; CHECK-NEXT: ret i32 [[R]]
1320 %xz = zext i1 %x to i32
1321 %ys = sext i1 %y to i32
1322 %sub = add i32 %xz, %ys
1323 %r = and i32 %sub, 31
1327 ; Negative test - extra use
1329 define i32 @lshr_add_use(i1 %x, i1 %y, ptr %p) {
1330 ; CHECK-LABEL: @lshr_add_use(
1331 ; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i32
1332 ; CHECK-NEXT: store i32 [[XZ]], ptr [[P:%.*]], align 4
1333 ; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1334 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1335 ; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
1336 ; CHECK-NEXT: ret i32 [[R]]
1338 %xz = zext i1 %x to i32
1339 store i32 %xz, ptr %p
1340 %ys = sext i1 %y to i32
1341 %sub = add i32 %xz, %ys
1342 %r = lshr i32 %sub, 31
1346 ; Negative test - extra use
1348 define i32 @lshr_add_use2(i1 %x, i1 %y, ptr %p) {
1349 ; CHECK-LABEL: @lshr_add_use2(
1350 ; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i32
1351 ; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1352 ; CHECK-NEXT: store i32 [[YS]], ptr [[P:%.*]], align 4
1353 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1354 ; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
1355 ; CHECK-NEXT: ret i32 [[R]]
1357 %xz = zext i1 %x to i32
1358 %ys = sext i1 %y to i32
1359 store i32 %ys, ptr %p
1360 %sub = add i32 %xz, %ys
1361 %r = lshr i32 %sub, 31
1365 define i32 @lshr_add_sexts(i1 %x, i1 %y) {
1366 ; CHECK-LABEL: @lshr_add_sexts(
1367 ; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
1368 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32
1369 ; CHECK-NEXT: ret i32 [[R]]
1371 %xs = sext i1 %x to i32
1372 %ys = sext i1 %y to i32
1373 %sub = add i32 %xs, %ys
1374 %r = lshr i32 %sub, 31
1378 define i5 @and_add_sexts(i1 %x, i1 %y) {
1379 ; CHECK-LABEL: @and_add_sexts(
1380 ; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
1381 ; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i5 -2, i5 0
1382 ; CHECK-NEXT: ret i5 [[R]]
1384 %xs = sext i1 %x to i5
1385 %ys = sext i1 %y to i5
1386 %sub = add i5 %xs, %ys
1387 %r = and i5 %sub, 30
1391 define <2 x i8> @ashr_add_sexts(<2 x i1> %x, <2 x i1> %y) {
1392 ; CHECK-LABEL: @ashr_add_sexts(
1393 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i1> [[Y:%.*]], [[X:%.*]]
1394 ; CHECK-NEXT: [[TMP2:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>
1395 ; CHECK-NEXT: ret <2 x i8> [[TMP2]]
1397 %xs = sext <2 x i1> %x to <2 x i8>
1398 %ys = sext <2 x i1> %y to <2 x i8>
1399 %sub = add nsw <2 x i8> %ys, %xs
1400 %r = ashr <2 x i8> %sub, <i8 1, i8 1>
1404 define i32 @cmp_math_sexts(i32 %x, i32 %y) {
1405 ; CHECK-LABEL: @cmp_math_sexts(
1406 ; CHECK-NEXT: [[DOTNOT:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
1407 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[DOTNOT]] to i32
1408 ; CHECK-NEXT: ret i32 [[R]]
1410 %gt = icmp ugt i32 %x, %y
1411 %lt = icmp ult i32 %x, %y
1412 %xz = sext i1 %gt to i32
1413 %yz = zext i1 %lt to i32
1414 %s = sub i32 %xz, %yz
1415 %r = lshr i32 %s, 31
1419 ; Negative test - wrong type
1421 define i32 @lshr_add_nonbool_sexts(i2 %x, i1 %y) {
1422 ; CHECK-LABEL: @lshr_add_nonbool_sexts(
1423 ; CHECK-NEXT: [[XS:%.*]] = sext i2 [[X:%.*]] to i32
1424 ; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1425 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1426 ; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
1427 ; CHECK-NEXT: ret i32 [[R]]
1429 %xs = sext i2 %x to i32
1430 %ys = sext i1 %y to i32
1431 %sub = add i32 %xs, %ys
1432 %r = lshr i32 %sub, 31
1436 ; Negative test - wrong demand
1438 define i32 @and31_add_sexts(i1 %x, i1 %y) {
1439 ; CHECK-LABEL: @and31_add_sexts(
1440 ; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32
1441 ; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1442 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1443 ; CHECK-NEXT: [[R:%.*]] = and i32 [[SUB]], 31
1444 ; CHECK-NEXT: ret i32 [[R]]
1446 %xs = sext i1 %x to i32
1447 %ys = sext i1 %y to i32
1448 %sub = add i32 %xs, %ys
1449 %r = and i32 %sub, 31
1453 define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {
1454 ; CHECK-LABEL: @lshr_add_use_sexts(
1455 ; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1456 ; CHECK-NEXT: store i32 [[YS]], ptr [[P:%.*]], align 4
1457 ; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y]]
1458 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32
1459 ; CHECK-NEXT: ret i32 [[R]]
1461 %xs = sext i1 %x to i32
1462 %ys = sext i1 %y to i32
1463 store i32 %ys, ptr %p
1464 %sub = add i32 %xs, %ys
1465 %r = lshr i32 %sub, 31
1469 define i32 @lshr_add_use_sexts_2(i1 %x, i1 %y, ptr %p) {
1470 ; CHECK-LABEL: @lshr_add_use_sexts_2(
1471 ; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32
1472 ; CHECK-NEXT: store i32 [[XS]], ptr [[P:%.*]], align 4
1473 ; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X]], [[Y:%.*]]
1474 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32
1475 ; CHECK-NEXT: ret i32 [[R]]
1477 %xs = sext i1 %x to i32
1478 store i32 %xs, ptr %p
1479 %ys = sext i1 %y to i32
1480 %sub = add i32 %xs, %ys
1481 %r = lshr i32 %sub, 31
1485 ; Negative test - extra use
1487 declare void @use_sexts(i32, i32)
1489 define i32 @lshr_add_use_sexts_both(i1 %x, i1 %y) {
1490 ; CHECK-LABEL: @lshr_add_use_sexts_both(
1491 ; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32
1492 ; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1493 ; CHECK-NEXT: call void @use_sexts(i32 [[XS]], i32 [[YS]])
1494 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1495 ; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
1496 ; CHECK-NEXT: ret i32 [[R]]
1498 %xs = sext i1 %x to i32
1499 %ys = sext i1 %y to i32
1500 call void @use_sexts(i32 %xs, i32 %ys)
1501 %sub = add i32 %xs, %ys
1502 %r = lshr i32 %sub, 31
1506 define i8 @add_like_or_t0(i8 %x) {
1507 ; CHECK-LABEL: @add_like_or_t0(
1508 ; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 4
1509 ; CHECK-NEXT: [[R:%.*]] = add i8 [[I0]], 57
1510 ; CHECK-NEXT: ret i8 [[R]]
1513 %i1 = or i8 %i0, 15 ; no common bits
1517 define i8 @add_like_or_n1(i8 %x) {
1518 ; CHECK-LABEL: @add_like_or_n1(
1519 ; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 4
1520 ; CHECK-NEXT: [[I1:%.*]] = or i8 [[I0]], 31
1521 ; CHECK-NEXT: [[R:%.*]] = add i8 [[I1]], 42
1522 ; CHECK-NEXT: ret i8 [[R]]
1525 %i1 = or i8 %i0, 31 ; 4'th bit might be common-set
1529 define i8 @add_like_or_t2_extrause(i8 %x) {
1530 ; CHECK-LABEL: @add_like_or_t2_extrause(
1531 ; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 4
1532 ; CHECK-NEXT: [[I1:%.*]] = or disjoint i8 [[I0]], 15
1533 ; CHECK-NEXT: call void @use(i8 [[I1]])
1534 ; CHECK-NEXT: [[R:%.*]] = add i8 [[I0]], 57
1535 ; CHECK-NEXT: ret i8 [[R]]
1538 %i1 = or i8 %i0, 15 ; no common bits
1539 call void @use(i8 %i1) ; extra use
1543 define i8 @fold_add_constant_preserve_nsw(i8 %x) {
1544 ; CHECK-LABEL: @fold_add_constant_preserve_nsw(
1545 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], -120
1546 ; CHECK-NEXT: ret i8 [[ADD]]
1548 %or = or disjoint i8 %x, -128
1549 %add = add nsw i8 %or, 8
1552 define i8 @fold_add_constant_no_nsw(i8 %x) {
1553 ; CHECK-LABEL: @fold_add_constant_no_nsw(
1554 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X:%.*]], 120
1555 ; CHECK-NEXT: ret i8 [[ADD]]
1557 %or = or disjoint i8 %x, -128
1558 %add = add nsw i8 %or, -8
1561 define i8 @fold_add_constant_preserve_nuw(i8 %x) {
1562 ; CHECK-LABEL: @fold_add_constant_preserve_nuw(
1563 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], -116
1564 ; CHECK-NEXT: ret i8 [[ADD]]
1566 %or = or disjoint i8 %x, 128
1567 %add = add nuw i8 %or, 12
1570 define i32 @sdiv_to_udiv(i32 %arg0, i32 %arg1) {
1571 ; CHECK-LABEL: @sdiv_to_udiv(
1572 ; CHECK-NEXT: [[T0:%.*]] = shl nuw nsw i32 [[ARG0:%.*]], 8
1573 ; CHECK-NEXT: [[T2:%.*]] = add nuw nsw i32 [[T0]], 6242049
1574 ; CHECK-NEXT: [[T3:%.*]] = udiv i32 [[T2]], 192
1575 ; CHECK-NEXT: ret i32 [[T3]]
1577 %t0 = shl nuw nsw i32 %arg0, 8
1578 %t1 = or disjoint i32 %t0, 1
1579 %t2 = add nuw nsw i32 %t1, 6242048
1580 %t3 = sdiv i32 %t2, 192
1584 define i8 @add_like_or_disjoint(i8 %x) {
1585 ; CHECK-LABEL: @add_like_or_disjoint(
1586 ; CHECK-NEXT: [[R:%.*]] = add i8 [[X:%.*]], 57
1587 ; CHECK-NEXT: ret i8 [[R]]
1589 %i1 = or disjoint i8 %x, 15
1594 define i8 @add_and_xor(i8 noundef %x, i8 %y) {
1595 ; CHECK-LABEL: @add_and_xor(
1596 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
1597 ; CHECK-NEXT: ret i8 [[ADD]]
1599 %xor = xor i8 %x, -1
1600 %and = and i8 %xor, %y
1601 %add = add i8 %and, %x
1605 define i8 @add_and_xor_wrong_const(i8 %x, i8 %y) {
1606 ; CHECK-LABEL: @add_and_xor_wrong_const(
1607 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -2
1608 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]]
1609 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], [[X]]
1610 ; CHECK-NEXT: ret i8 [[ADD]]
1612 %xor = xor i8 %x, -2
1613 %and = and i8 %xor, %y
1614 %add = add i8 %and, %x
1618 define i8 @add_and_xor_wrong_op(i8 %x, i8 %y, i8 %z) {
1619 ; CHECK-LABEL: @add_and_xor_wrong_op(
1620 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Z:%.*]], -1
1621 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]]
1622 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], [[X:%.*]]
1623 ; CHECK-NEXT: ret i8 [[ADD]]
1625 %xor = xor i8 %z, -1
1626 %and = and i8 %xor, %y
1627 %add = add i8 %and, %x
1631 define i8 @add_and_xor_commuted1(i8 noundef %x, i8 %_y) {
1632 ; CHECK-LABEL: @add_and_xor_commuted1(
1633 ; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1634 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X:%.*]]
1635 ; CHECK-NEXT: ret i8 [[ADD]]
1637 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1638 %xor = xor i8 %x, -1
1639 %and = and i8 %y, %xor
1640 %add = add i8 %and, %x
1644 define i8 @add_and_xor_commuted2(i8 noundef %_x, i8 %y) {
1645 ; CHECK-LABEL: @add_and_xor_commuted2(
1646 ; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1647 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y:%.*]]
1648 ; CHECK-NEXT: ret i8 [[ADD]]
1650 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1651 %xor = xor i8 %x, -1
1652 %and = and i8 %xor, %y
1653 %add = add i8 %x, %and
1657 define i8 @add_and_xor_commuted3(i8 noundef %_x, i8 %_y) {
1658 ; CHECK-LABEL: @add_and_xor_commuted3(
1659 ; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1660 ; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1661 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]]
1662 ; CHECK-NEXT: ret i8 [[ADD]]
1664 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1665 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1666 %xor = xor i8 %x, -1
1667 %and = and i8 %y, %xor
1668 %add = add i8 %x, %and
1672 define i8 @add_and_xor_extra_use(i8 noundef %x, i8 %y) {
1673 ; CHECK-LABEL: @add_and_xor_extra_use(
1674 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1
1675 ; CHECK-NEXT: call void @use(i8 [[XOR]])
1676 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]]
1677 ; CHECK-NEXT: call void @use(i8 [[AND]])
1678 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]
1679 ; CHECK-NEXT: ret i8 [[ADD]]
1681 %xor = xor i8 %x, -1
1682 call void @use(i8 %xor)
1683 %and = and i8 %xor, %y
1684 call void @use(i8 %and)
1685 %add = add i8 %and, %x
1689 define i8 @add_xor_and_const(i8 noundef %x) {
1690 ; CHECK-LABEL: @add_xor_and_const(
1691 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X:%.*]], 42
1692 ; CHECK-NEXT: ret i8 [[ADD]]
1694 %and = and i8 %x, 42
1695 %xor = xor i8 %and, 42
1696 %add = add i8 %xor, %x
1700 define i8 @add_xor_and_const_wrong_const(i8 %x) {
1701 ; CHECK-LABEL: @add_xor_and_const_wrong_const(
1702 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 42
1703 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], 88
1704 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[X]]
1705 ; CHECK-NEXT: ret i8 [[ADD]]
1707 %and = and i8 %x, 42
1708 %xor = xor i8 %and, 88
1709 %add = add i8 %xor, %x
1713 define i8 @add_xor_and_var(i8 noundef %x, i8 noundef %y) {
1714 ; CHECK-LABEL: @add_xor_and_var(
1715 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1716 ; CHECK-NEXT: call void @use(i8 [[AND]])
1717 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]
1718 ; CHECK-NEXT: ret i8 [[ADD]]
1720 %and = and i8 %x, %y
1721 call void @use(i8 %and)
1722 %xor = xor i8 %and, %y
1723 %add = add i8 %xor, %x
1727 define i8 @add_xor_and_var_wrong_op1(i8 %x, i8 %y, i8 %z) {
1728 ; CHECK-LABEL: @add_xor_and_var_wrong_op1(
1729 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1730 ; CHECK-NEXT: call void @use(i8 [[AND]])
1731 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Z:%.*]]
1732 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[X]]
1733 ; CHECK-NEXT: ret i8 [[ADD]]
1735 %and = and i8 %x, %y
1736 call void @use(i8 %and)
1737 %xor = xor i8 %and, %z
1738 %add = add i8 %xor, %x
1742 define i8 @add_xor_and_var_wrong_op2(i8 %x, i8 %y, i8 %z) {
1743 ; CHECK-LABEL: @add_xor_and_var_wrong_op2(
1744 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1745 ; CHECK-NEXT: call void @use(i8 [[AND]])
1746 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Y]]
1747 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[Z:%.*]]
1748 ; CHECK-NEXT: ret i8 [[ADD]]
1750 %and = and i8 %x, %y
1751 call void @use(i8 %and)
1752 %xor = xor i8 %and, %y
1753 %add = add i8 %xor, %z
1757 define i8 @add_xor_and_var_commuted1(i8 noundef %x, i8 noundef %y) {
1758 ; CHECK-LABEL: @add_xor_and_var_commuted1(
1759 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y:%.*]], [[X:%.*]]
1760 ; CHECK-NEXT: call void @use(i8 [[AND]])
1761 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]
1762 ; CHECK-NEXT: ret i8 [[ADD]]
1764 %and = and i8 %y, %x
1765 call void @use(i8 %and)
1766 %xor = xor i8 %and, %y
1767 %add = add i8 %xor, %x
1771 define i8 @add_xor_and_var_commuted2(i8 noundef %_x, i8 noundef %_y) {
1772 ; CHECK-LABEL: @add_xor_and_var_commuted2(
1773 ; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1774 ; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1775 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]]
1776 ; CHECK-NEXT: call void @use(i8 [[AND]])
1777 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]
1778 ; CHECK-NEXT: ret i8 [[ADD]]
1780 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1781 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1782 %and = and i8 %x, %y
1783 call void @use(i8 %and)
1784 %xor = xor i8 %y, %and
1785 %add = add i8 %xor, %x
1789 define i8 @add_xor_and_var_commuted3(i8 noundef %x, i8 noundef %_y) {
1790 ; CHECK-LABEL: @add_xor_and_var_commuted3(
1791 ; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1792 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X:%.*]]
1793 ; CHECK-NEXT: call void @use(i8 [[AND]])
1794 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]
1795 ; CHECK-NEXT: ret i8 [[ADD]]
1797 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1798 %and = and i8 %y, %x
1799 call void @use(i8 %and)
1800 %xor = xor i8 %y, %and
1801 %add = add i8 %xor, %x
1805 define i8 @add_xor_and_var_commuted4(i8 noundef %_x, i8 noundef %y) {
1806 ; CHECK-LABEL: @add_xor_and_var_commuted4(
1807 ; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1808 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y:%.*]]
1809 ; CHECK-NEXT: call void @use(i8 [[AND]])
1810 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]]
1811 ; CHECK-NEXT: ret i8 [[ADD]]
1813 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1814 %and = and i8 %x, %y
1815 call void @use(i8 %and)
1816 %xor = xor i8 %and, %y
1817 %add = add i8 %x, %xor
1821 define i8 @add_xor_and_var_commuted5(i8 noundef %_x, i8 noundef %_y) {
1822 ; CHECK-LABEL: @add_xor_and_var_commuted5(
1823 ; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1824 ; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1825 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X]]
1826 ; CHECK-NEXT: call void @use(i8 [[AND]])
1827 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]]
1828 ; CHECK-NEXT: ret i8 [[ADD]]
1830 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1831 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1832 %and = and i8 %y, %x
1833 call void @use(i8 %and)
1834 %xor = xor i8 %and, %y
1835 %add = add i8 %x, %xor
1839 define i8 @add_xor_and_var_commuted6(i8 noundef %_x, i8 noundef %_y) {
1840 ; CHECK-LABEL: @add_xor_and_var_commuted6(
1841 ; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1842 ; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1843 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]]
1844 ; CHECK-NEXT: call void @use(i8 [[AND]])
1845 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]]
1846 ; CHECK-NEXT: ret i8 [[ADD]]
1848 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1849 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1850 %and = and i8 %x, %y
1851 call void @use(i8 %and)
1852 %xor = xor i8 %y, %and
1853 %add = add i8 %x, %xor
1857 define i8 @add_xor_and_var_commuted7(i8 noundef %_x, i8 noundef %_y) {
1858 ; CHECK-LABEL: @add_xor_and_var_commuted7(
1859 ; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1860 ; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1861 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X]]
1862 ; CHECK-NEXT: call void @use(i8 [[AND]])
1863 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]]
1864 ; CHECK-NEXT: ret i8 [[ADD]]
1866 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1867 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1868 %and = and i8 %y, %x
1869 call void @use(i8 %and)
1870 %xor = xor i8 %y, %and
1871 %add = add i8 %x, %xor
1875 define i8 @add_xor_and_var_extra_use(i8 noundef %x, i8 noundef %y) {
1876 ; CHECK-LABEL: @add_xor_and_var_extra_use(
1877 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1878 ; CHECK-NEXT: call void @use(i8 [[AND]])
1879 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Y]]
1880 ; CHECK-NEXT: call void @use(i8 [[XOR]])
1881 ; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]
1882 ; CHECK-NEXT: ret i8 [[ADD]]
1884 %and = and i8 %x, %y
1885 call void @use(i8 %and)
1886 %xor = xor i8 %and, %y
1887 call void @use(i8 %xor)
1888 %add = add i8 %xor, %x
1892 define i32 @add_add_add(i32 %A, i32 %B, i32 %C, i32 %D) {
1893 ; CHECK-LABEL: @add_add_add(
1894 ; CHECK-NEXT: [[E:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
1895 ; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]]
1896 ; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1897 ; CHECK-NEXT: ret i32 [[G]]
1905 define i32 @add_add_add_commute1(i32 %A, i32 %B, i32 %C, i32 %D) {
1906 ; CHECK-LABEL: @add_add_add_commute1(
1907 ; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
1908 ; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]]
1909 ; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1910 ; CHECK-NEXT: ret i32 [[G]]
1918 define i32 @add_add_add_commute2(i32 %A, i32 %B, i32 %C, i32 %D) {
1919 ; CHECK-LABEL: @add_add_add_commute2(
1920 ; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
1921 ; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]]
1922 ; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1923 ; CHECK-NEXT: ret i32 [[G]]
1931 define i32 @add_add_add_commute3(i32 %A, i32 %B, i32 %C, i32 %D) {
1932 ; CHECK-LABEL: @add_add_add_commute3(
1933 ; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
1934 ; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]]
1935 ; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1936 ; CHECK-NEXT: ret i32 [[G]]
1944 ; x * y + x --> (y + 1) * x
1946 define i8 @mul_add_common_factor_commute1(i8 %x, i8 %y) {
1947 ; CHECK-LABEL: @mul_add_common_factor_commute1(
1948 ; CHECK-NEXT: [[X1:%.*]] = add i8 [[Y:%.*]], 1
1949 ; CHECK-NEXT: [[A:%.*]] = mul i8 [[X1]], [[X:%.*]]
1950 ; CHECK-NEXT: ret i8 [[A]]
1952 %m = mul nsw i8 %x, %y
1953 %a = add nsw i8 %m, %x
1957 define <2 x i8> @mul_add_common_factor_commute2(<2 x i8> %x, <2 x i8> %y) {
1958 ; CHECK-LABEL: @mul_add_common_factor_commute2(
1959 ; CHECK-NEXT: [[M1:%.*]] = add <2 x i8> [[Y:%.*]], <i8 1, i8 1>
1960 ; CHECK-NEXT: [[A:%.*]] = mul nuw <2 x i8> [[M1]], [[X:%.*]]
1961 ; CHECK-NEXT: ret <2 x i8> [[A]]
1963 %m = mul nuw <2 x i8> %y, %x
1964 %a = add nuw <2 x i8> %m, %x
1968 define i8 @mul_add_common_factor_commute3(i8 %p, i8 %y) {
1969 ; CHECK-LABEL: @mul_add_common_factor_commute3(
1970 ; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
1971 ; CHECK-NEXT: [[M1:%.*]] = add i8 [[Y:%.*]], 1
1972 ; CHECK-NEXT: [[A:%.*]] = mul i8 [[X]], [[M1]]
1973 ; CHECK-NEXT: ret i8 [[A]]
1975 %x = mul i8 %p, %p ; thwart complexity-based canonicalization
1976 %m = mul nuw i8 %x, %y
1977 %a = add nsw i8 %x, %m
1981 define i8 @mul_add_common_factor_commute4(i8 %p, i8 %q) {
1982 ; CHECK-LABEL: @mul_add_common_factor_commute4(
1983 ; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
1984 ; CHECK-NEXT: [[Y:%.*]] = mul i8 [[Q:%.*]], [[Q]]
1985 ; CHECK-NEXT: [[M1:%.*]] = add i8 [[Y]], 1
1986 ; CHECK-NEXT: [[A:%.*]] = mul i8 [[X]], [[M1]]
1987 ; CHECK-NEXT: ret i8 [[A]]
1989 %x = mul i8 %p, %p ; thwart complexity-based canonicalization
1990 %y = mul i8 %q, %q ; thwart complexity-based canonicalization
1991 %m = mul nsw i8 %y, %x
1992 %a = add nuw i8 %x, %m
1996 ; negative test - uses
1998 define i8 @mul_add_common_factor_use(i8 %x, i8 %y) {
1999 ; CHECK-LABEL: @mul_add_common_factor_use(
2000 ; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]
2001 ; CHECK-NEXT: call void @use(i8 [[M]])
2002 ; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], [[X]]
2003 ; CHECK-NEXT: ret i8 [[A]]
2006 call void @use(i8 %m)
2011 define i8 @not_mul(i8 %x) {
2012 ; CHECK-LABEL: @not_mul(
2013 ; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], -41
2014 ; CHECK-NEXT: [[PLUSX:%.*]] = add i8 [[TMP1]], -1
2015 ; CHECK-NEXT: ret i8 [[PLUSX]]
2017 %mul = mul nsw i8 %x, 42
2018 %not = xor i8 %mul, -1
2019 %plusx = add nsw i8 %not, %x
2023 define <2 x i8> @not_mul_commute(<2 x i8> %p) {
2024 ; CHECK-LABEL: @not_mul_commute(
2025 ; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
2026 ; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i8> [[X]], <i8 43, i8 43>
2027 ; CHECK-NEXT: [[PLUSX:%.*]] = add <2 x i8> [[TMP1]], <i8 -1, i8 -1>
2028 ; CHECK-NEXT: ret <2 x i8> [[PLUSX]]
2030 %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
2031 %mul = mul nuw <2 x i8> %x, <i8 -42, i8 -42>
2032 %not = xor <2 x i8> %mul, <i8 -1, i8 -1>
2033 %plusx = add nuw <2 x i8> %x, %not
2037 ; negative test - need common operand
2039 define i8 @not_mul_wrong_op(i8 %x, i8 %y) {
2040 ; CHECK-LABEL: @not_mul_wrong_op(
2041 ; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 42
2042 ; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[MUL]], -1
2043 ; CHECK-NEXT: [[PLUSX:%.*]] = add i8 [[NOT]], [[Y:%.*]]
2044 ; CHECK-NEXT: ret i8 [[PLUSX]]
2046 %mul = mul i8 %x, 42
2047 %not = xor i8 %mul, -1
2048 %plusx = add i8 %not, %y
2052 ; negative test - avoid creating an extra mul
2054 define i8 @not_mul_use1(i8 %x) {
2055 ; CHECK-LABEL: @not_mul_use1(
2056 ; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[X:%.*]], 42
2057 ; CHECK-NEXT: call void @use(i8 [[MUL]])
2058 ; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[MUL]], -1
2059 ; CHECK-NEXT: [[PLUSX:%.*]] = add nsw i8 [[NOT]], [[X]]
2060 ; CHECK-NEXT: ret i8 [[PLUSX]]
2062 %mul = mul nsw i8 %x, 42
2063 call void @use(i8 %mul)
2064 %not = xor i8 %mul, -1
2065 %plusx = add nsw i8 %not, %x
2069 ; negative test - too many instructions
2071 define i8 @not_mul_use2(i8 %x) {
2072 ; CHECK-LABEL: @not_mul_use2(
2073 ; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 42
2074 ; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[MUL]], -1
2075 ; CHECK-NEXT: call void @use(i8 [[NOT]])
2076 ; CHECK-NEXT: [[PLUSX:%.*]] = add i8 [[NOT]], [[X]]
2077 ; CHECK-NEXT: ret i8 [[PLUSX]]
2079 %mul = mul i8 %x, 42
2080 %not = xor i8 %mul, -1
2081 call void @use(i8 %not)
2082 %plusx = add i8 %not, %x
2086 define i8 @full_ashr_inc(i8 %x) {
2087 ; CHECK-LABEL: @full_ashr_inc(
2088 ; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
2089 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i8
2090 ; CHECK-NEXT: ret i8 [[R]]
2097 define <2 x i6> @full_ashr_inc_vec(<2 x i6> %x) {
2098 ; CHECK-LABEL: @full_ashr_inc_vec(
2099 ; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt <2 x i6> [[X:%.*]], <i6 -1, i6 -1>
2100 ; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i6>
2101 ; CHECK-NEXT: ret <2 x i6> [[R]]
2103 %a = ashr <2 x i6> %x, <i6 5, i6 poison>
2104 %r = add <2 x i6> %a, <i6 1, i6 1>
2108 ; negative test - extra use
2110 define i8 @full_ashr_inc_use(i8 %x) {
2111 ; CHECK-LABEL: @full_ashr_inc_use(
2112 ; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 7
2113 ; CHECK-NEXT: call void @use(i8 [[A]])
2114 ; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[A]], 1
2115 ; CHECK-NEXT: ret i8 [[R]]
2118 call void @use(i8 %a)
2123 ; negative test - wrong shift amount
2125 define i8 @not_full_ashr_inc(i8 %x) {
2126 ; CHECK-LABEL: @not_full_ashr_inc(
2127 ; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 6
2128 ; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[A]], 1
2129 ; CHECK-NEXT: ret i8 [[R]]
2136 ; negative test - wrong add amount
2138 define i8 @full_ashr_not_inc(i8 %x) {
2139 ; CHECK-LABEL: @full_ashr_not_inc(
2140 ; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 7
2141 ; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[A]], 2
2142 ; CHECK-NEXT: ret i8 [[R]]
2149 define i8 @select_negate_or_zero(i1 %b, i8 %x, i8 %y) {
2150 ; CHECK-LABEL: @select_negate_or_zero(
2151 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[X:%.*]]
2152 ; CHECK-NEXT: [[ADD1:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2153 ; CHECK-NEXT: ret i8 [[ADD1]]
2155 %negx = sub i8 0, %x
2156 %sel = select i1 %b, i8 0, i8 %negx
2157 %add = add i8 %sel, %y
2161 ; commuted add operands - same result
2163 define <2 x i8> @select_negate_or_zero_commute(<2 x i1> %b, <2 x i8> %x, <2 x i8> %p) {
2164 ; CHECK-LABEL: @select_negate_or_zero_commute(
2165 ; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
2166 ; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> zeroinitializer, <2 x i8> [[X:%.*]]
2167 ; CHECK-NEXT: [[ADD1:%.*]] = sub <2 x i8> [[Y]], [[TMP1]]
2168 ; CHECK-NEXT: ret <2 x i8> [[ADD1]]
2170 %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
2171 %negx = sub <2 x i8> <i8 poison, i8 0>, %x
2172 %sel = select <2 x i1> %b, <2 x i8> <i8 poison, i8 0>, <2 x i8> %negx
2173 %add = add <2 x i8> %y, %sel
2177 ; swapped select operands and extra use are ok
2179 define i8 @select_negate_or_zero_swap(i1 %b, i8 %x, i8 %y) {
2180 ; CHECK-LABEL: @select_negate_or_zero_swap(
2181 ; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
2182 ; CHECK-NEXT: call void @use(i8 [[NEGX]])
2183 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i8 [[X]], i8 0
2184 ; CHECK-NEXT: [[ADD1:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2185 ; CHECK-NEXT: ret i8 [[ADD1]]
2187 %negx = sub i8 0, %x
2188 call void @use(i8 %negx)
2189 %sel = select i1 %b, i8 %negx, i8 0
2190 %add = add i8 %sel, %y
2194 ; commuted add operands - same result
2196 define i8 @select_negate_or_zero_swap_commute(i1 %b, i8 %x, i8 %p) {
2197 ; CHECK-LABEL: @select_negate_or_zero_swap_commute(
2198 ; CHECK-NEXT: [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]
2199 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i8 [[X:%.*]], i8 0
2200 ; CHECK-NEXT: [[ADD1:%.*]] = sub i8 [[Y]], [[TMP1]]
2201 ; CHECK-NEXT: ret i8 [[ADD1]]
2203 %y = mul i8 %p, %p ; thwart complexity-based canonicalization
2204 %negx = sub i8 0, %x
2205 %sel = select i1 %b, i8 %negx, i8 0
2206 %add = add i8 %y, %sel
2210 ; negative test - one arm of the select must simplify
2212 define i8 @select_negate_or_nonzero(i1 %b, i8 %x, i8 %y) {
2213 ; CHECK-LABEL: @select_negate_or_nonzero(
2214 ; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
2215 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 42, i8 [[NEGX]]
2216 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]
2217 ; CHECK-NEXT: ret i8 [[ADD]]
2219 %negx = sub i8 0, %x
2220 %sel = select i1 %b, i8 42, i8 %negx
2221 %add = add i8 %sel, %y
2225 ; negative test - must have a negate, not any subtract
2227 define i8 @select_nonnegate_or_zero(i1 %b, i8 %x, i8 %y) {
2228 ; CHECK-LABEL: @select_nonnegate_or_zero(
2229 ; CHECK-NEXT: [[NEGX:%.*]] = sub i8 42, [[X:%.*]]
2230 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[NEGX]]
2231 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]
2232 ; CHECK-NEXT: ret i8 [[ADD]]
2234 %negx = sub i8 42, %x
2235 %sel = select i1 %b, i8 0, i8 %negx
2236 %add = add i8 %sel, %y
2240 ; negative test - don't create an extra instruction
2242 define i8 @select_negate_or_nonzero_use(i1 %b, i8 %x, i8 %y) {
2243 ; CHECK-LABEL: @select_negate_or_nonzero_use(
2244 ; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
2245 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[NEGX]]
2246 ; CHECK-NEXT: call void @use(i8 [[SEL]])
2247 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]
2248 ; CHECK-NEXT: ret i8 [[ADD]]
2250 %negx = sub i8 0, %x
2251 %sel = select i1 %b, i8 0, i8 %negx
2252 call void @use(i8 %sel)
2253 %add = add i8 %sel, %y
2257 ; extra reduction because y + ~y -> -1
2259 define i5 @select_negate_not(i1 %b, i5 %x, i5 %y) {
2260 ; CHECK-LABEL: @select_negate_not(
2261 ; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y:%.*]], [[X:%.*]]
2262 ; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 -1, i5 [[TMP1]]
2263 ; CHECK-NEXT: ret i5 [[ADD1]]
2265 %negx = sub i5 0, %x
2266 %noty = xor i5 %y, -1
2267 %sel = select i1 %b, i5 %noty, i5 %negx
2268 %add = add i5 %sel, %y
2272 define i5 @select_negate_not_commute(i1 %b, i5 %x, i5 %p) {
2273 ; CHECK-LABEL: @select_negate_not_commute(
2274 ; CHECK-NEXT: [[Y:%.*]] = mul i5 [[P:%.*]], [[P]]
2275 ; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y]], [[X:%.*]]
2276 ; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 -1, i5 [[TMP1]]
2277 ; CHECK-NEXT: ret i5 [[ADD1]]
2279 %y = mul i5 %p, %p ; thwart complexity-based canonicalization
2280 %negx = sub i5 0, %x
2281 %noty = xor i5 %y, -1
2282 %sel = select i1 %b, i5 %noty, i5 %negx
2283 %add = add i5 %y, %sel
2287 define i5 @select_negate_not_swap(i1 %b, i5 %x, i5 %y) {
2288 ; CHECK-LABEL: @select_negate_not_swap(
2289 ; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y:%.*]], [[X:%.*]]
2290 ; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 [[TMP1]], i5 -1
2291 ; CHECK-NEXT: ret i5 [[ADD1]]
2293 %negx = sub i5 0, %x
2294 %noty = xor i5 %y, -1
2295 %sel = select i1 %b, i5 %negx, i5 %noty
2296 %add = add i5 %sel, %y
2300 define i5 @select_negate_not_swap_commute(i1 %b, i5 %x, i5 %p) {
2301 ; CHECK-LABEL: @select_negate_not_swap_commute(
2302 ; CHECK-NEXT: [[Y:%.*]] = mul i5 [[P:%.*]], [[P]]
2303 ; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y]], [[X:%.*]]
2304 ; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 [[TMP1]], i5 -1
2305 ; CHECK-NEXT: ret i5 [[ADD1]]
2307 %y = mul i5 %p, %p ; thwart complexity-based canonicalization
2308 %negx = sub i5 0, %x
2309 %noty = xor i5 %y, -1
2310 %sel = select i1 %b, i5 %negx, i5 %noty
2311 %add = add i5 %y, %sel
2315 define i32 @add_select_sub_both_arms_simplify(i1 %b, i32 %a) {
2316 ; CHECK-LABEL: @add_select_sub_both_arms_simplify(
2317 ; CHECK-NEXT: [[ADD:%.*]] = select i1 [[B:%.*]], i32 [[A:%.*]], i32 99
2318 ; CHECK-NEXT: ret i32 [[ADD]]
2320 %sub = sub i32 99, %a
2321 %sel = select i1 %b, i32 0, i32 %sub
2322 %add = add i32 %sel, %a
2326 define <2 x i8> @add_select_sub_both_arms_simplify_swap(<2 x i1> %b, <2 x i8> %a) {
2327 ; CHECK-LABEL: @add_select_sub_both_arms_simplify_swap(
2328 ; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> <i8 42, i8 99>, <2 x i8> [[A:%.*]]
2329 ; CHECK-NEXT: ret <2 x i8> [[ADD]]
2331 %sub = sub <2 x i8> <i8 42, i8 99>, %a
2332 %sel = select <2 x i1> %b, <2 x i8> %sub, <2 x i8> zeroinitializer
2333 %add = add <2 x i8> %sel, %a
2337 define i8 @add_select_sub_both_arms_simplify_use1(i1 %b, i8 %a) {
2338 ; CHECK-LABEL: @add_select_sub_both_arms_simplify_use1(
2339 ; CHECK-NEXT: [[SUB:%.*]] = sub i8 42, [[A:%.*]]
2340 ; CHECK-NEXT: call void @use(i8 [[SUB]])
2341 ; CHECK-NEXT: [[ADD:%.*]] = select i1 [[B:%.*]], i8 [[A]], i8 42
2342 ; CHECK-NEXT: ret i8 [[ADD]]
2344 %sub = sub i8 42, %a
2345 call void @use(i8 %sub)
2346 %sel = select i1 %b, i8 0, i8 %sub
2347 %add = add i8 %sel, %a
2351 define i8 @add_select_sub_both_arms_simplify_use2(i1 %b, i8 %a) {
2352 ; CHECK-LABEL: @add_select_sub_both_arms_simplify_use2(
2353 ; CHECK-NEXT: [[SUB:%.*]] = sub i8 42, [[A:%.*]]
2354 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[SUB]]
2355 ; CHECK-NEXT: call void @use(i8 [[SEL]])
2356 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[A]]
2357 ; CHECK-NEXT: ret i8 [[ADD]]
2359 %sub = sub i8 42, %a
2360 %sel = select i1 %b, i8 0, i8 %sub
2361 call void @use(i8 %sel)
2362 %add = add i8 %sel, %a
2366 define i5 @demand_low_bits_uses(i8 %x, i8 %y) {
2367 ; CHECK-LABEL: @demand_low_bits_uses(
2368 ; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 5
2369 ; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2370 ; CHECK-NEXT: call void @use(i8 [[A]])
2371 ; CHECK-NEXT: [[R:%.*]] = trunc i8 [[Y]] to i5
2372 ; CHECK-NEXT: ret i5 [[R]]
2374 %m = mul i8 %x, -32 ; 0xE0
2376 call void @use(i8 %a)
2377 %r = trunc i8 %a to i5
2381 ; negative test - demands one more bit
2383 define i6 @demand_low_bits_uses_extra_bit(i8 %x, i8 %y) {
2384 ; CHECK-LABEL: @demand_low_bits_uses_extra_bit(
2385 ; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 5
2386 ; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2387 ; CHECK-NEXT: call void @use(i8 [[A]])
2388 ; CHECK-NEXT: [[R:%.*]] = trunc i8 [[A]] to i6
2389 ; CHECK-NEXT: ret i6 [[R]]
2391 %m = mul i8 %x, -32 ; 0xE0
2393 call void @use(i8 %a)
2394 %r = trunc i8 %a to i6
2398 define i8 @demand_low_bits_uses_commute(i8 %x, i8 %p, i8 %z) {
2399 ; CHECK-LABEL: @demand_low_bits_uses_commute(
2400 ; CHECK-NEXT: [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]
2401 ; CHECK-NEXT: [[M:%.*]] = and i8 [[X:%.*]], -64
2402 ; CHECK-NEXT: [[A:%.*]] = add i8 [[Y]], [[M]]
2403 ; CHECK-NEXT: call void @use(i8 [[A]])
2404 ; CHECK-NEXT: [[S:%.*]] = sub i8 [[Y]], [[Z:%.*]]
2405 ; CHECK-NEXT: [[R:%.*]] = shl i8 [[S]], 2
2406 ; CHECK-NEXT: ret i8 [[R]]
2408 %y = mul i8 %p, %p ; thwart complexity-based canonicalization
2409 %m = and i8 %x, -64 ; 0xC0
2411 call void @use(i8 %a)
2417 ; negative test - demands one more bit
2419 define i8 @demand_low_bits_uses_commute_extra_bit(i8 %x, i8 %p, i8 %z) {
2420 ; CHECK-LABEL: @demand_low_bits_uses_commute_extra_bit(
2421 ; CHECK-NEXT: [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]
2422 ; CHECK-NEXT: [[M:%.*]] = and i8 [[X:%.*]], -64
2423 ; CHECK-NEXT: [[A:%.*]] = add i8 [[Y]], [[M]]
2424 ; CHECK-NEXT: call void @use(i8 [[A]])
2425 ; CHECK-NEXT: [[S:%.*]] = sub i8 [[A]], [[Z:%.*]]
2426 ; CHECK-NEXT: [[R:%.*]] = shl i8 [[S]], 1
2427 ; CHECK-NEXT: ret i8 [[R]]
2429 %y = mul i8 %p, %p ; thwart complexity-based canonicalization
2430 %m = and i8 %x, -64 ; 0xC0
2432 call void @use(i8 %a)
2438 define { i64, i64 } @PR57576(i64 noundef %x, i64 noundef %y, i64 noundef %z, i64 noundef %w) {
2439 ; CHECK-LABEL: @PR57576(
2440 ; CHECK-NEXT: [[ZX:%.*]] = zext i64 [[X:%.*]] to i128
2441 ; CHECK-NEXT: [[ZY:%.*]] = zext i64 [[Y:%.*]] to i128
2442 ; CHECK-NEXT: [[ZZ:%.*]] = zext i64 [[Z:%.*]] to i128
2443 ; CHECK-NEXT: [[SHY:%.*]] = shl nuw i128 [[ZY]], 64
2444 ; CHECK-NEXT: [[XY:%.*]] = or disjoint i128 [[SHY]], [[ZX]]
2445 ; CHECK-NEXT: [[SUB:%.*]] = sub i128 [[XY]], [[ZZ]]
2446 ; CHECK-NEXT: [[T:%.*]] = trunc i128 [[SUB]] to i64
2447 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i128 [[SUB]], 64
2448 ; CHECK-NEXT: [[DOTTR:%.*]] = trunc nuw i128 [[TMP1]] to i64
2449 ; CHECK-NEXT: [[DOTNARROW:%.*]] = sub i64 [[DOTTR]], [[W:%.*]]
2450 ; CHECK-NEXT: [[R1:%.*]] = insertvalue { i64, i64 } poison, i64 [[T]], 0
2451 ; CHECK-NEXT: [[R2:%.*]] = insertvalue { i64, i64 } [[R1]], i64 [[DOTNARROW]], 1
2452 ; CHECK-NEXT: ret { i64, i64 } [[R2]]
2454 %zx = zext i64 %x to i128
2455 %zy = zext i64 %y to i128
2456 %zw = zext i64 %w to i128
2457 %zz = zext i64 %z to i128
2458 %shy = shl nuw i128 %zy, 64
2459 %mw = mul i128 %zw, -18446744073709551616
2460 %xy = or i128 %shy, %zx
2461 %sub = sub i128 %xy, %zz
2462 %add = add i128 %sub, %mw
2463 %t = trunc i128 %add to i64
2464 %h = lshr i128 %add, 64
2465 %t2 = trunc i128 %h to i64
2466 %r1 = insertvalue { i64, i64 } poison, i64 %t, 0
2467 %r2 = insertvalue { i64, i64 } %r1, i64 %t2, 1
2468 ret { i64, i64 } %r2
2471 define i8 @mul_negpow2(i8 %x, i8 %y) {
2472 ; CHECK-LABEL: @mul_negpow2(
2473 ; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 1
2474 ; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2475 ; CHECK-NEXT: ret i8 [[A]]
2482 define <2 x i8> @mul_negpow2_commute_vec(<2 x i8> %x, <2 x i8> %p) {
2483 ; CHECK-LABEL: @mul_negpow2_commute_vec(
2484 ; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
2485 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 3, i8 3>
2486 ; CHECK-NEXT: [[A:%.*]] = sub <2 x i8> [[Y]], [[TMP1]]
2487 ; CHECK-NEXT: ret <2 x i8> [[A]]
2489 %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
2490 %m = mul <2 x i8> %x, <i8 -8, i8 -8>
2491 %a = add <2 x i8> %y, %m
2495 ; negative test - extra use
2497 define i8 @mul_negpow2_use(i8 %x) {
2498 ; CHECK-LABEL: @mul_negpow2_use(
2499 ; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -2
2500 ; CHECK-NEXT: call void @use(i8 [[M]])
2501 ; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], 42
2502 ; CHECK-NEXT: ret i8 [[A]]
2505 call void @use(i8 %m)
2510 ; negative test - not negative-power-of-2 multiplier
2512 define i8 @mul_not_negpow2(i8 %x) {
2513 ; CHECK-LABEL: @mul_not_negpow2(
2514 ; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -3
2515 ; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], 42
2516 ; CHECK-NEXT: ret i8 [[A]]
2523 define i16 @add_sub_zext(i8 %x, i8 %y) {
2524 ; CHECK-LABEL: @add_sub_zext(
2525 ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i16
2526 ; CHECK-NEXT: ret i16 [[TMP1]]
2528 %1 = sub nuw i8 %y, %x
2529 %2 = zext i8 %1 to i16
2530 %3 = zext i8 %x to i16
2535 define i16 @add_commute_sub_zext(i8 %x, i8 %y) {
2536 ; CHECK-LABEL: @add_commute_sub_zext(
2537 ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i16
2538 ; CHECK-NEXT: ret i16 [[TMP1]]
2540 %1 = sub nuw i8 %y, %x
2541 %2 = zext i8 %1 to i16
2542 %3 = zext i8 %x to i16
2547 define <2 x i8> @add_sub_2xi5_zext(<2 x i5> %x, <2 x i5> %y) {
2548 ; CHECK-LABEL: @add_sub_2xi5_zext(
2549 ; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i5> [[Y:%.*]] to <2 x i8>
2550 ; CHECK-NEXT: ret <2 x i8> [[TMP1]]
2552 %1 = sub nuw <2 x i5> %y, %x
2553 %2 = zext <2 x i5> %1 to <2 x i8>
2554 %3 = zext <2 x i5> %x to <2 x i8>
2555 %4 = add <2 x i8> %3, %2
2560 define i3 @add_commute_sub_i2_zext_i3(i2 %x, i2 %y) {
2561 ; CHECK-LABEL: @add_commute_sub_i2_zext_i3(
2562 ; CHECK-NEXT: [[TMP1:%.*]] = zext i2 [[Y:%.*]] to i3
2563 ; CHECK-NEXT: ret i3 [[TMP1]]
2565 %1 = sub nuw i2 %y, %x
2566 %2 = zext i2 %1 to i3
2567 %3 = zext i2 %x to i3
2572 define i16 @add_sub_use_zext(i8 %x, i8 %y) {
2573 ; CHECK-LABEL: @add_sub_use_zext(
2574 ; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i8 [[Y:%.*]], [[X:%.*]]
2575 ; CHECK-NEXT: call void @use(i8 [[TMP1]])
2576 ; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[Y]] to i16
2577 ; CHECK-NEXT: ret i16 [[TMP2]]
2579 %1 = sub nuw i8 %y, %x
2580 call void @use(i8 %1)
2581 %2 = zext i8 %1 to i16
2582 %3 = zext i8 %x to i16
2587 ; Negative test: x - y + x != y
2588 define i16 @add_sub_commute_zext(i8 %x, i8 %y) {
2589 ; CHECK-LABEL: @add_sub_commute_zext(
2590 ; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]]
2591 ; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i16
2592 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[X]] to i16
2593 ; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i16 [[TMP2]], [[TMP3]]
2594 ; CHECK-NEXT: ret i16 [[TMP4]]
2596 %1 = sub nuw i8 %x, %y
2597 %2 = zext i8 %1 to i16
2598 %3 = zext i8 %x to i16
2603 ; Negative test: no nuw flags
2604 define i16 @add_no_nuw_sub_zext(i8 %x, i8 %y) {
2605 ; CHECK-LABEL: @add_no_nuw_sub_zext(
2606 ; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]]
2607 ; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i16
2608 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[X]] to i16
2609 ; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i16 [[TMP3]], [[TMP2]]
2610 ; CHECK-NEXT: ret i16 [[TMP4]]
2613 %2 = zext i8 %1 to i16
2614 %3 = zext i8 %x to i16
2619 define i16 @add_no_nuw_sub_commute_zext(i8 %x, i8 %y) {
2620 ; CHECK-LABEL: @add_no_nuw_sub_commute_zext(
2621 ; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
2622 ; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i16
2623 ; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[X]] to i16
2624 ; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i16 [[TMP3]], [[TMP2]]
2625 ; CHECK-NEXT: ret i16 [[TMP4]]
2628 %2 = zext i8 %1 to i16
2629 %3 = zext i8 %x to i16
2634 define i16 @add_sub_zext_constant(i8 %x) {
2635 ; CHECK-LABEL: @add_sub_zext_constant(
2636 ; CHECK-NEXT: ret i16 254
2638 %1 = sub nuw i8 254, %x
2639 %2 = zext i8 %1 to i16
2640 %3 = zext i8 %x to i16
2645 define <vscale x 1 x i32> @add_to_or_scalable(<vscale x 1 x i32> %in) {
2646 ; CHECK-LABEL: @add_to_or_scalable(
2647 ; CHECK-NEXT: [[SHL:%.*]] = shl <vscale x 1 x i32> [[IN:%.*]], shufflevector (<vscale x 1 x i32> insertelement (<vscale x 1 x i32> poison, i32 1, i64 0), <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer)
2648 ; CHECK-NEXT: [[ADD:%.*]] = or disjoint <vscale x 1 x i32> [[SHL]], shufflevector (<vscale x 1 x i32> insertelement (<vscale x 1 x i32> poison, i32 1, i64 0), <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer)
2649 ; CHECK-NEXT: ret <vscale x 1 x i32> [[ADD]]
2651 %shl = shl <vscale x 1 x i32> %in, splat (i32 1)
2652 %add = add <vscale x 1 x i32> %shl, splat (i32 1)
2653 ret <vscale x 1 x i32> %add
2656 define i5 @zext_zext_not(i3 noundef %x) {
2657 ; CHECK-LABEL: @zext_zext_not(
2658 ; CHECK-NEXT: ret i5 7
2660 %zx = zext i3 %x to i5
2661 %notx = xor i3 %x, -1
2662 %znotx = zext i3 %notx to i5
2663 %r = add i5 %zx, %znotx
2667 define <2 x i5> @zext_zext_not_commute(<2 x i3> noundef %x) {
2668 ; CHECK-LABEL: @zext_zext_not_commute(
2669 ; CHECK-NEXT: ret <2 x i5> <i5 7, i5 7>
2671 %zx = zext <2 x i3> %x to <2 x i5>
2672 %notx = xor <2 x i3> %x, <i3 -1, i3 poison>
2673 %znotx = zext <2 x i3> %notx to <2 x i5>
2674 %r = add <2 x i5> %znotx, %zx
2678 define i9 @sext_sext_not(i3 noundef %x) {
2679 ; CHECK-LABEL: @sext_sext_not(
2680 ; CHECK-NEXT: ret i9 -1
2682 %sx = sext i3 %x to i9
2683 %notx = xor i3 %x, -1
2684 %snotx = sext i3 %notx to i9
2685 %r = add i9 %sx, %snotx
2689 define i8 @sext_sext_not_commute(i3 noundef %x) {
2690 ; CHECK-LABEL: @sext_sext_not_commute(
2691 ; CHECK-NEXT: [[SX:%.*]] = sext i3 [[X:%.*]] to i8
2692 ; CHECK-NEXT: call void @use(i8 [[SX]])
2693 ; CHECK-NEXT: ret i8 -1
2696 %sx = sext i3 %x to i8
2697 call void @use(i8 %sx)
2698 %notx = xor i3 %x, -1
2699 %snotx = sext i3 %notx to i8
2700 %r = add i8 %snotx, %sx
2704 define i5 @zext_sext_not(i4 noundef %x) {
2705 ; CHECK-LABEL: @zext_sext_not(
2706 ; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i5
2707 ; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
2708 ; CHECK-NEXT: [[SNOTX:%.*]] = sext i4 [[NOTX]] to i5
2709 ; CHECK-NEXT: [[R:%.*]] = or disjoint i5 [[ZX]], [[SNOTX]]
2710 ; CHECK-NEXT: ret i5 [[R]]
2712 %zx = zext i4 %x to i5
2713 %notx = xor i4 %x, -1
2714 %snotx = sext i4 %notx to i5
2715 %r = add i5 %zx, %snotx
2719 define i8 @zext_sext_not_commute(i4 noundef %x) {
2720 ; CHECK-LABEL: @zext_sext_not_commute(
2721 ; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i8
2722 ; CHECK-NEXT: call void @use(i8 [[ZX]])
2723 ; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
2724 ; CHECK-NEXT: [[SNOTX:%.*]] = sext i4 [[NOTX]] to i8
2725 ; CHECK-NEXT: call void @use(i8 [[SNOTX]])
2726 ; CHECK-NEXT: [[R:%.*]] = or disjoint i8 [[SNOTX]], [[ZX]]
2727 ; CHECK-NEXT: ret i8 [[R]]
2729 %zx = zext i4 %x to i8
2730 call void @use(i8 %zx)
2731 %notx = xor i4 %x, -1
2732 %snotx = sext i4 %notx to i8
2733 call void @use(i8 %snotx)
2734 %r = add i8 %snotx, %zx
2738 define i9 @sext_zext_not(i4 noundef %x) {
2739 ; CHECK-LABEL: @sext_zext_not(
2740 ; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i9
2741 ; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
2742 ; CHECK-NEXT: [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9
2743 ; CHECK-NEXT: [[R:%.*]] = or disjoint i9 [[SX]], [[ZNOTX]]
2744 ; CHECK-NEXT: ret i9 [[R]]
2746 %sx = sext i4 %x to i9
2747 %notx = xor i4 %x, -1
2748 %znotx = zext i4 %notx to i9
2749 %r = add i9 %sx, %znotx
2753 define i9 @sext_zext_not_commute(i4 noundef %x) {
2754 ; CHECK-LABEL: @sext_zext_not_commute(
2755 ; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i9
2756 ; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
2757 ; CHECK-NEXT: [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9
2758 ; CHECK-NEXT: [[R:%.*]] = or disjoint i9 [[ZNOTX]], [[SX]]
2759 ; CHECK-NEXT: ret i9 [[R]]
2761 %sx = sext i4 %x to i9
2762 %notx = xor i4 %x, -1
2763 %znotx = zext i4 %notx to i9
2764 %r = add i9 %znotx, %sx
2770 define i32 @floor_sdiv(i32 %x) {
2771 ; CHECK-LABEL: @floor_sdiv(
2772 ; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X:%.*]], 2
2773 ; CHECK-NEXT: ret i32 [[R]]
2776 %a = and i32 %x, -2147483645
2777 %i = icmp ugt i32 %a, -2147483648
2778 %s = sext i1 %i to i32
2783 define i8 @floor_sdiv_by_2(i8 %x) {
2784 ; CHECK-LABEL: @floor_sdiv_by_2(
2785 ; CHECK-NEXT: [[RV:%.*]] = ashr i8 [[X:%.*]], 1
2786 ; CHECK-NEXT: ret i8 [[RV]]
2788 %div = sdiv i8 %x, 2
2789 %and = and i8 %x, -127
2790 %icmp = icmp eq i8 %and, -127
2791 %sext = sext i1 %icmp to i8
2792 %rv = add nsw i8 %div, %sext
2796 define i8 @floor_sdiv_by_2_wrong_mask(i8 %x) {
2797 ; CHECK-LABEL: @floor_sdiv_by_2_wrong_mask(
2798 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X:%.*]], 2
2799 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], 127
2800 ; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i8 [[AND]], 127
2801 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i8
2802 ; CHECK-NEXT: [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]
2803 ; CHECK-NEXT: ret i8 [[RV]]
2805 %div = sdiv i8 %x, 2
2806 %and = and i8 %x, 127
2807 %icmp = icmp eq i8 %and, 127
2808 %sext = sext i1 %icmp to i8
2809 %rv = add nsw i8 %div, %sext
2813 define i8 @floor_sdiv_by_2_wrong_constant(i8 %x) {
2814 ; CHECK-LABEL: @floor_sdiv_by_2_wrong_constant(
2815 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X:%.*]], 4
2816 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -125
2817 ; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i8 [[AND]], -125
2818 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i8
2819 ; CHECK-NEXT: [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]
2820 ; CHECK-NEXT: ret i8 [[RV]]
2822 %div = sdiv i8 %x, 4
2823 %and = and i8 %x, -125
2824 %icmp = icmp eq i8 %and, -125
2825 %sext = sext i1 %icmp to i8
2826 %rv = add nsw i8 %div, %sext
2830 define i8 @floor_sdiv_by_2_wrong_cast(i8 %x) {
2831 ; CHECK-LABEL: @floor_sdiv_by_2_wrong_cast(
2832 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X:%.*]], 2
2833 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -127
2834 ; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i8 [[AND]], -127
2835 ; CHECK-NEXT: [[SEXT:%.*]] = zext i1 [[ICMP]] to i8
2836 ; CHECK-NEXT: [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]
2837 ; CHECK-NEXT: ret i8 [[RV]]
2839 %div = sdiv i8 %x, 2
2840 %and = and i8 %x, -127
2841 %icmp = icmp eq i8 %and, -127
2842 %sext = zext i1 %icmp to i8
2843 %rv = add nsw i8 %div, %sext
2847 ; vectors work too and commute is handled by complexity-based canonicalization
2849 define <2 x i32> @floor_sdiv_vec_commute(<2 x i32> %x) {
2850 ; CHECK-LABEL: @floor_sdiv_vec_commute(
2851 ; CHECK-NEXT: [[R:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 2, i32 2>
2852 ; CHECK-NEXT: ret <2 x i32> [[R]]
2854 %d = sdiv <2 x i32> %x, <i32 4, i32 4>
2855 %a = and <2 x i32> %x, <i32 -2147483645, i32 -2147483645>
2856 %i = icmp ugt <2 x i32> %a, <i32 -2147483648, i32 -2147483648>
2857 %s = sext <2 x i1> %i to <2 x i32>
2858 %r = add <2 x i32> %s, %d
2864 define i8 @floor_sdiv_uses(i8 %x) {
2865 ; CHECK-LABEL: @floor_sdiv_uses(
2866 ; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], 16
2867 ; CHECK-NEXT: call void @use(i8 [[D]])
2868 ; CHECK-NEXT: [[A:%.*]] = and i8 [[X]], -113
2869 ; CHECK-NEXT: call void @use(i8 [[A]])
2870 ; CHECK-NEXT: [[I:%.*]] = icmp ugt i8 [[A]], -128
2871 ; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i8
2872 ; CHECK-NEXT: call void @use(i8 [[S]])
2873 ; CHECK-NEXT: [[R:%.*]] = ashr i8 [[X]], 4
2874 ; CHECK-NEXT: ret i8 [[R]]
2877 call void @use(i8 %d)
2878 %a = and i8 %x, 143 ; 128 + 15
2879 call void @use(i8 %a)
2880 %i = icmp ugt i8 %a, 128
2881 %s = sext i1 %i to i8
2882 call void @use(i8 %s)
2889 define i32 @floor_sdiv_wrong_div(i32 %x) {
2890 ; CHECK-LABEL: @floor_sdiv_wrong_div(
2891 ; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 8
2892 ; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -2147483645
2893 ; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2894 ; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i32
2895 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]]
2896 ; CHECK-NEXT: ret i32 [[R]]
2899 %a = and i32 %x, -2147483645
2900 %i = icmp ugt i32 %a, -2147483648
2901 %s = sext i1 %i to i32
2908 define i32 @floor_sdiv_wrong_mask(i32 %x) {
2909 ; CHECK-LABEL: @floor_sdiv_wrong_mask(
2910 ; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2911 ; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -2147483644
2912 ; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2913 ; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i32
2914 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]]
2915 ; CHECK-NEXT: ret i32 [[R]]
2918 %a = and i32 %x, -2147483644
2919 %i = icmp ugt i32 %a, -2147483648
2920 %s = sext i1 %i to i32
2927 define i32 @floor_sdiv_wrong_cmp(i32 %x) {
2928 ; CHECK-LABEL: @floor_sdiv_wrong_cmp(
2929 ; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2930 ; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -2147483646
2931 ; CHECK-NEXT: [[I:%.*]] = icmp eq i32 [[A]], -2147483646
2932 ; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i32
2933 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]]
2934 ; CHECK-NEXT: ret i32 [[R]]
2937 %a = and i32 %x, -2147483645
2938 %i = icmp ugt i32 %a, -2147483647
2939 %s = sext i1 %i to i32
2946 define i32 @floor_sdiv_wrong_ext(i32 %x) {
2947 ; CHECK-LABEL: @floor_sdiv_wrong_ext(
2948 ; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2949 ; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -2147483645
2950 ; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2951 ; CHECK-NEXT: [[S:%.*]] = zext i1 [[I]] to i32
2952 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]]
2953 ; CHECK-NEXT: ret i32 [[R]]
2956 %a = and i32 %x, -2147483645
2957 %i = icmp ugt i32 %a, -2147483648
2958 %s = zext i1 %i to i32
2965 define i32 @floor_sdiv_wrong_op(i32 %x, i32 %y) {
2966 ; CHECK-LABEL: @floor_sdiv_wrong_op(
2967 ; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2968 ; CHECK-NEXT: [[A:%.*]] = and i32 [[Y:%.*]], -2147483645
2969 ; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2970 ; CHECK-NEXT: [[S:%.*]] = zext i1 [[I]] to i32
2971 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]]
2972 ; CHECK-NEXT: ret i32 [[R]]
2975 %a = and i32 %y, -2147483645
2976 %i = icmp ugt i32 %a, -2147483648
2977 %s = zext i1 %i to i32
2982 ; (X s>> (BW - 1)) + (zext (X s> 0)) --> (X s>> (BW - 1)) | (zext (X != 0))
2984 define i8 @signum_i8_i8(i8 %x) {
2985 ; CHECK-LABEL: @signum_i8_i8(
2986 ; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7
2987 ; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne i8 [[X]], 0
2988 ; CHECK-NEXT: [[ISNOTNULL_ZEXT:%.*]] = zext i1 [[ISNOTNULL]] to i8
2989 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGNBIT]], [[ISNOTNULL_ZEXT]]
2990 ; CHECK-NEXT: ret i8 [[R]]
2992 %sgt0 = icmp sgt i8 %x, 0
2993 %zgt0 = zext i1 %sgt0 to i8
2994 %signbit = ashr i8 %x, 7
2995 %r = add i8 %zgt0, %signbit
2999 ; extra use of shift is ok
3001 define i8 @signum_i8_i8_use1(i8 %x) {
3002 ; CHECK-LABEL: @signum_i8_i8_use1(
3003 ; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7
3004 ; CHECK-NEXT: call void @use(i8 [[SIGNBIT]])
3005 ; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne i8 [[X]], 0
3006 ; CHECK-NEXT: [[ISNOTNULL_ZEXT:%.*]] = zext i1 [[ISNOTNULL]] to i8
3007 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGNBIT]], [[ISNOTNULL_ZEXT]]
3008 ; CHECK-NEXT: ret i8 [[R]]
3010 %sgt0 = icmp sgt i8 %x, 0
3011 %zgt0 = zext i1 %sgt0 to i8
3012 %signbit = ashr i8 %x, 7
3013 call void @use(i8 %signbit)
3014 %r = add i8 %zgt0, %signbit
3020 define i8 @signum_i8_i8_use2(i8 %x) {
3021 ; CHECK-LABEL: @signum_i8_i8_use2(
3022 ; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3023 ; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3024 ; CHECK-NEXT: call void @use(i8 [[ZGT0]])
3025 ; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3026 ; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3027 ; CHECK-NEXT: ret i8 [[R]]
3029 %sgt0 = icmp sgt i8 %x, 0
3030 %zgt0 = zext i1 %sgt0 to i8
3031 call void @use(i8 %zgt0)
3032 %signbit = ashr i8 %x, 7
3033 %r = add i8 %zgt0, %signbit
3039 define i8 @signum_i8_i8_use3(i8 %x) {
3040 ; CHECK-LABEL: @signum_i8_i8_use3(
3041 ; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3042 ; CHECK-NEXT: call void @use_i1(i1 [[SGT0]])
3043 ; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3044 ; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3045 ; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3046 ; CHECK-NEXT: ret i8 [[R]]
3048 %sgt0 = icmp sgt i8 %x, 0
3049 call void @use_i1(i1 %sgt0)
3050 %zgt0 = zext i1 %sgt0 to i8
3051 %signbit = ashr i8 %x, 7
3052 %r = add i8 %zgt0, %signbit
3056 ; poison is ok to propagate in shift amount
3057 ; complexity canonicalization guarantees that shift is op0 of add
3059 define <2 x i5> @signum_v2i5_v2i5(<2 x i5> %x) {
3060 ; CHECK-LABEL: @signum_v2i5_v2i5(
3061 ; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr <2 x i5> [[X:%.*]], <i5 4, i5 poison>
3062 ; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne <2 x i5> [[X]], zeroinitializer
3063 ; CHECK-NEXT: [[ISNOTNULL_ZEXT:%.*]] = zext <2 x i1> [[ISNOTNULL]] to <2 x i5>
3064 ; CHECK-NEXT: [[R:%.*]] = or <2 x i5> [[SIGNBIT]], [[ISNOTNULL_ZEXT]]
3065 ; CHECK-NEXT: ret <2 x i5> [[R]]
3067 %sgt0 = icmp sgt <2 x i5> %x, zeroinitializer
3068 %zgt0 = zext <2 x i1> %sgt0 to <2 x i5>
3069 %signbit = ashr <2 x i5> %x, <i5 4, i5 poison>
3070 %r = add <2 x i5> %signbit, %zgt0
3076 define i8 @signum_i8_i8_wrong_sh_amt(i8 %x) {
3077 ; CHECK-LABEL: @signum_i8_i8_wrong_sh_amt(
3078 ; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3079 ; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3080 ; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 6
3081 ; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3082 ; CHECK-NEXT: ret i8 [[R]]
3084 %sgt0 = icmp sgt i8 %x, 0
3085 %zgt0 = zext i1 %sgt0 to i8
3086 %signbit = ashr i8 %x, 6
3087 %r = add i8 %zgt0, %signbit
3093 define i8 @signum_i8_i8_wrong_ext(i8 %x) {
3094 ; CHECK-LABEL: @signum_i8_i8_wrong_ext(
3095 ; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3096 ; CHECK-NEXT: [[ZGT0:%.*]] = sext i1 [[SGT0]] to i8
3097 ; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3098 ; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3099 ; CHECK-NEXT: ret i8 [[R]]
3101 %sgt0 = icmp sgt i8 %x, 0
3102 %zgt0 = sext i1 %sgt0 to i8
3103 %signbit = ashr i8 %x, 7
3104 %r = add i8 %zgt0, %signbit
3110 define i8 @signum_i8_i8_wrong_pred(i8 %x) {
3111 ; CHECK-LABEL: @signum_i8_i8_wrong_pred(
3112 ; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], -1
3113 ; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3114 ; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3115 ; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3116 ; CHECK-NEXT: ret i8 [[R]]
3118 %sgt0 = icmp sge i8 %x, 0
3119 %zgt0 = zext i1 %sgt0 to i8
3120 %signbit = ashr i8 %x, 7
3121 %r = add i8 %zgt0, %signbit
3125 define i32 @dec_zext_add_assume_nonzero(i8 %x) {
3126 ; CHECK-LABEL: @dec_zext_add_assume_nonzero(
3127 ; CHECK-NEXT: [[Z:%.*]] = icmp ne i8 [[X:%.*]], 0
3128 ; CHECK-NEXT: call void @llvm.assume(i1 [[Z]])
3129 ; CHECK-NEXT: [[C:%.*]] = zext i8 [[X]] to i32
3130 ; CHECK-NEXT: ret i32 [[C]]
3132 %z = icmp ne i8 %x, 0
3133 call void @llvm.assume(i1 %z)
3135 %b = zext i8 %a to i32
3140 define i32 @dec_zext_add_nonzero(i8 %x) {
3141 ; CHECK-LABEL: @dec_zext_add_nonzero(
3142 ; CHECK-NEXT: [[O:%.*]] = or i8 [[X:%.*]], 4
3143 ; CHECK-NEXT: [[C:%.*]] = zext i8 [[O]] to i32
3144 ; CHECK-NEXT: ret i32 [[C]]
3148 %b = zext i8 %a to i32
3153 define <2 x i32> @dec_zext_add_nonzero_vec(<2 x i8> %x) {
3154 ; CHECK-LABEL: @dec_zext_add_nonzero_vec(
3155 ; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 8>
3156 ; CHECK-NEXT: [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>
3157 ; CHECK-NEXT: ret <2 x i32> [[C]]
3159 %o = or <2 x i8> %x, <i8 8, i8 8>
3160 %a = add <2 x i8> %o, <i8 -1, i8 -1>
3161 %b = zext <2 x i8> %a to <2 x i32>
3162 %c = add <2 x i32> %b, <i32 1, i32 1>
3166 ; Negative test: Folding this with undef is not safe.
3168 define <2 x i32> @dec_zext_add_nonzero_vec_undef0(<2 x i8> %x) {
3169 ; CHECK-LABEL: @dec_zext_add_nonzero_vec_undef0(
3170 ; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 undef>
3171 ; CHECK-NEXT: [[A:%.*]] = add <2 x i8> [[O]], <i8 -1, i8 -1>
3172 ; CHECK-NEXT: [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32>
3173 ; CHECK-NEXT: [[C:%.*]] = add nuw nsw <2 x i32> [[B]], <i32 1, i32 1>
3174 ; CHECK-NEXT: ret <2 x i32> [[C]]
3176 %o = or <2 x i8> %x, <i8 8, i8 undef>
3177 %a = add <2 x i8> %o, <i8 -1, i8 -1>
3178 %b = zext <2 x i8> %a to <2 x i32>
3179 %c = add <2 x i32> %b, <i32 1, i32 1>
3183 define <2 x i32> @dec_zext_add_nonzero_poison0(<2 x i8> %x) {
3184 ; CHECK-LABEL: @dec_zext_add_nonzero_poison0(
3185 ; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 poison>
3186 ; CHECK-NEXT: [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>
3187 ; CHECK-NEXT: ret <2 x i32> [[C]]
3189 %o = or <2 x i8> %x, <i8 8, i8 poison>
3190 %a = add <2 x i8> %o, <i8 -1, i8 -1>
3191 %b = zext <2 x i8> %a to <2 x i32>
3192 %c = add <2 x i32> %b, <i32 1, i32 1>
3196 define <2 x i32> @dec_zext_add_nonzero_vec_poison1(<2 x i8> %x) {
3197 ; CHECK-LABEL: @dec_zext_add_nonzero_vec_poison1(
3198 ; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 8>
3199 ; CHECK-NEXT: [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>
3200 ; CHECK-NEXT: ret <2 x i32> [[C]]
3202 %o = or <2 x i8> %x, <i8 8, i8 8>
3203 %a = add <2 x i8> %o, <i8 -1, i8 poison>
3204 %b = zext <2 x i8> %a to <2 x i32>
3205 %c = add <2 x i32> %b, <i32 1, i32 1>
3209 define <2 x i32> @dec_zext_add_nonzero_vec_poison2(<2 x i8> %x) {
3210 ; CHECK-LABEL: @dec_zext_add_nonzero_vec_poison2(
3211 ; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 8>
3212 ; CHECK-NEXT: [[A:%.*]] = add nsw <2 x i8> [[O]], <i8 -1, i8 -1>
3213 ; CHECK-NEXT: [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32>
3214 ; CHECK-NEXT: [[C:%.*]] = add nuw nsw <2 x i32> [[B]], <i32 1, i32 poison>
3215 ; CHECK-NEXT: ret <2 x i32> [[C]]
3217 %o = or <2 x i8> %x, <i8 8, i8 8>
3218 %a = add <2 x i8> %o, <i8 -1, i8 -1>
3219 %b = zext <2 x i8> %a to <2 x i32>
3220 %c = add <2 x i32> %b, <i32 1, i32 poison>
3224 define i32 @add_zext_sext_i1(i1 %a) {
3225 ; CHECK-LABEL: @add_zext_sext_i1(
3226 ; CHECK-NEXT: ret i32 0
3228 %zext = zext i1 %a to i32
3229 %sext = sext i1 %a to i32
3230 %add = add i32 %zext, %sext
3234 define i32 @add_sext_zext_i1(i1 %a) {
3235 ; CHECK-LABEL: @add_sext_zext_i1(
3236 ; CHECK-NEXT: ret i32 0
3238 %zext = zext i1 %a to i32
3239 %sext = sext i1 %a to i32
3240 %add = add i32 %sext, %zext
3244 define <2 x i32> @add_zext_sext_i1_vec(<2 x i1> %a) {
3245 ; CHECK-LABEL: @add_zext_sext_i1_vec(
3246 ; CHECK-NEXT: ret <2 x i32> zeroinitializer
3248 %zext = zext <2 x i1> %a to <2 x i32>
3249 %sext = sext <2 x i1> %a to <2 x i32>
3250 %add = add <2 x i32> %zext, %sext
3254 define i32 @add_zext_zext_i1(i1 %a) {
3255 ; CHECK-LABEL: @add_zext_zext_i1(
3256 ; CHECK-NEXT: [[ADD:%.*]] = select i1 [[A:%.*]], i32 2, i32 0
3257 ; CHECK-NEXT: ret i32 [[ADD]]
3259 %zext = zext i1 %a to i32
3260 %add = add i32 %zext, %zext
3264 define i32 @add_sext_sext_i1(i1 %a) {
3265 ; CHECK-LABEL: @add_sext_sext_i1(
3266 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i32
3267 ; CHECK-NEXT: [[ADD:%.*]] = shl nsw i32 [[SEXT]], 1
3268 ; CHECK-NEXT: ret i32 [[ADD]]
3270 %sext = sext i1 %a to i32
3271 %add = add i32 %sext, %sext
3275 define i32 @add_zext_sext_not_i1(i8 %a) {
3276 ; CHECK-LABEL: @add_zext_sext_not_i1(
3277 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[A:%.*]] to i32
3278 ; CHECK-NEXT: [[SEXT:%.*]] = sext i8 [[A]] to i32
3279 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]]
3280 ; CHECK-NEXT: ret i32 [[ADD]]
3282 %zext = zext i8 %a to i32
3283 %sext = sext i8 %a to i32
3284 %add = add i32 %zext, %sext
3288 define i32 @add_zext_sext_i1_different_values(i1 %a, i1 %b) {
3289 ; CHECK-LABEL: @add_zext_sext_i1_different_values(
3290 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[A:%.*]] to i32
3291 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[B:%.*]] to i32
3292 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]]
3293 ; CHECK-NEXT: ret i32 [[ADD]]
3295 %zext = zext i1 %a to i32
3296 %sext = sext i1 %b to i32
3297 %add = add i32 %zext, %sext
3301 define i32 @add_reduce_sqr_sum_nsw(i32 %a, i32 %b) {
3302 ; CHECK-LABEL: @add_reduce_sqr_sum_nsw(
3303 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3304 ; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3305 ; CHECK-NEXT: ret i32 [[ADD]]
3307 %a_sq = mul nsw i32 %a, %a
3308 %two_a = shl i32 %a, 1
3309 %two_a_plus_b = add i32 %two_a, %b
3310 %mul = mul i32 %two_a_plus_b, %b
3311 %add = add i32 %mul, %a_sq
3315 define i32 @add_reduce_sqr_sum_u(i32 %a, i32 %b) {
3316 ; CHECK-LABEL: @add_reduce_sqr_sum_u(
3317 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3318 ; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3319 ; CHECK-NEXT: ret i32 [[ADD]]
3321 %a_sq = mul i32 %a, %a
3322 %two_a = shl i32 %a, 1
3323 %two_a_plus_b = add i32 %two_a, %b
3324 %mul = mul i32 %two_a_plus_b, %b
3325 %add = add i32 %mul, %a_sq
3329 define i32 @add_reduce_sqr_sum_nuw(i32 %a, i32 %b) {
3330 ; CHECK-LABEL: @add_reduce_sqr_sum_nuw(
3331 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3332 ; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3333 ; CHECK-NEXT: ret i32 [[ADD]]
3335 %a_sq = mul nuw i32 %a, %a
3336 %two_a = mul i32 %a, 2
3337 %two_a_plus_b = add i32 %two_a, %b
3338 %mul = mul nuw i32 %two_a_plus_b, %b
3339 %add = add i32 %mul, %a_sq
3343 define i32 @add_reduce_sqr_sum_flipped(i32 %a, i32 %b) {
3344 ; CHECK-LABEL: @add_reduce_sqr_sum_flipped(
3345 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3346 ; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3347 ; CHECK-NEXT: ret i32 [[ADD]]
3349 %a_sq = mul nsw i32 %a, %a
3350 %two_a = shl i32 %a, 1
3351 %two_a_plus_b = add i32 %two_a, %b
3352 %mul = mul i32 %two_a_plus_b, %b
3353 %add = add i32 %a_sq, %mul
3357 define i32 @add_reduce_sqr_sum_flipped2(i32 %a, i32 %bx) {
3358 ; CHECK-LABEL: @add_reduce_sqr_sum_flipped2(
3359 ; CHECK-NEXT: [[B:%.*]] = xor i32 [[BX:%.*]], 42
3360 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B]], [[A:%.*]]
3361 ; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3362 ; CHECK-NEXT: ret i32 [[ADD]]
3364 %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization
3365 %a_sq = mul nsw i32 %a, %a
3366 %two_a = shl i32 %a, 1
3367 %two_a_plus_b = add i32 %two_a, %b
3368 %mul = mul i32 %b, %two_a_plus_b
3369 %add = add i32 %mul, %a_sq
3373 define i32 @add_reduce_sqr_sum_flipped3(i32 %a, i32 %b) {
3374 ; CHECK-LABEL: @add_reduce_sqr_sum_flipped3(
3375 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3376 ; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3377 ; CHECK-NEXT: ret i32 [[ADD]]
3379 %a_sq = mul nsw i32 %a, %a
3380 %two_a = shl i32 %a, 1
3381 %two_a_plus_b = add i32 %b, %two_a
3382 %mul = mul i32 %two_a_plus_b, %b
3383 %add = add i32 %mul, %a_sq
3387 define i32 @add_reduce_sqr_sum_order2(i32 %a, i32 %b) {
3388 ; CHECK-LABEL: @add_reduce_sqr_sum_order2(
3389 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3390 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3391 ; CHECK-NEXT: ret i32 [[AB2]]
3393 %a_sq = mul nsw i32 %a, %a
3394 %twoa = mul i32 %a, 2
3395 %twoab = mul i32 %twoa, %b
3396 %b_sq = mul i32 %b, %b
3397 %twoab_b2 = add i32 %twoab, %b_sq
3398 %ab2 = add i32 %a_sq, %twoab_b2
3402 define i32 @add_reduce_sqr_sum_order2_flipped(i32 %a, i32 %b) {
3403 ; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped(
3404 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3405 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3406 ; CHECK-NEXT: ret i32 [[AB2]]
3408 %a_sq = mul nsw i32 %a, %a
3409 %twoa = mul i32 %a, 2
3410 %twoab = mul i32 %twoa, %b
3411 %b_sq = mul i32 %b, %b
3412 %twoab_b2 = add i32 %twoab, %b_sq
3413 %ab2 = add i32 %twoab_b2, %a_sq
3417 define i32 @add_reduce_sqr_sum_order2_flipped2(i32 %a, i32 %bx) {
3418 ; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped2(
3419 ; CHECK-NEXT: [[B:%.*]] = xor i32 [[BX:%.*]], 42
3420 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B]], [[A:%.*]]
3421 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3422 ; CHECK-NEXT: ret i32 [[AB2]]
3424 %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization
3425 %a_sq = mul nsw i32 %a, %a
3426 %twoa = mul i32 %a, 2
3427 %twoab = mul i32 %twoa, %b
3428 %b_sq = mul i32 %b, %b
3429 %twoab_b2 = add i32 %b_sq, %twoab
3430 %ab2 = add i32 %a_sq, %twoab_b2
3434 define i32 @add_reduce_sqr_sum_order2_flipped3(i32 %a, i32 %bx) {
3435 ; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped3(
3436 ; CHECK-NEXT: [[B:%.*]] = xor i32 [[BX:%.*]], 42
3437 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B]], [[A:%.*]]
3438 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3439 ; CHECK-NEXT: ret i32 [[AB2]]
3441 %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization
3442 %a_sq = mul nsw i32 %a, %a
3443 %twoa = mul i32 %a, 2
3444 %twoab = mul i32 %b, %twoa
3445 %b_sq = mul i32 %b, %b
3446 %twoab_b2 = add i32 %twoab, %b_sq
3447 %ab2 = add i32 %a_sq, %twoab_b2
3451 define i32 @add_reduce_sqr_sum_order3(i32 %a, i32 %b) {
3452 ; CHECK-LABEL: @add_reduce_sqr_sum_order3(
3453 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3454 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3455 ; CHECK-NEXT: ret i32 [[AB2]]
3457 %a_sq = mul nsw i32 %a, %a
3458 %twoa = mul i32 %a, 2
3459 %twoab = mul i32 %twoa, %b
3460 %b_sq = mul i32 %b, %b
3461 %a2_b2 = add i32 %a_sq, %b_sq
3462 %ab2 = add i32 %twoab, %a2_b2
3466 define i32 @add_reduce_sqr_sum_order3_flipped(i32 %a, i32 %b) {
3467 ; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped(
3468 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3469 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3470 ; CHECK-NEXT: ret i32 [[AB2]]
3472 %a_sq = mul nsw i32 %a, %a
3473 %twoa = mul i32 %a, 2
3474 %twoab = mul i32 %twoa, %b
3475 %b_sq = mul i32 %b, %b
3476 %a2_b2 = add i32 %a_sq, %b_sq
3477 %ab2 = add i32 %a2_b2, %twoab
3481 define i32 @add_reduce_sqr_sum_order3_flipped2(i32 %a, i32 %b) {
3482 ; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped2(
3483 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3484 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3485 ; CHECK-NEXT: ret i32 [[AB2]]
3487 %a_sq = mul nsw i32 %a, %a
3488 %twoa = mul i32 %a, 2
3489 %twoab = mul i32 %twoa, %b
3490 %b_sq = mul i32 %b, %b
3491 %a2_b2 = add i32 %b_sq, %a_sq
3492 %ab2 = add i32 %twoab, %a2_b2
3496 define i32 @add_reduce_sqr_sum_order3_flipped3(i32 %a, i32 %b) {
3497 ; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped3(
3498 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3499 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3500 ; CHECK-NEXT: ret i32 [[AB2]]
3502 %a_sq = mul nsw i32 %a, %a
3503 %twoa = mul i32 %a, 2
3504 %twoab = mul i32 %b, %twoa
3505 %b_sq = mul i32 %b, %b
3506 %a2_b2 = add i32 %a_sq, %b_sq
3507 %ab2 = add i32 %twoab, %a2_b2
3511 define i32 @add_reduce_sqr_sum_order4(i32 %a, i32 %b) {
3512 ; CHECK-LABEL: @add_reduce_sqr_sum_order4(
3513 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3514 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3515 ; CHECK-NEXT: ret i32 [[AB2]]
3517 %a_sq = mul nsw i32 %a, %a
3518 %ab = mul i32 %a, %b
3519 %twoab = mul i32 %ab, 2
3520 %b_sq = mul i32 %b, %b
3521 %a2_b2 = add i32 %a_sq, %b_sq
3522 %ab2 = add i32 %twoab, %a2_b2
3526 define i32 @add_reduce_sqr_sum_order4_flipped(i32 %a, i32 %b) {
3527 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped(
3528 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3529 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3530 ; CHECK-NEXT: ret i32 [[AB2]]
3532 %a_sq = mul nsw i32 %a, %a
3533 %ab = mul i32 %a, %b
3534 %twoab = mul i32 %ab, 2
3535 %b_sq = mul i32 %b, %b
3536 %a2_b2 = add i32 %a_sq, %b_sq
3537 %ab2 = add i32 %a2_b2, %twoab
3541 define i32 @add_reduce_sqr_sum_order4_flipped2(i32 %a, i32 %b) {
3542 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped2(
3543 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3544 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3545 ; CHECK-NEXT: ret i32 [[AB2]]
3547 %a_sq = mul nsw i32 %a, %a
3548 %ab = mul i32 %a, %b
3549 %twoab = mul i32 %ab, 2
3550 %b_sq = mul i32 %b, %b
3551 %a2_b2 = add i32 %b_sq, %a_sq
3552 %ab2 = add i32 %twoab, %a2_b2
3556 define i32 @add_reduce_sqr_sum_order4_flipped3(i32 %a, i32 %b) {
3557 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped3(
3558 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3559 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3560 ; CHECK-NEXT: ret i32 [[AB2]]
3562 %a_sq = mul nsw i32 %a, %a
3563 %ab = mul i32 %a, %b
3564 %twoab = mul i32 2, %ab
3565 %b_sq = mul i32 %b, %b
3566 %a2_b2 = add i32 %a_sq, %b_sq
3567 %ab2 = add i32 %twoab, %a2_b2
3571 define i32 @add_reduce_sqr_sum_order4_flipped4(i32 %a, i32 %b) {
3572 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped4(
3573 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3574 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3575 ; CHECK-NEXT: ret i32 [[AB2]]
3577 %a_sq = mul nsw i32 %a, %a
3578 %ab = mul i32 %b, %a
3579 %twoab = mul i32 %ab, 2
3580 %b_sq = mul i32 %b, %b
3581 %a2_b2 = add i32 %a_sq, %b_sq
3582 %ab2 = add i32 %twoab, %a2_b2
3586 define i32 @add_reduce_sqr_sum_order5(i32 %a, i32 %b) {
3587 ; CHECK-LABEL: @add_reduce_sqr_sum_order5(
3588 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3589 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3590 ; CHECK-NEXT: ret i32 [[AB2]]
3592 %a_sq = mul nsw i32 %a, %a
3593 %twob = mul i32 %b, 2
3594 %twoab = mul i32 %twob, %a
3595 %b_sq = mul i32 %b, %b
3596 %a2_b2 = add i32 %a_sq, %b_sq
3597 %ab2 = add i32 %twoab, %a2_b2
3601 define i32 @add_reduce_sqr_sum_order5_flipped(i32 %a, i32 %b) {
3602 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped(
3603 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3604 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3605 ; CHECK-NEXT: ret i32 [[AB2]]
3607 %a_sq = mul nsw i32 %a, %a
3608 %twob = mul i32 %b, 2
3609 %twoab = mul i32 %twob, %a
3610 %b_sq = mul i32 %b, %b
3611 %a2_b2 = add i32 %a_sq, %b_sq
3612 %ab2 = add i32 %a2_b2, %twoab
3616 define i32 @add_reduce_sqr_sum_order5_flipped2(i32 %a, i32 %b) {
3617 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped2(
3618 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3619 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3620 ; CHECK-NEXT: ret i32 [[AB2]]
3622 %a_sq = mul nsw i32 %a, %a
3623 %twob = mul i32 %b, 2
3624 %twoab = mul i32 %twob, %a
3625 %b_sq = mul i32 %b, %b
3626 %a2_b2 = add i32 %b_sq, %a_sq
3627 %ab2 = add i32 %twoab, %a2_b2
3631 define i32 @add_reduce_sqr_sum_order5_flipped3(i32 %ax, i32 %b) {
3632 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped3(
3633 ; CHECK-NEXT: [[A:%.*]] = xor i32 [[AX:%.*]], 42
3634 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A]], [[B:%.*]]
3635 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3636 ; CHECK-NEXT: ret i32 [[AB2]]
3638 %a = xor i32 %ax, 42 ; thwart complexity-based canonicalization
3639 %a_sq = mul nsw i32 %a, %a
3640 %twob = mul i32 %b, 2
3641 %twoab = mul i32 %a, %twob
3642 %b_sq = mul i32 %b, %b
3643 %a2_b2 = add i32 %a_sq, %b_sq
3644 %ab2 = add i32 %twoab, %a2_b2
3648 define i32 @add_reduce_sqr_sum_order5_flipped4(i32 %a, i32 %b) {
3649 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped4(
3650 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3651 ; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3652 ; CHECK-NEXT: ret i32 [[AB2]]
3654 %a_sq = mul nsw i32 %a, %a
3655 %twob = mul i32 2, %b
3656 %twoab = mul i32 %twob, %a
3657 %b_sq = mul i32 %b, %b
3658 %a2_b2 = add i32 %a_sq, %b_sq
3659 %ab2 = add i32 %twoab, %a2_b2
3663 define i32 @add_reduce_sqr_sum_not_one_use(i32 %a, i32 %b) {
3664 ; CHECK-LABEL: @add_reduce_sqr_sum_not_one_use(
3665 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3666 ; CHECK-NEXT: [[TWO_A:%.*]] = shl i32 [[A]], 1
3667 ; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]
3668 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3669 ; CHECK-NEXT: tail call void @fake_func(i32 [[MUL]])
3670 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3671 ; CHECK-NEXT: ret i32 [[ADD]]
3673 %a_sq = mul nsw i32 %a, %a
3674 %two_a = shl i32 %a, 1
3675 %two_a_plus_b = add i32 %two_a, %b
3676 %mul = mul i32 %two_a_plus_b, %b
3677 tail call void @fake_func (i32 %mul)
3678 %add = add i32 %mul, %a_sq
3682 define i32 @add_reduce_sqr_sum_not_one_use2(i32 %a, i32 %b) {
3683 ; CHECK-LABEL: @add_reduce_sqr_sum_not_one_use2(
3684 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3685 ; CHECK-NEXT: [[TWO_A:%.*]] = shl i32 [[A]], 1
3686 ; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]
3687 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3688 ; CHECK-NEXT: tail call void @fake_func(i32 [[A_SQ]])
3689 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3690 ; CHECK-NEXT: ret i32 [[ADD]]
3692 %a_sq = mul nsw i32 %a, %a
3693 %two_a = shl i32 %a, 1
3694 %two_a_plus_b = add i32 %two_a, %b
3695 %mul = mul i32 %two_a_plus_b, %b
3696 tail call void @fake_func (i32 %a_sq)
3697 %add = add i32 %mul, %a_sq
3701 define i32 @add_reduce_sqr_sum_order2_not_one_use(i32 %a, i32 %b) {
3702 ; CHECK-LABEL: @add_reduce_sqr_sum_order2_not_one_use(
3703 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3704 ; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 1
3705 ; CHECK-NEXT: [[TWOAB1:%.*]] = add i32 [[TWOA]], [[B:%.*]]
3706 ; CHECK-NEXT: [[TWOAB_B2:%.*]] = mul i32 [[TWOAB1]], [[B]]
3707 ; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB_B2]])
3708 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[A_SQ]], [[TWOAB_B2]]
3709 ; CHECK-NEXT: ret i32 [[AB2]]
3711 %a_sq = mul nsw i32 %a, %a
3712 %twoa = mul i32 %a, 2
3713 %twoab = mul i32 %twoa, %b
3714 %b_sq = mul i32 %b, %b
3715 %twoab_b2 = add i32 %twoab, %b_sq
3716 tail call void @fake_func (i32 %twoab_b2)
3717 %ab2 = add i32 %a_sq, %twoab_b2
3721 define i32 @add_reduce_sqr_sum_order2_not_one_use2(i32 %a, i32 %b) {
3722 ; CHECK-LABEL: @add_reduce_sqr_sum_order2_not_one_use2(
3723 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3724 ; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 1
3725 ; CHECK-NEXT: [[TWOAB1:%.*]] = add i32 [[TWOA]], [[B:%.*]]
3726 ; CHECK-NEXT: [[TWOAB_B2:%.*]] = mul i32 [[TWOAB1]], [[B]]
3727 ; CHECK-NEXT: tail call void @fake_func(i32 [[A_SQ]])
3728 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[A_SQ]], [[TWOAB_B2]]
3729 ; CHECK-NEXT: ret i32 [[AB2]]
3731 %a_sq = mul nsw i32 %a, %a
3732 %twoa = mul i32 %a, 2
3733 %twoab = mul i32 %twoa, %b
3734 %b_sq = mul i32 %b, %b
3735 %twoab_b2 = add i32 %twoab, %b_sq
3736 tail call void @fake_func (i32 %a_sq)
3737 %ab2 = add i32 %a_sq, %twoab_b2
3741 define i32 @add_reduce_sqr_sum_order3_not_one_use(i32 %a, i32 %b) {
3742 ; CHECK-LABEL: @add_reduce_sqr_sum_order3_not_one_use(
3743 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3744 ; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 1
3745 ; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOA]], [[B:%.*]]
3746 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3747 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3748 ; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB]])
3749 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3750 ; CHECK-NEXT: ret i32 [[AB2]]
3752 %a_sq = mul nsw i32 %a, %a
3753 %twoa = mul i32 %a, 2
3754 %twoab = mul i32 %twoa, %b
3755 %b_sq = mul i32 %b, %b
3756 %a2_b2 = add i32 %a_sq, %b_sq
3757 tail call void @fake_func (i32 %twoab)
3758 %ab2 = add i32 %twoab, %a2_b2
3762 define i32 @add_reduce_sqr_sum_order3_not_one_use2(i32 %a, i32 %b) {
3763 ; CHECK-LABEL: @add_reduce_sqr_sum_order3_not_one_use2(
3764 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3765 ; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 1
3766 ; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOA]], [[B:%.*]]
3767 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3768 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3769 ; CHECK-NEXT: tail call void @fake_func(i32 [[A2_B2]])
3770 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3771 ; CHECK-NEXT: ret i32 [[AB2]]
3773 %a_sq = mul nsw i32 %a, %a
3774 %twoa = mul i32 %a, 2
3775 %twoab = mul i32 %twoa, %b
3776 %b_sq = mul i32 %b, %b
3777 %a2_b2 = add i32 %a_sq, %b_sq
3778 tail call void @fake_func (i32 %a2_b2)
3779 %ab2 = add i32 %twoab, %a2_b2
3783 define i32 @add_reduce_sqr_sum_order4_not_one_use(i32 %a, i32 %b) {
3784 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_not_one_use(
3785 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3786 ; CHECK-NEXT: [[AB:%.*]] = mul i32 [[A]], [[B:%.*]]
3787 ; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[AB]], 1
3788 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3789 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3790 ; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB]])
3791 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3792 ; CHECK-NEXT: ret i32 [[AB2]]
3794 %a_sq = mul nsw i32 %a, %a
3795 %ab = mul i32 %a, %b
3796 %twoab = mul i32 %ab, 2
3797 %b_sq = mul i32 %b, %b
3798 %a2_b2 = add i32 %a_sq, %b_sq
3799 tail call void @fake_func (i32 %twoab)
3800 %ab2 = add i32 %twoab, %a2_b2
3804 define i32 @add_reduce_sqr_sum_order4_not_one_use2(i32 %a, i32 %b) {
3805 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_not_one_use2(
3806 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3807 ; CHECK-NEXT: [[AB:%.*]] = mul i32 [[A]], [[B:%.*]]
3808 ; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[AB]], 1
3809 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3810 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3811 ; CHECK-NEXT: tail call void @fake_func(i32 [[A2_B2]])
3812 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3813 ; CHECK-NEXT: ret i32 [[AB2]]
3815 %a_sq = mul nsw i32 %a, %a
3816 %ab = mul i32 %a, %b
3817 %twoab = mul i32 %ab, 2
3818 %b_sq = mul i32 %b, %b
3819 %a2_b2 = add i32 %a_sq, %b_sq
3820 tail call void @fake_func (i32 %a2_b2)
3821 %ab2 = add i32 %twoab, %a2_b2
3825 define i32 @add_reduce_sqr_sum_order5_not_one_use(i32 %a, i32 %b) {
3826 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_not_one_use(
3827 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3828 ; CHECK-NEXT: [[TWOB:%.*]] = shl i32 [[B:%.*]], 1
3829 ; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOB]], [[A]]
3830 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3831 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3832 ; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB]])
3833 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3834 ; CHECK-NEXT: ret i32 [[AB2]]
3836 %a_sq = mul nsw i32 %a, %a
3837 %twob = mul i32 %b, 2
3838 %twoab = mul i32 %twob, %a
3839 %b_sq = mul i32 %b, %b
3840 %a2_b2 = add i32 %a_sq, %b_sq
3841 tail call void @fake_func (i32 %twoab)
3842 %ab2 = add i32 %twoab, %a2_b2
3846 define i32 @add_reduce_sqr_sum_order5_not_one_use2(i32 %a, i32 %b) {
3847 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_not_one_use2(
3848 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3849 ; CHECK-NEXT: [[TWOB:%.*]] = shl i32 [[B:%.*]], 1
3850 ; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOB]], [[A]]
3851 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3852 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3853 ; CHECK-NEXT: tail call void @fake_func(i32 [[A2_B2]])
3854 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3855 ; CHECK-NEXT: ret i32 [[AB2]]
3857 %a_sq = mul nsw i32 %a, %a
3858 %twob = mul i32 %b, 2
3859 %twoab = mul i32 %twob, %a
3860 %b_sq = mul i32 %b, %b
3861 %a2_b2 = add i32 %a_sq, %b_sq
3862 tail call void @fake_func (i32 %a2_b2)
3863 %ab2 = add i32 %twoab, %a2_b2
3867 define i32 @add_reduce_sqr_sum_invalid0(i32 %a, i32 %b) {
3868 ; CHECK-LABEL: @add_reduce_sqr_sum_invalid0(
3869 ; CHECK-NEXT: [[TWO_A:%.*]] = shl i32 [[A:%.*]], 1
3870 ; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]
3871 ; CHECK-NEXT: [[MUL1:%.*]] = add i32 [[TWO_A_PLUS_B]], [[A]]
3872 ; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[MUL1]], [[B]]
3873 ; CHECK-NEXT: ret i32 [[ADD]]
3875 %not_a_sq = mul nsw i32 %a, %b
3876 %two_a = shl i32 %a, 1
3877 %two_a_plus_b = add i32 %two_a, %b
3878 %mul = mul i32 %two_a_plus_b, %b
3879 %add = add i32 %mul, %not_a_sq
3883 define i32 @add_reduce_sqr_sum_invalid1(i32 %a, i32 %b) {
3884 ; CHECK-LABEL: @add_reduce_sqr_sum_invalid1(
3885 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3886 ; CHECK-NEXT: [[NOT_TWO_A_PLUS_B:%.*]] = mul i32 [[A]], 3
3887 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[NOT_TWO_A_PLUS_B]], [[B:%.*]]
3888 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3889 ; CHECK-NEXT: ret i32 [[ADD]]
3891 %a_sq = mul nsw i32 %a, %a
3892 %two_a = shl i32 %a, 1
3893 %not_two_a_plus_b = add i32 %two_a, %a
3894 %mul = mul i32 %not_two_a_plus_b, %b
3895 %add = add i32 %mul, %a_sq
3899 define i32 @add_reduce_sqr_sum_invalid2(i32 %a, i32 %b) {
3900 ; CHECK-LABEL: @add_reduce_sqr_sum_invalid2(
3901 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3902 ; CHECK-NEXT: [[NOT_TWO_A:%.*]] = shl i32 [[A]], 2
3903 ; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[NOT_TWO_A]], [[B:%.*]]
3904 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3905 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3906 ; CHECK-NEXT: ret i32 [[ADD]]
3908 %a_sq = mul nsw i32 %a, %a
3909 %not_two_a = shl i32 %a, 2
3910 %two_a_plus_b = add i32 %not_two_a, %b
3911 %mul = mul i32 %two_a_plus_b, %b
3912 %add = add i32 %mul, %a_sq
3916 define i32 @add_reduce_sqr_sum_invalid3(i32 %a, i32 %b) {
3917 ; CHECK-LABEL: @add_reduce_sqr_sum_invalid3(
3918 ; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = mul i32 [[B:%.*]], 3
3919 ; CHECK-NEXT: [[MUL1:%.*]] = add i32 [[TWO_A_PLUS_B]], [[A:%.*]]
3920 ; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[MUL1]], [[A]]
3921 ; CHECK-NEXT: ret i32 [[ADD]]
3923 %a_sq = mul nsw i32 %a, %a
3924 %not_two_a = shl i32 %b, 1
3925 %two_a_plus_b = add i32 %not_two_a, %b
3926 %mul = mul i32 %two_a_plus_b, %a
3927 %add = add i32 %mul, %a_sq
3931 define i32 @add_reduce_sqr_sum_invalid4(i32 %a, i32 %b) {
3932 ; CHECK-LABEL: @add_reduce_sqr_sum_invalid4(
3933 ; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3934 ; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = mul i32 [[B:%.*]], 3
3935 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3936 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3937 ; CHECK-NEXT: ret i32 [[ADD]]
3939 %a_sq = mul nsw i32 %a, %a
3940 %not_two_a = shl i32 %b, 1
3941 %two_a_plus_b = add i32 %not_two_a, %b
3942 %mul = mul i32 %two_a_plus_b, %b
3943 %add = add i32 %mul, %a_sq
3947 define i32 @add_reduce_sqr_sum_varB_invalid0(i32 %a, i32 %b) {
3948 ; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid0(
3949 ; CHECK-NEXT: [[NOT_A_B:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3950 ; CHECK-NEXT: [[TWOAB:%.*]] = shl nuw i32 [[NOT_A_B]], 1
3951 ; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
3952 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B:%.*]], [[B]]
3953 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3954 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3955 ; CHECK-NEXT: ret i32 [[AB2]]
3957 %not_a_b = mul nsw i32 %a, %a
3958 %twoab = mul i32 %not_a_b, 2
3959 %a_sq = mul i32 %a, %a
3960 %b_sq = mul i32 %b, %b
3961 %a2_b2 = add i32 %a_sq, %b_sq
3962 %ab2 = add i32 %twoab, %a2_b2
3966 define i32 @add_reduce_sqr_sum_varB_invalid1(i32 %a, i32 %b) {
3967 ; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid1(
3968 ; CHECK-NEXT: [[NOT_A_B:%.*]] = mul nsw i32 [[B:%.*]], [[B]]
3969 ; CHECK-NEXT: [[TWOAB:%.*]] = shl nuw i32 [[NOT_A_B]], 1
3970 ; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A:%.*]], [[A]]
3971 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3972 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3973 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3974 ; CHECK-NEXT: ret i32 [[AB2]]
3976 %not_a_b = mul nsw i32 %b, %b
3977 %twoab = mul i32 %not_a_b, 2
3978 %a_sq = mul i32 %a, %a
3979 %b_sq = mul i32 %b, %b
3980 %a2_b2 = add i32 %a_sq, %b_sq
3981 %ab2 = add i32 %twoab, %a2_b2
3985 define i32 @add_reduce_sqr_sum_varB_invalid2(i32 %a, i32 %b) {
3986 ; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid2(
3987 ; CHECK-NEXT: [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]
3988 ; CHECK-NEXT: [[NOT_TWOAB:%.*]] = shl i32 [[A_B]], 2
3989 ; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
3990 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3991 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3992 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[NOT_TWOAB]], [[A2_B2]]
3993 ; CHECK-NEXT: ret i32 [[AB2]]
3995 %a_b = mul nsw i32 %a, %b
3996 %not_twoab = mul i32 %a_b, 4
3997 %a_sq = mul i32 %a, %a
3998 %b_sq = mul i32 %b, %b
3999 %a2_b2 = add i32 %a_sq, %b_sq
4000 %ab2 = add i32 %not_twoab, %a2_b2
4004 define i32 @add_reduce_sqr_sum_varB_invalid3(i32 %a, i32 %b) {
4005 ; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid3(
4006 ; CHECK-NEXT: [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]
4007 ; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[A_B]], 1
4008 ; CHECK-NEXT: [[B_SQ1:%.*]] = add i32 [[A]], [[B]]
4009 ; CHECK-NEXT: [[A2_B2:%.*]] = mul i32 [[B_SQ1]], [[B]]
4010 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4011 ; CHECK-NEXT: ret i32 [[AB2]]
4013 %a_b = mul nsw i32 %a, %b
4014 %twoab = mul i32 %a_b, 2
4015 %not_a_sq = mul i32 %b, %a
4016 %b_sq = mul i32 %b, %b
4017 %a2_b2 = add i32 %not_a_sq, %b_sq
4018 %ab2 = add i32 %twoab, %a2_b2
4022 define i32 @add_reduce_sqr_sum_varB_invalid4(i32 %a, i32 %b) {
4023 ; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid4(
4024 ; CHECK-NEXT: [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]
4025 ; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[A_B]], 1
4026 ; CHECK-NEXT: [[NOT_B_SQ1:%.*]] = add i32 [[A]], [[B]]
4027 ; CHECK-NEXT: [[A2_B2:%.*]] = mul i32 [[NOT_B_SQ1]], [[A]]
4028 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4029 ; CHECK-NEXT: ret i32 [[AB2]]
4031 %a_b = mul nsw i32 %a, %b
4032 %twoab = mul i32 %a_b, 2
4033 %a_sq = mul i32 %a, %a
4034 %not_b_sq = mul i32 %b, %a
4035 %a2_b2 = add i32 %a_sq, %not_b_sq
4036 %ab2 = add i32 %twoab, %a2_b2
4040 define i32 @add_reduce_sqr_sum_varC_invalid0(i32 %a, i32 %b) {
4041 ; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid0(
4042 ; CHECK-NEXT: [[NOT_TWOA:%.*]] = shl nsw i32 [[B:%.*]], 1
4043 ; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[NOT_TWOA]], [[B]]
4044 ; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A:%.*]], [[A]]
4045 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
4046 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4047 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4048 ; CHECK-NEXT: ret i32 [[AB2]]
4050 %not_twoa = mul nsw i32 %b, 2
4051 %twoab = mul i32 %not_twoa, %b
4052 %a_sq = mul i32 %a, %a
4053 %b_sq = mul i32 %b, %b
4054 %a2_b2 = add i32 %a_sq, %b_sq
4055 %ab2 = add i32 %twoab, %a2_b2
4059 define i32 @add_reduce_sqr_sum_varC_invalid1(i32 %a, i32 %b) {
4060 ; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid1(
4061 ; CHECK-NEXT: [[NOT_TWOA:%.*]] = shl nsw i32 [[A:%.*]], 2
4062 ; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[NOT_TWOA]], [[B:%.*]]
4063 ; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
4064 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
4065 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4066 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4067 ; CHECK-NEXT: ret i32 [[AB2]]
4069 %not_twoa = mul nsw i32 %a, 4
4070 %twoab = mul i32 %not_twoa, %b
4071 %a_sq = mul i32 %a, %a
4072 %b_sq = mul i32 %b, %b
4073 %a2_b2 = add i32 %a_sq, %b_sq
4074 %ab2 = add i32 %twoab, %a2_b2
4078 define i32 @add_reduce_sqr_sum_varC_invalid2(i32 %a, i32 %b) {
4079 ; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid2(
4080 ; CHECK-NEXT: [[TWOA:%.*]] = shl nsw i32 [[A:%.*]], 1
4081 ; CHECK-NEXT: [[NOT_TWOAB:%.*]] = mul i32 [[TWOA]], [[A]]
4082 ; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
4083 ; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B:%.*]], [[B]]
4084 ; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4085 ; CHECK-NEXT: [[AB2:%.*]] = add i32 [[NOT_TWOAB]], [[A2_B2]]
4086 ; CHECK-NEXT: ret i32 [[AB2]]
4088 %twoa = mul nsw i32 %a, 2
4089 %not_twoab = mul i32 %twoa, %a
4090 %a_sq = mul i32 %a, %a
4091 %b_sq = mul i32 %b, %b
4092 %a2_b2 = add i32 %a_sq, %b_sq
4093 %ab2 = add i32 %not_twoab, %a2_b2
4097 define i32 @fold_sext_addition_or_disjoint(i8 %x) {
4098 ; CHECK-LABEL: @fold_sext_addition_or_disjoint(
4099 ; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
4100 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 1246
4101 ; CHECK-NEXT: ret i32 [[R]]
4103 %xx = or disjoint i8 %x, 12
4104 %se = sext i8 %xx to i32
4105 %r = add i32 %se, 1234
4109 define i32 @fold_sext_addition_fail(i8 %x) {
4110 ; CHECK-LABEL: @fold_sext_addition_fail(
4111 ; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 12
4112 ; CHECK-NEXT: [[SE:%.*]] = sext i8 [[XX]] to i32
4113 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], 1234
4114 ; CHECK-NEXT: ret i32 [[R]]
4117 %se = sext i8 %xx to i32
4118 %r = add i32 %se, 1234
4122 define i32 @fold_zext_addition_or_disjoint(i8 %x) {
4123 ; CHECK-LABEL: @fold_zext_addition_or_disjoint(
4124 ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
4125 ; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[TMP1]], 1246
4126 ; CHECK-NEXT: ret i32 [[R]]
4128 %xx = or disjoint i8 %x, 12
4129 %se = zext i8 %xx to i32
4130 %r = add i32 %se, 1234
4134 define i32 @fold_zext_addition_or_disjoint2(i8 %x) {
4135 ; CHECK-LABEL: @fold_zext_addition_or_disjoint2(
4136 ; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 4
4137 ; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP1]] to i32
4138 ; CHECK-NEXT: ret i32 [[R]]
4140 %xx = or disjoint i8 %x, 18
4141 %se = zext i8 %xx to i32
4142 %r = add i32 %se, -14
4146 define i32 @fold_zext_addition_fail(i8 %x) {
4147 ; CHECK-LABEL: @fold_zext_addition_fail(
4148 ; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 12
4149 ; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i32
4150 ; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SE]], 1234
4151 ; CHECK-NEXT: ret i32 [[R]]
4154 %se = zext i8 %xx to i32
4155 %r = add i32 %se, 1234
4159 define i32 @fold_zext_addition_fail2(i8 %x) {
4160 ; CHECK-LABEL: @fold_zext_addition_fail2(
4161 ; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 18
4162 ; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i32
4163 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], -14
4164 ; CHECK-NEXT: ret i32 [[R]]
4167 %se = zext i8 %xx to i32
4168 %r = add i32 %se, -14
4172 define i32 @fold_zext_nneg_add_const(i8 %x) {
4173 ; CHECK-LABEL: @fold_zext_nneg_add_const(
4174 ; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
4175 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 98
4176 ; CHECK-NEXT: ret i32 [[R]]
4178 %xx = add nsw i8 %x, 123
4179 %ze = zext nneg i8 %xx to i32
4180 %r = add nsw i32 %ze, -25
4184 define i32 @fold_zext_nneg_add_const_fail1(i8 %x) {
4185 ; CHECK-LABEL: @fold_zext_nneg_add_const_fail1(
4186 ; CHECK-NEXT: [[XX:%.*]] = add nsw i8 [[X:%.*]], 123
4187 ; CHECK-NEXT: [[ZE:%.*]] = zext i8 [[XX]] to i32
4188 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[ZE]], -25
4189 ; CHECK-NEXT: ret i32 [[R]]
4191 %xx = add nsw i8 %x, 123
4192 %ze = zext i8 %xx to i32
4193 %r = add nsw i32 %ze, -25
4197 define i32 @fold_zext_nneg_add_const_fail2(i8 %x) {
4198 ; CHECK-LABEL: @fold_zext_nneg_add_const_fail2(
4199 ; CHECK-NEXT: [[XX:%.*]] = add i8 [[X:%.*]], 123
4200 ; CHECK-NEXT: [[ZE:%.*]] = zext nneg i8 [[XX]] to i32
4201 ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[ZE]], -25
4202 ; CHECK-NEXT: ret i32 [[R]]
4204 %xx = add i8 %x, 123
4205 %ze = zext nneg i8 %xx to i32
4206 %r = add nsw i32 %ze, -25
4210 declare void @llvm.assume(i1)
4211 declare void @fake_func(i32)