4538 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3; RUN: opt < %s -passes=instcombine -use-constant-int-for-fixed-length-splat -S | FileCheck %s4 5declare void @use(i8)6declare void @use_i1(i1)7 8define i32 @select_0_or_1_from_bool(i1 %x) {9; CHECK-LABEL: @select_0_or_1_from_bool(10; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true11; CHECK-NEXT: [[ADD:%.*]] = zext i1 [[NOT_X]] to i3212; CHECK-NEXT: ret i32 [[ADD]]13;14 %ext = sext i1 %x to i3215 %add = add i32 %ext, 116 ret i32 %add17}18 19define <2 x i32> @select_0_or_1_from_bool_vec(<2 x i1> %x) {20; CHECK-LABEL: @select_0_or_1_from_bool_vec(21; CHECK-NEXT: [[NOT_X:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true)22; CHECK-NEXT: [[ADD:%.*]] = zext <2 x i1> [[NOT_X]] to <2 x i32>23; CHECK-NEXT: ret <2 x i32> [[ADD]]24;25 %ext = sext <2 x i1> %x to <2 x i32>26 %add = add <2 x i32> %ext, <i32 1, i32 1>27 ret <2 x i32> %add28}29 30define i32 @select_C_minus_1_or_C_from_bool(i1 %x) {31; CHECK-LABEL: @select_C_minus_1_or_C_from_bool(32; CHECK-NEXT: [[ADD:%.*]] = select i1 [[X:%.*]], i32 41, i32 4233; CHECK-NEXT: ret i32 [[ADD]]34;35 %ext = sext i1 %x to i3236 %add = add i32 %ext, 4237 ret i32 %add38}39 40define <2 x i32> @select_C_minus_1_or_C_from_bool_vec(<2 x i1> %x) {41; CHECK-LABEL: @select_C_minus_1_or_C_from_bool_vec(42; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 41, i32 42>, <2 x i32> <i32 42, i32 43>43; CHECK-NEXT: ret <2 x i32> [[ADD]]44;45 %ext = sext <2 x i1> %x to <2 x i32>46 %add = add <2 x i32> %ext, <i32 42, i32 43>47 ret <2 x i32> %add48}49 50; This is an 'andn' of the low bit.51 52define i32 @flip_and_mask(i32 %x) {53; CHECK-LABEL: @flip_and_mask(54; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 155; CHECK-NEXT: [[INC:%.*]] = xor i32 [[TMP1]], 156; CHECK-NEXT: ret i32 [[INC]]57;58 %shl = shl i32 %x, 3159 %shr = ashr i32 %shl, 3160 %inc = add i32 %shr, 161 ret i32 %inc62}63 64define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) {65; CHECK-LABEL: @flip_and_mask_splat(66; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 1)67; CHECK-NEXT: [[INC:%.*]] = xor <2 x i8> [[TMP1]], splat (i8 1)68; CHECK-NEXT: ret <2 x i8> [[INC]]69;70 %shl = shl <2 x i8> %x, <i8 7, i8 7>71 %shr = ashr <2 x i8> %shl, <i8 7, i8 7>72 %inc = add <2 x i8> %shr, <i8 1, i8 1>73 ret <2 x i8> %inc74}75 76define i32 @test1(i32 %A) {77; CHECK-LABEL: @test1(78; CHECK-NEXT: ret i32 [[A:%.*]]79;80 %B = add i32 %A, 081 ret i32 %B82}83 84define i32 @test2(i32 %A) {85; CHECK-LABEL: @test2(86; CHECK-NEXT: ret i32 [[A:%.*]]87;88 %B = add i32 %A, 589 %C = add i32 %B, -590 ret i32 %C91}92 93define i32 @test3(i32 %A) {94; CHECK-LABEL: @test3(95; CHECK-NEXT: ret i32 [[A:%.*]]96;97 %B = add i32 %A, 598 %C = sub i32 %B, 599 ret i32 %C100}101 102; D = B + -A = B - A103define i32 @test4(i32 %A, i32 %BB) {104; CHECK-LABEL: @test4(105; CHECK-NEXT: [[B:%.*]] = xor i32 [[BB:%.*]], 1106; CHECK-NEXT: [[D:%.*]] = sub i32 [[B]], [[A:%.*]]107; CHECK-NEXT: ret i32 [[D]]108;109 %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization110 %C = sub i32 0, %A111 %D = add i32 %B, %C112 ret i32 %D113}114 115define i32 @test4_both_nsw(i32 %A, i32 %BB) {116; CHECK-LABEL: @test4_both_nsw(117; CHECK-NEXT: [[B:%.*]] = xor i32 [[BB:%.*]], 1118; CHECK-NEXT: [[D:%.*]] = sub nsw i32 [[B]], [[A:%.*]]119; CHECK-NEXT: ret i32 [[D]]120;121 %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization122 %C = sub nsw i32 0, %A123 %D = add nsw i32 %B, %C124 ret i32 %D125}126 127define i32 @test4_neg_nsw(i32 %A, i32 %BB) {128; CHECK-LABEL: @test4_neg_nsw(129; CHECK-NEXT: [[B:%.*]] = xor i32 [[BB:%.*]], 1130; CHECK-NEXT: [[D:%.*]] = sub i32 [[B]], [[A:%.*]]131; CHECK-NEXT: ret i32 [[D]]132;133 %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization134 %C = sub nsw i32 0, %A135 %D = add i32 %B, %C136 ret i32 %D137}138 139define i32 @test4_add_nsw(i32 %A, i32 %BB) {140; CHECK-LABEL: @test4_add_nsw(141; CHECK-NEXT: [[B:%.*]] = xor i32 [[BB:%.*]], 1142; CHECK-NEXT: [[D:%.*]] = sub i32 [[B]], [[A:%.*]]143; CHECK-NEXT: ret i32 [[D]]144;145 %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization146 %C = sub i32 0, %A147 %D = add nsw i32 %B, %C148 ret i32 %D149}150 151; D = -A + B = B - A152define i32 @test5(i32 %A, i32 %B) {153; CHECK-LABEL: @test5(154; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]155; CHECK-NEXT: ret i32 [[D]]156;157 %C = sub i32 0, %A158 %D = add i32 %C, %B159 ret i32 %D160}161 162define i32 @test5_both_nsw(i32 %A, i32 %B) {163; CHECK-LABEL: @test5_both_nsw(164; CHECK-NEXT: [[D:%.*]] = sub nsw i32 [[B:%.*]], [[A:%.*]]165; CHECK-NEXT: ret i32 [[D]]166;167 %C = sub nsw i32 0, %A168 %D = add nsw i32 %C, %B169 ret i32 %D170}171 172define i32 @test5_neg_nsw(i32 %A, i32 %B) {173; CHECK-LABEL: @test5_neg_nsw(174; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]175; CHECK-NEXT: ret i32 [[D]]176;177 %C = sub nsw i32 0, %A178 %D = add i32 %C, %B179 ret i32 %D180}181 182define i32 @test5_add_nsw(i32 %A, i32 %B) {183; CHECK-LABEL: @test5_add_nsw(184; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]185; CHECK-NEXT: ret i32 [[D]]186;187 %C = sub i32 0, %A188 %D = add nsw i32 %C, %B189 ret i32 %D190}191 192define <2 x i8> @neg_op0_vec_poison_elt(<2 x i8> %a, <2 x i8> %b) {193; CHECK-LABEL: @neg_op0_vec_poison_elt(194; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[B:%.*]], [[A:%.*]]195; CHECK-NEXT: ret <2 x i8> [[R]]196;197 %nega = sub <2 x i8> <i8 0, i8 poison>, %a198 %r = add <2 x i8> %nega, %b199 ret <2 x i8> %r200}201 202define <2 x i8> @neg_neg_vec_poison_elt(<2 x i8> %a, <2 x i8> %b) {203; CHECK-LABEL: @neg_neg_vec_poison_elt(204; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]]205; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]206; CHECK-NEXT: ret <2 x i8> [[R]]207;208 %nega = sub <2 x i8> <i8 poison, i8 0>, %a209 %negb = sub <2 x i8> <i8 poison, i8 0>, %b210 %r = add <2 x i8> %nega, %negb211 ret <2 x i8> %r212}213 214; C = 7*A+A == 8*A == A << 3215define i32 @test6(i32 %A) {216; CHECK-LABEL: @test6(217; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3218; CHECK-NEXT: ret i32 [[C]]219;220 %B = mul i32 7, %A221 %C = add i32 %B, %A222 ret i32 %C223}224 225; C = A+7*A == 8*A == A << 3226define i32 @test7(i32 %A) {227; CHECK-LABEL: @test7(228; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3229; CHECK-NEXT: ret i32 [[C]]230;231 %B = mul i32 7, %A232 %C = add i32 %A, %B233 ret i32 %C234}235 236; (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0237define i32 @test8(i32 %A, i32 %B) {238; CHECK-LABEL: @test8(239; CHECK-NEXT: [[A1:%.*]] = and i32 [[A:%.*]], 7240; CHECK-NEXT: [[B1:%.*]] = and i32 [[B:%.*]], 128241; CHECK-NEXT: [[C:%.*]] = or disjoint i32 [[A1]], [[B1]]242; CHECK-NEXT: ret i32 [[C]]243;244 %A1 = and i32 %A, 7245 %B1 = and i32 %B, 128246 %C = add i32 %A1, %B1247 ret i32 %C248}249 250define i32 @test9(i32 %A) {251; CHECK-LABEL: @test9(252; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 5253; CHECK-NEXT: ret i32 [[C]]254;255 %B = shl i32 %A, 4256 %C = add i32 %B, %B257 ret i32 %C258}259 260; a != -b261define i1 @test10(i8 %a, i8 %b) {262; CHECK-LABEL: @test10(263; CHECK-NEXT: [[ADD:%.*]] = sub i8 0, [[B:%.*]]264; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], [[ADD]]265; CHECK-NEXT: ret i1 [[C]]266;267 %add = add i8 %a, %b268 %c = icmp ne i8 %add, 0269 ret i1 %c270}271 272define <2 x i1> @test10vec(<2 x i8> %a, <2 x i8> %b) {273; CHECK-LABEL: @test10vec(274; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> zeroinitializer, [[B:%.*]]275; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> [[A:%.*]], [[C]]276; CHECK-NEXT: ret <2 x i1> [[D]]277;278 %c = add <2 x i8> %a, %b279 %d = icmp ne <2 x i8> %c, zeroinitializer280 ret <2 x i1> %d281}282 283define i1 @test11(i8 %A) {284; CHECK-LABEL: @test11(285; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], 1286; CHECK-NEXT: ret i1 [[C]]287;288 %B = add i8 %A, -1289 %c = icmp ne i8 %B, 0290 ret i1 %c291}292 293define <2 x i1> @test11vec(<2 x i8> %a) {294; CHECK-LABEL: @test11vec(295; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], splat (i8 1)296; CHECK-NEXT: ret <2 x i1> [[C]]297;298 %b = add <2 x i8> %a, <i8 -1, i8 -1>299 %c = icmp ne <2 x i8> %b, zeroinitializer300 ret <2 x i1> %c301}302 303define i8 @reassoc_shl1(i8 %x, i8 %y) {304; CHECK-LABEL: @reassoc_shl1(305; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X:%.*]], 1306; CHECK-NEXT: [[R:%.*]] = add i8 [[Y:%.*]], [[REASS_ADD]]307; CHECK-NEXT: ret i8 [[R]]308;309 %a = add i8 %y, %x310 %r = add i8 %a, %x311 ret i8 %r312}313 314define <2 x i8> @reassoc_shl1_commute1(<2 x i8> %x, <2 x i8> %y) {315; CHECK-LABEL: @reassoc_shl1_commute1(316; CHECK-NEXT: [[REASS_ADD:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 1)317; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[Y:%.*]], [[REASS_ADD]]318; CHECK-NEXT: ret <2 x i8> [[R]]319;320 %a = add <2 x i8> %x, %y321 %r = add <2 x i8> %a, %x322 ret <2 x i8> %r323}324 325define i8 @reassoc_shl1_commute2(i8 %px, i8 %py) {326; CHECK-LABEL: @reassoc_shl1_commute2(327; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[PX:%.*]]328; CHECK-NEXT: [[Y:%.*]] = sdiv i8 43, [[PY:%.*]]329; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X]], 1330; CHECK-NEXT: [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]]331; CHECK-NEXT: ret i8 [[R]]332;333 %x = sdiv i8 42, %px ; thwart complexity-based canonicalization334 %y = sdiv i8 43, %py ; thwart complexity-based canonicalization335 %a = add i8 %y, %x336 %r = add i8 %x, %a337 ret i8 %r338}339 340define i8 @reassoc_shl1_commute3(i8 %px, i8 %py) {341; CHECK-LABEL: @reassoc_shl1_commute3(342; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[PX:%.*]]343; CHECK-NEXT: [[Y:%.*]] = sdiv i8 43, [[PY:%.*]]344; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X]], 1345; CHECK-NEXT: [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]]346; CHECK-NEXT: ret i8 [[R]]347;348 %x = sdiv i8 42, %px ; thwart complexity-based canonicalization349 %y = sdiv i8 43, %py ; thwart complexity-based canonicalization350 %a = add i8 %x, %y351 %r = add i8 %x, %a352 ret i8 %r353}354 355define i8 @reassoc_shl1_extra_use(i8 %x, i8 %y) {356; CHECK-LABEL: @reassoc_shl1_extra_use(357; CHECK-NEXT: [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]]358; CHECK-NEXT: call void @use(i8 [[A]])359; CHECK-NEXT: [[R:%.*]] = add i8 [[A]], [[X]]360; CHECK-NEXT: ret i8 [[R]]361;362 %a = add i8 %y, %x363 call void @use(i8 %a)364 %r = add i8 %a, %x365 ret i8 %r366}367 368;; TODO: shl A, 1?369define i32 @test13(i32 %A, i32 %B, i32 %C) {370; CHECK-LABEL: @test13(371; CHECK-NEXT: [[D_OK:%.*]] = add i32 [[A:%.*]], [[B:%.*]]372; CHECK-NEXT: [[E_OK:%.*]] = add i32 [[D_OK]], [[C:%.*]]373; CHECK-NEXT: [[F:%.*]] = add i32 [[E_OK]], [[A]]374; CHECK-NEXT: ret i32 [[F]]375;376 %D_OK = add i32 %A, %B377 %E_OK = add i32 %D_OK, %C378 %F = add i32 %E_OK, %A379 ret i32 %F380}381 382define i32 @test14(i32 %offset, i32 %difference) {383; CHECK-LABEL: @test14(384; CHECK-NEXT: [[TMP_2:%.*]] = and i32 [[DIFFERENCE:%.*]], 3385; CHECK-NEXT: [[TMP_3_OK:%.*]] = add i32 [[TMP_2]], [[OFFSET:%.*]]386; CHECK-NEXT: [[TMP_5_MASK:%.*]] = and i32 [[DIFFERENCE]], -4387; CHECK-NEXT: [[TMP_8:%.*]] = add i32 [[TMP_3_OK]], [[TMP_5_MASK]]388; CHECK-NEXT: ret i32 [[TMP_8]]389;390 %tmp.2 = and i32 %difference, 3391 %tmp.3_OK = add i32 %tmp.2, %offset392 %tmp.5.mask = and i32 %difference, -4393 ; == add %offset, %difference394 %tmp.8 = add i32 %tmp.3_OK, %tmp.5.mask395 ret i32 %tmp.8396}397 398; Only one bit set399define i8 @test15(i8 %A) {400; CHECK-LABEL: @test15(401; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 16402; CHECK-NEXT: ret i8 [[C]]403;404 %B = add i8 %A, -64405 %C = and i8 %B, 16406 ret i8 %C407}408 409define i32 @test17(i32 %A) {410; CHECK-LABEL: @test17(411; CHECK-NEXT: [[C:%.*]] = sub i32 0, [[A:%.*]]412; CHECK-NEXT: ret i32 [[C]]413;414 %B = xor i32 %A, -1415 %C = add i32 %B, 1416 ret i32 %C417}418 419define i8 @test18(i8 %A) {420; CHECK-LABEL: @test18(421; CHECK-NEXT: [[C:%.*]] = sub i8 16, [[A:%.*]]422; CHECK-NEXT: ret i8 [[C]]423;424 %B = xor i8 %A, -1425 %C = add i8 %B, 17426 ret i8 %C427}428 429; ~X + -127 and (-128) - X with nsw are equally poisonous430define i8 @test18_nsw(i8 %A) {431; CHECK-LABEL: @test18_nsw(432; CHECK-NEXT: [[C:%.*]] = sub nsw i8 -128, [[A:%.*]]433; CHECK-NEXT: ret i8 [[C]]434;435 %B = xor i8 %A, -1436 %C = add nsw i8 %B, -127437 ret i8 %C438}439 440; nuw couldn't propagate as nsw is.441define i8 @test18_nuw(i8 %A) {442; CHECK-LABEL: @test18_nuw(443; CHECK-NEXT: [[C:%.*]] = sub i8 -128, [[A:%.*]]444; CHECK-NEXT: ret i8 [[C]]445;446 %B = xor i8 %A, -1447 %C = add nuw i8 %B, -127448 ret i8 %C449}450 451; 127 - X with nsw will be more poisonous than ~X + -128 with nsw. (see X = -1)452define i8 @test18_nsw_overflow(i8 %A) {453; CHECK-LABEL: @test18_nsw_overflow(454; CHECK-NEXT: [[C:%.*]] = sub i8 127, [[A:%.*]]455; CHECK-NEXT: ret i8 [[C]]456;457 %B = xor i8 %A, -1458 %C = add nsw i8 %B, -128459 ret i8 %C460}461 462define <2 x i64> @test18vec(<2 x i64> %A) {463; CHECK-LABEL: @test18vec(464; CHECK-NEXT: [[ADD:%.*]] = sub <2 x i64> <i64 1, i64 2>, [[A:%.*]]465; CHECK-NEXT: ret <2 x i64> [[ADD]]466;467 %xor = xor <2 x i64> %A, <i64 -1, i64 -1>468 %add = add <2 x i64> %xor, <i64 2, i64 3>469 ret <2 x i64> %add470}471 472define <2 x i8> @test18vec_nsw(<2 x i8> %A) {473; CHECK-LABEL: @test18vec_nsw(474; CHECK-NEXT: [[C:%.*]] = sub nsw <2 x i8> <i8 -124, i8 -125>, [[A:%.*]]475; CHECK-NEXT: ret <2 x i8> [[C]]476;477 %B = xor <2 x i8> %A, <i8 -1, i8 -1>478 %C = add nsw <2 x i8> %B, <i8 -123, i8 -124>479 ret <2 x i8> %C480}481 482define <2 x i8> @test18vec_nsw_false(<2 x i8> %A) {483; CHECK-LABEL: @test18vec_nsw_false(484; CHECK-NEXT: [[C:%.*]] = sub nsw <2 x i8> <i8 -125, i8 -126>, [[A:%.*]]485; CHECK-NEXT: ret <2 x i8> [[C]]486;487 %B = xor <2 x i8> %A, <i8 -1, i8 -1>488 %C = add nsw <2 x i8> %B, <i8 -124, i8 -125>489 ret <2 x i8> %C490}491 492 493define <2 x i8> @test18vec_nuw(<2 x i8> %A) {494; CHECK-LABEL: @test18vec_nuw(495; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> <i8 -128, i8 -127>, [[A:%.*]]496; CHECK-NEXT: ret <2 x i8> [[C]]497;498 %B = xor <2 x i8> %A, <i8 -1, i8 -1>499 %C = add nuw <2 x i8> %B, <i8 -127, i8 -126>500 ret <2 x i8> %C501}502 503define <2 x i8> @test18vec_nsw_overflow(<2 x i8> %A) {504; CHECK-LABEL: @test18vec_nsw_overflow(505; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> <i8 -128, i8 127>, [[A:%.*]]506; CHECK-NEXT: ret <2 x i8> [[C]]507;508 %B = xor <2 x i8> %A, <i8 -1, i8 -1>509 %C = add nsw <2 x i8> %B, <i8 -127, i8 -128>510 ret <2 x i8> %C511}512 513define i32 @test19(i1 %C) {514; CHECK-LABEL: @test19(515; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133516; CHECK-NEXT: ret i32 [[V]]517;518 %A = select i1 %C, i32 1000, i32 10519 %V = add i32 %A, 123520 ret i32 %V521}522 523define <2 x i32> @test19vec(i1 %C) {524; CHECK-LABEL: @test19vec(525; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 1123), <2 x i32> splat (i32 133)526; CHECK-NEXT: ret <2 x i32> [[V]]527;528 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>529 %V = add <2 x i32> %A, <i32 123, i32 123>530 ret <2 x i32> %V531}532 533; This is an InstSimplify fold, but test it here to make sure that534; InstCombine does not prevent the fold.535; With NSW, add of sign bit -> or of sign bit.536 537define i32 @test20(i32 %x) {538; CHECK-LABEL: @test20(539; CHECK-NEXT: ret i32 [[X:%.*]]540;541 %y = xor i32 %x, -2147483648542 %z = add nsw i32 %y, -2147483648543 ret i32 %z544}545 546define i32 @xor_sign_bit(i32 %x) {547; CHECK-LABEL: @xor_sign_bit(548; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], -2147483606549; CHECK-NEXT: ret i32 [[ADD]]550;551 %xor = xor i32 %x, 2147483648552 %add = add i32 %xor, 42553 ret i32 %add554}555 556define <2 x i32> @xor_sign_bit_vec_splat(<2 x i32> %x) {557; CHECK-LABEL: @xor_sign_bit_vec_splat(558; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -2147483606)559; CHECK-NEXT: ret <2 x i32> [[ADD]]560;561 %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648>562 %add = add <2 x i32> %xor, <i32 42, i32 42>563 ret <2 x i32> %add564}565 566; No-wrap info allows converting the add to 'or'.567 568define i8 @add_nsw_signbit(i8 %x) {569; CHECK-LABEL: @add_nsw_signbit(570; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128571; CHECK-NEXT: ret i8 [[Y]]572;573 %y = add nsw i8 %x, -128574 ret i8 %y575}576 577; No-wrap info allows converting the add to 'or'.578 579define i8 @add_nuw_signbit(i8 %x) {580; CHECK-LABEL: @add_nuw_signbit(581; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128582; CHECK-NEXT: ret i8 [[Y]]583;584 %y = add nuw i8 %x, 128585 ret i8 %y586}587 588define i32 @add_nsw_sext_add(i8 %x) {589; CHECK-LABEL: @add_nsw_sext_add(590; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32591; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 398592; CHECK-NEXT: ret i32 [[R]]593;594 %add = add nsw i8 %x, 42595 %ext = sext i8 %add to i32596 %r = add i32 %ext, 356597 ret i32 %r598}599 600; Negative test - extra use of the sext means increase of instructions.601 602define i32 @add_nsw_sext_add_extra_use_1(i8 %x, ptr %p) {603; CHECK-LABEL: @add_nsw_sext_add_extra_use_1(604; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], 42605; CHECK-NEXT: [[EXT:%.*]] = sext i8 [[ADD]] to i32606; CHECK-NEXT: store i32 [[EXT]], ptr [[P:%.*]], align 4607; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[EXT]], 356608; CHECK-NEXT: ret i32 [[R]]609;610 %add = add nsw i8 %x, 42611 %ext = sext i8 %add to i32612 store i32 %ext, ptr %p613 %r = add i32 %ext, 356614 ret i32 %r615}616 617define <2 x i32> @add_nsw_sext_add_vec_extra_use_2(<2 x i8> %x, ptr %p) {618; CHECK-LABEL: @add_nsw_sext_add_vec_extra_use_2(619; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i8> [[X:%.*]], <i8 42, i8 -5>620; CHECK-NEXT: store <2 x i8> [[ADD]], ptr [[P:%.*]], align 2621; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32>622; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 398, i32 7>623; CHECK-NEXT: ret <2 x i32> [[R]]624;625 %add = add nsw <2 x i8> %x, <i8 42, i8 -5>626 store <2 x i8> %add, ptr %p627 %ext = sext <2 x i8> %add to <2 x i32>628 %r = add <2 x i32> %ext, <i32 356, i32 12>629 ret <2 x i32> %r630}631 632define <2 x i32> @add_nuw_zext_add_vec(<2 x i16> %x) {633; CHECK-LABEL: @add_nuw_zext_add_vec(634; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i32>635; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 65850, i32 -7>636; CHECK-NEXT: ret <2 x i32> [[R]]637;638 %add = add nuw <2 x i16> %x, <i16 -42, i16 5>639 %ext = zext <2 x i16> %add to <2 x i32>640 %r = add <2 x i32> %ext, <i32 356, i32 -12>641 ret <2 x i32> %r642}643 644; Negative test - extra use of the zext means increase of instructions.645 646define i64 @add_nuw_zext_add_extra_use_1(i8 %x, ptr %p) {647; CHECK-LABEL: @add_nuw_zext_add_extra_use_1(648; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42649; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[ADD]] to i64650; CHECK-NEXT: store i64 [[EXT]], ptr [[P:%.*]], align 4651; CHECK-NEXT: [[R:%.*]] = add nuw nsw i64 [[EXT]], 356652; CHECK-NEXT: ret i64 [[R]]653;654 %add = add nuw i8 %x, 42655 %ext = zext i8 %add to i64656 store i64 %ext, ptr %p657 %r = add i64 %ext, 356658 ret i64 %r659}660 661define i64 @add_nuw_zext_add_extra_use_2(i8 %x, ptr %p) {662; CHECK-LABEL: @add_nuw_zext_add_extra_use_2(663; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42664; CHECK-NEXT: store i8 [[ADD]], ptr [[P:%.*]], align 1665; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i64666; CHECK-NEXT: [[R:%.*]] = add nuw nsw i64 [[TMP1]], -314667; CHECK-NEXT: ret i64 [[R]]668;669 %add = add nuw i8 %x, 42670 store i8 %add, ptr %p671 %ext = zext i8 %add to i64672 %r = add i64 %ext, -356673 ret i64 %r674}675 676define i1 @test21(i32 %x) {677; CHECK-LABEL: @test21(678; CHECK-NEXT: [[Y:%.*]] = icmp eq i32 [[X:%.*]], 119679; CHECK-NEXT: ret i1 [[Y]]680;681 %t = add i32 %x, 4682 %y = icmp eq i32 %t, 123683 ret i1 %y684}685 686define <2 x i1> @test21vec(<2 x i32> %x) {687; CHECK-LABEL: @test21vec(688; CHECK-NEXT: [[Y:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 119)689; CHECK-NEXT: ret <2 x i1> [[Y]]690;691 %t = add <2 x i32> %x, <i32 4, i32 4>692 %y = icmp eq <2 x i32> %t, <i32 123, i32 123>693 ret <2 x i1> %y694}695 696define i32 @test22(i32 %V) {697; CHECK-LABEL: @test22(698; CHECK-NEXT: switch i32 [[V:%.*]], label [[DEFAULT:%.*]] [699; CHECK-NEXT: i32 10, label [[LAB1:%.*]]700; CHECK-NEXT: i32 20, label [[LAB2:%.*]]701; CHECK-NEXT: ]702; CHECK: Default:703; CHECK-NEXT: ret i32 123704; CHECK: Lab1:705; CHECK-NEXT: ret i32 12312706; CHECK: Lab2:707; CHECK-NEXT: ret i32 1231231708;709 %V2 = add i32 %V, 10710 switch i32 %V2, label %Default [711 i32 20, label %Lab1712 i32 30, label %Lab2713 ]714 715Default: ; preds = %0716 ret i32 123717 718Lab1: ; preds = %0719 ret i32 12312720 721Lab2: ; preds = %0722 ret i32 1231231723}724 725define i32 @test23(i1 %C, i32 %a) {726; CHECK-LABEL: @test23(727; CHECK-NEXT: entry:728; CHECK-NEXT: br i1 [[C:%.*]], label [[ENDIF:%.*]], label [[ELSE:%.*]]729; CHECK: else:730; CHECK-NEXT: br label [[ENDIF]]731; CHECK: endif:732; CHECK-NEXT: [[B_0:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[ELSE]] ]733; CHECK-NEXT: ret i32 [[B_0]]734;735entry:736 br i1 %C, label %endif, label %else737 738else: ; preds = %entry739 br label %endif740 741endif: ; preds = %else, %entry742 %b.0 = phi i32 [ 0, %entry ], [ 1, %else ]743 %tmp.4 = add i32 %b.0, 1744 ret i32 %tmp.4745}746 747define i32 @test24(i32 %A) {748; CHECK-LABEL: @test24(749; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1750; CHECK-NEXT: ret i32 [[B]]751;752 %B = add i32 %A, 1753 %C = shl i32 %B, 1754 %D = sub i32 %C, 2755 ret i32 %D756}757 758define i64 @test25(i64 %Y) {759; CHECK-LABEL: @test25(760; CHECK-NEXT: [[TMP_8:%.*]] = shl i64 [[Y:%.*]], 3761; CHECK-NEXT: ret i64 [[TMP_8]]762;763 %tmp.4 = shl i64 %Y, 2764 %tmp.12 = shl i64 %Y, 2765 %tmp.8 = add i64 %tmp.4, %tmp.12766 ret i64 %tmp.8767}768 769define i32 @test26(i32 %A, i32 %B) {770; CHECK-LABEL: @test26(771; CHECK-NEXT: ret i32 [[A:%.*]]772;773 %C = add i32 %A, %B774 %D = sub i32 %C, %B775 ret i32 %D776}777 778; Fold add through select.779define i32 @test27(i1 %C, i32 %X, i32 %Y) {780; CHECK-LABEL: @test27(781; CHECK-NEXT: [[C_UPGRD_1_V:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 123782; CHECK-NEXT: ret i32 [[C_UPGRD_1_V]]783;784 %A = add i32 %X, %Y785 %B = add i32 %Y, 123786 %C.upgrd.1 = select i1 %C, i32 %A, i32 %B787 %D = sub i32 %C.upgrd.1, %Y788 ret i32 %D789}790 791define i32 @test28(i32 %X) {792; CHECK-LABEL: @test28(793; CHECK-NEXT: [[Z:%.*]] = sub i32 -1192, [[X:%.*]]794; CHECK-NEXT: ret i32 [[Z]]795;796 %Y = add i32 %X, 1234797 %Z = sub i32 42, %Y798 ret i32 %Z799}800 801define i32 @test29(i32 %x, i32 %y) {802; CHECK-LABEL: @test29(803; CHECK-NEXT: [[TMP_2:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]804; CHECK-NEXT: [[TMP_7:%.*]] = and i32 [[X]], 63805; CHECK-NEXT: [[TMP_9:%.*]] = and i32 [[TMP_2]], -64806; CHECK-NEXT: [[TMP_10:%.*]] = or disjoint i32 [[TMP_7]], [[TMP_9]]807; CHECK-NEXT: ret i32 [[TMP_10]]808;809 %tmp.2 = sub i32 %x, %y810 %tmp.2.mask = and i32 %tmp.2, 63811 %tmp.6 = add i32 %tmp.2.mask, %y812 %tmp.7 = and i32 %tmp.6, 63813 %tmp.9 = and i32 %tmp.2, -64814 %tmp.10 = or i32 %tmp.7, %tmp.9815 ret i32 %tmp.10816}817 818; Add of sign bit -> xor of sign bit.819define i64 @test30(i64 %x) {820; CHECK-LABEL: @test30(821; CHECK-NEXT: ret i64 [[X:%.*]]822;823 %tmp.2 = xor i64 %x, -9223372036854775808824 %tmp.4 = add i64 %tmp.2, -9223372036854775808825 ret i64 %tmp.4826}827 828define i32 @test31(i32 %A) {829; CHECK-LABEL: @test31(830; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[A:%.*]], 5831; CHECK-NEXT: ret i32 [[TMP1]]832;833 %B = add i32 %A, 4834 %C = mul i32 %B, 5835 %D = sub i32 %C, 20836 ret i32 %D837}838 839define i32 @test32(i32 %A) {840; CHECK-LABEL: @test32(841; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 2842; CHECK-NEXT: ret i32 [[B]]843;844 %B = add i32 %A, 4845 %C = shl i32 %B, 2846 %D = sub i32 %C, 16847 ret i32 %D848}849 850define i8 @test33(i8 %A) {851; CHECK-LABEL: @test33(852; CHECK-NEXT: [[C:%.*]] = or i8 [[A:%.*]], 1853; CHECK-NEXT: ret i8 [[C]]854;855 %B = and i8 %A, -2856 %C = add i8 %B, 1857 ret i8 %C858}859 860define i8 @test34(i8 %A) {861; CHECK-LABEL: @test34(862; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 12863; CHECK-NEXT: ret i8 [[C]]864;865 %B = add i8 %A, 64866 %C = and i8 %B, 12867 ret i8 %C868}869 870; If all bits affected by the add are included871; in the mask, do the mask op before the add.872 873define i8 @masked_add(i8 %x) {874; CHECK-LABEL: @masked_add(875; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], -16876; CHECK-NEXT: [[R:%.*]] = add i8 [[AND]], 96877; CHECK-NEXT: ret i8 [[R]]878;879 %and = and i8 %x, 240 ; 0xf0880 %r = add i8 %and, 96 ; 0x60881 ret i8 %r882}883 884define <2 x i8> @masked_add_splat(<2 x i8> %x) {885; CHECK-LABEL: @masked_add_splat(886; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 -64)887; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[AND]], splat (i8 64)888; CHECK-NEXT: ret <2 x i8> [[R]]889;890 %and = and <2 x i8> %x, <i8 192, i8 192> ; 0xc0891 %r = add <2 x i8> %and, <i8 64, i8 64> ; 0x40892 ret <2 x i8> %r893}894 895define i8 @not_masked_add(i8 %x) {896; CHECK-LABEL: @not_masked_add(897; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 112898; CHECK-NEXT: [[R:%.*]] = add nuw i8 [[AND]], 96899; CHECK-NEXT: ret i8 [[R]]900;901 %and = and i8 %x, 112 ; 0x70902 %r = add i8 %and, 96 ; 0x60903 ret i8 %r904}905 906define i8 @masked_add_multi_use(i8 %x) {907; CHECK-LABEL: @masked_add_multi_use(908; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], -16909; CHECK-NEXT: [[R:%.*]] = add i8 [[AND]], 96910; CHECK-NEXT: call void @use(i8 [[AND]])911; CHECK-NEXT: ret i8 [[R]]912;913 %and = and i8 %x, -16 ; 0xf0914 %r = add i8 %and, 96 ; 0x60915 call void @use(i8 %and) ; extra use916 ret i8 %r917}918 919define i32 @test35(i32 %a) {920; CHECK-LABEL: @test35(921; CHECK-NEXT: ret i32 -1922;923 %tmpnot = xor i32 %a, -1924 %tmp2 = add i32 %tmpnot, %a925 ret i32 %tmp2926}927 928define i32 @test36(i32 %a) {929; CHECK-LABEL: @test36(930; CHECK-NEXT: ret i32 0931;932 %x = and i32 %a, -2933 %y = and i32 %a, -126934 %z = add i32 %x, %y935 %q = and i32 %z, 1 ; always zero936 ret i32 %q937}938 939define i1 @test37(i32 %a, i32 %b) {940; CHECK-LABEL: @test37(941; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0942; CHECK-NEXT: ret i1 [[CMP]]943;944 %add = add i32 %a, %b945 %cmp = icmp eq i32 %add, %a946 ret i1 %cmp947}948 949define i1 @test38(i32 %a, i32 %b) {950; CHECK-LABEL: @test38(951; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0952; CHECK-NEXT: ret i1 [[CMP]]953;954 %add = add i32 %a, %b955 %cmp = icmp eq i32 %add, %b956 ret i1 %cmp957}958 959define i1 @test39(i32 %a, i32 %b) {960; CHECK-LABEL: @test39(961; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0962; CHECK-NEXT: ret i1 [[CMP]]963;964 %add = add i32 %b, %a965 %cmp = icmp eq i32 %add, %a966 ret i1 %cmp967}968 969define i1 @test40(i32 %a, i32 %b) {970; CHECK-LABEL: @test40(971; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0972; CHECK-NEXT: ret i1 [[CMP]]973;974 %add = add i32 %b, %a975 %cmp = icmp eq i32 %add, %b976 ret i1 %cmp977}978 979; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))980 981define i64 @test41(i32 %a) {982; CHECK-LABEL: @test41(983; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[A:%.*]], 15984; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[TMP1]] to i64985; CHECK-NEXT: ret i64 [[SUB]]986;987 %add = add nuw i32 %a, 16988 %zext = zext i32 %add to i64989 %sub = add i64 %zext, -1990 ret i64 %sub991}992 993define i64 @test41_multiuse_constants_cancel(i32 %a) {994; CHECK-LABEL: @test41_multiuse_constants_cancel(995; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A:%.*]], 1996; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[ADD]] to i64997; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[A]] to i64998; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nuw nsw i64 [[ZEXT]], [[SUB]]999; CHECK-NEXT: ret i64 [[EXTRAUSE]]1000;1001 %add = add nuw i32 %a, 11002 %zext = zext i32 %add to i641003 %sub = add i64 %zext, -11004 %extrause = add i64 %zext, %sub1005 ret i64 %extrause1006}1007 1008; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))1009 1010define <2 x i64> @test41vec(<2 x i32> %a) {1011; CHECK-LABEL: @test41vec(1012; CHECK-NEXT: [[TMP1:%.*]] = add nuw <2 x i32> [[A:%.*]], splat (i32 15)1013; CHECK-NEXT: [[SUB:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>1014; CHECK-NEXT: ret <2 x i64> [[SUB]]1015;1016 %add = add nuw <2 x i32> %a, <i32 16, i32 16>1017 %zext = zext <2 x i32> %add to <2 x i64>1018 %sub = add <2 x i64> %zext, <i64 -1, i64 -1>1019 ret <2 x i64> %sub1020}1021 1022define <2 x i64> @test41vec_and_multiuse(<2 x i32> %a) {1023; CHECK-LABEL: @test41vec_and_multiuse(1024; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i32> [[A:%.*]], splat (i32 16)1025; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i32> [[ADD]] to <2 x i64>1026; CHECK-NEXT: [[REASS_ADD:%.*]] = shl nuw nsw <2 x i64> [[ZEXT]], splat (i64 1)1027; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nsw <2 x i64> [[REASS_ADD]], splat (i64 -1)1028; CHECK-NEXT: ret <2 x i64> [[EXTRAUSE]]1029;1030 %add = add nuw <2 x i32> %a, <i32 16, i32 16>1031 %zext = zext <2 x i32> %add to <2 x i64>1032 %sub = add <2 x i64> %zext, <i64 -1, i64 -1>1033 %extrause = add <2 x i64> %zext, %sub1034 ret <2 x i64> %extrause1035}1036 1037define i32 @test42(i1 %C) {1038; CHECK-LABEL: @test42(1039; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 1331040; CHECK-NEXT: ret i32 [[V]]1041;1042 %A = select i1 %C, i32 1000, i32 101043 %V = add i32 123, %A1044 ret i32 %V1045}1046 1047define <2 x i32> @test42vec(i1 %C) {1048; CHECK-LABEL: @test42vec(1049; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 1123), <2 x i32> splat (i32 133)1050; CHECK-NEXT: ret <2 x i32> [[V]]1051;1052 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>1053 %V = add <2 x i32> <i32 123, i32 123>, %A1054 ret <2 x i32> %V1055}1056 1057define <2 x i32> @test42vec2(i1 %C) {1058; CHECK-LABEL: @test42vec2(1059; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 2833>, <2 x i32> <i32 133, i32 363>1060; CHECK-NEXT: ret <2 x i32> [[V]]1061;1062 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>1063 %V = add <2 x i32> <i32 123, i32 333>, %A1064 ret <2 x i32> %V1065}1066 1067define i32 @test55(i1 %which) {1068; CHECK-LABEL: @test55(1069; CHECK-NEXT: entry:1070; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]1071; CHECK: delay:1072; CHECK-NEXT: br label [[FINAL]]1073; CHECK: final:1074; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1123, [[ENTRY:%.*]] ], [ 133, [[DELAY]] ]1075; CHECK-NEXT: ret i32 [[A]]1076;1077entry:1078 br i1 %which, label %final, label %delay1079 1080delay:1081 br label %final1082 1083final:1084 %A = phi i32 [ 1000, %entry ], [ 10, %delay ]1085 %value = add i32 123, %A1086 ret i32 %value1087}1088 1089define <2 x i32> @test43vec(i1 %which) {1090; CHECK-LABEL: @test43vec(1091; CHECK-NEXT: entry:1092; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]1093; CHECK: delay:1094; CHECK-NEXT: br label [[FINAL]]1095; CHECK: final:1096; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ splat (i32 1123), [[ENTRY:%.*]] ], [ splat (i32 133), [[DELAY]] ]1097; CHECK-NEXT: ret <2 x i32> [[A]]1098;1099entry:1100 br i1 %which, label %final, label %delay1101 1102delay:1103 br label %final1104 1105final:1106 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]1107 %value = add <2 x i32> <i32 123, i32 123>, %A1108 ret <2 x i32> %value1109}1110 1111define <2 x i32> @test43vec2(i1 %which) {1112; CHECK-LABEL: @test43vec2(1113; CHECK-NEXT: entry:1114; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]1115; CHECK: delay:1116; CHECK-NEXT: br label [[FINAL]]1117; CHECK: final:1118; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 2833>, [[ENTRY:%.*]] ], [ <i32 133, i32 363>, [[DELAY]] ]1119; CHECK-NEXT: ret <2 x i32> [[A]]1120;1121entry:1122 br i1 %which, label %final, label %delay1123 1124delay:1125 br label %final1126 1127final:1128 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]1129 %value = add <2 x i32> <i32 123, i32 333>, %A1130 ret <2 x i32> %value1131}1132 1133; E = (A + 1) + ~B = A - B1134define i32 @add_not_increment(i32 %A, i32 %B) {1135; CHECK-LABEL: @add_not_increment(1136; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]1137; CHECK-NEXT: ret i32 [[E]]1138;1139 %C = xor i32 %B, -11140 %D = add i32 %A, 11141 %E = add i32 %D, %C1142 ret i32 %E1143}1144 1145; E = (A + 1) + ~B = A - B1146define <2 x i32> @add_not_increment_vec(<2 x i32> %A, <2 x i32> %B) {1147; CHECK-LABEL: @add_not_increment_vec(1148; CHECK-NEXT: [[E:%.*]] = sub <2 x i32> [[A:%.*]], [[B:%.*]]1149; CHECK-NEXT: ret <2 x i32> [[E]]1150;1151 %C = xor <2 x i32> %B, <i32 -1, i32 -1>1152 %D = add <2 x i32> %A, <i32 1, i32 1>1153 %E = add <2 x i32> %D, %C1154 ret <2 x i32> %E1155}1156 1157; E = ~B + (1 + A) = A - B1158define i32 @add_not_increment_commuted(i32 %A, i32 %B) {1159; CHECK-LABEL: @add_not_increment_commuted(1160; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]1161; CHECK-NEXT: ret i32 [[E]]1162;1163 %C = xor i32 %B, -11164 %D = add i32 %A, 11165 %E = add i32 %C, %D1166 ret i32 %E1167}1168 1169; E = (A + ~B) + 1 = A - B1170define i32 @add_to_sub(i32 %M, i32 %B) {1171; CHECK-LABEL: @add_to_sub(1172; CHECK-NEXT: [[A:%.*]] = mul i32 [[M:%.*]], 421173; CHECK-NEXT: [[E:%.*]] = sub i32 [[A]], [[B:%.*]]1174; CHECK-NEXT: ret i32 [[E]]1175;1176 %A = mul i32 %M, 42 ; thwart complexity-based ordering1177 %C = xor i32 %B, -11178 %D = add i32 %A, %C1179 %E = add i32 %D, 11180 ret i32 %E1181}1182 1183; E = (~B + A) + 1 = A - B1184define i32 @add_to_sub2(i32 %A, i32 %M) {1185; CHECK-LABEL: @add_to_sub2(1186; CHECK-NEXT: [[B_NEG:%.*]] = mul i32 [[M:%.*]], -421187; CHECK-NEXT: [[E:%.*]] = add i32 [[B_NEG]], [[A:%.*]]1188; CHECK-NEXT: ret i32 [[E]]1189;1190 %B = mul i32 %M, 42 ; thwart complexity-based ordering1191 %C = xor i32 %B, -11192 %D = add i32 %C, %A1193 %E = add i32 %D, 11194 ret i32 %E1195}1196 1197; (X | C1) + C2 --> (X | C1) ^ C1 iff (C1 == -C2)1198define i32 @test44(i32 %A) {1199; CHECK-LABEL: @test44(1200; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], -1241201; CHECK-NEXT: ret i32 [[C]]1202;1203 %B = or i32 %A, 1231204 %C = add i32 %B, -1231205 ret i32 %C1206}1207 1208define i32 @test44_extra_use(i32 %A) {1209; CHECK-LABEL: @test44_extra_use(1210; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 1231211; CHECK-NEXT: [[C:%.*]] = and i32 [[A]], -1241212; CHECK-NEXT: [[D:%.*]] = mul i32 [[B]], [[C]]1213; CHECK-NEXT: ret i32 [[D]]1214;1215 %B = or i32 %A, 1231216 %C = add i32 %B, -1231217 %D = mul i32 %B, %C1218 ret i32 %D1219}1220 1221define i32 @test44_non_matching(i32 %A) {1222; CHECK-LABEL: @test44_non_matching(1223; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 1231224; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], -3211225; CHECK-NEXT: ret i32 [[C]]1226;1227 %B = or i32 %A, 1231228 %C = add i32 %B, -3211229 ret i32 %C1230}1231 1232define <2 x i32> @test44_vec(<2 x i32> %A) {1233; CHECK-LABEL: @test44_vec(1234; CHECK-NEXT: [[C:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -124)1235; CHECK-NEXT: ret <2 x i32> [[C]]1236;1237 %B = or <2 x i32> %A, <i32 123, i32 123>1238 %C = add <2 x i32> %B, <i32 -123, i32 -123>1239 ret <2 x i32> %C1240}1241 1242define <2 x i32> @test44_vec_non_matching(<2 x i32> %A) {1243; CHECK-LABEL: @test44_vec_non_matching(1244; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], splat (i32 123)1245; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], splat (i32 -321)1246; CHECK-NEXT: ret <2 x i32> [[C]]1247;1248 %B = or <2 x i32> %A, <i32 123, i32 123>1249 %C = add <2 x i32> %B, <i32 -321, i32 -321>1250 ret <2 x i32> %C1251}1252 1253define <2 x i32> @test44_vec_poison(<2 x i32> %A) {1254; CHECK-LABEL: @test44_vec_poison(1255; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 poison>1256; CHECK-NEXT: [[C:%.*]] = add nsw <2 x i32> [[B]], <i32 -123, i32 poison>1257; CHECK-NEXT: ret <2 x i32> [[C]]1258;1259 %B = or <2 x i32> %A, <i32 123, i32 poison>1260 %C = add <2 x i32> %B, <i32 -123, i32 poison>1261 ret <2 x i32> %C1262}1263 1264define <2 x i32> @test44_vec_non_splat(<2 x i32> %A) {1265; CHECK-LABEL: @test44_vec_non_splat(1266; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 456>1267; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], <i32 -123, i32 -456>1268; CHECK-NEXT: ret <2 x i32> [[C]]1269;1270 %B = or <2 x i32> %A, <i32 123, i32 456>1271 %C = add <2 x i32> %B, <i32 -123, i32 -456>1272 ret <2 x i32> %C1273}1274 1275define i32 @lshr_add(i1 %x, i1 %y) {1276; CHECK-LABEL: @lshr_add(1277; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true1278; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[Y:%.*]], [[TMP1]]1279; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP2]] to i321280; CHECK-NEXT: ret i32 [[R]]1281;1282 %xz = zext i1 %x to i321283 %ys = sext i1 %y to i321284 %sub = add i32 %xz, %ys1285 %r = lshr i32 %sub, 311286 ret i32 %r1287}1288 1289define i5 @and_add(i1 %x, i1 %y) {1290; CHECK-LABEL: @and_add(1291; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true1292; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[Y:%.*]], [[TMP1]]1293; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i5 -2, i5 01294; CHECK-NEXT: ret i5 [[R]]1295;1296 %xz = zext i1 %x to i51297 %ys = sext i1 %y to i51298 %sub = add i5 %xz, %ys1299 %r = and i5 %sub, 301300 ret i5 %r1301}1302 1303define <2 x i8> @ashr_add_commute(<2 x i1> %x, <2 x i1> %y) {1304; CHECK-LABEL: @ashr_add_commute(1305; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true)1306; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i1> [[Y:%.*]], [[TMP1]]1307; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i8>1308; CHECK-NEXT: ret <2 x i8> [[TMP3]]1309;1310 %xz = zext <2 x i1> %x to <2 x i8>1311 %ys = sext <2 x i1> %y to <2 x i8>1312 %sub = add nsw <2 x i8> %ys, %xz1313 %r = ashr <2 x i8> %sub, <i8 1, i8 1>1314 ret <2 x i8> %r1315}1316 1317define i32 @cmp_math(i32 %x, i32 %y) {1318; CHECK-LABEL: @cmp_math(1319; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]1320; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i321321; CHECK-NEXT: ret i32 [[R]]1322;1323 %gt = icmp ugt i32 %x, %y1324 %lt = icmp ult i32 %x, %y1325 %xz = zext i1 %gt to i321326 %yz = zext i1 %lt to i321327 %s = sub i32 %xz, %yz1328 %r = lshr i32 %s, 311329 ret i32 %r1330}1331 1332; Negative test - wrong type1333 1334define i32 @lshr_add_nonbool(i2 %x, i1 %y) {1335; CHECK-LABEL: @lshr_add_nonbool(1336; CHECK-NEXT: [[XZ:%.*]] = zext i2 [[X:%.*]] to i321337; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i321338; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]1339; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 311340; CHECK-NEXT: ret i32 [[R]]1341;1342 %xz = zext i2 %x to i321343 %ys = sext i1 %y to i321344 %sub = add i32 %xz, %ys1345 %r = lshr i32 %sub, 311346 ret i32 %r1347}1348 1349; Negative test - wrong demand1350 1351define i32 @and31_add(i1 %x, i1 %y) {1352; CHECK-LABEL: @and31_add(1353; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i321354; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i321355; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]1356; CHECK-NEXT: [[R:%.*]] = and i32 [[SUB]], 311357; CHECK-NEXT: ret i32 [[R]]1358;1359 %xz = zext i1 %x to i321360 %ys = sext i1 %y to i321361 %sub = add i32 %xz, %ys1362 %r = and i32 %sub, 311363 ret i32 %r1364}1365 1366; Negative test - extra use1367 1368define i32 @lshr_add_use(i1 %x, i1 %y, ptr %p) {1369; CHECK-LABEL: @lshr_add_use(1370; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i321371; CHECK-NEXT: store i32 [[XZ]], ptr [[P:%.*]], align 41372; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i321373; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]1374; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 311375; CHECK-NEXT: ret i32 [[R]]1376;1377 %xz = zext i1 %x to i321378 store i32 %xz, ptr %p1379 %ys = sext i1 %y to i321380 %sub = add i32 %xz, %ys1381 %r = lshr i32 %sub, 311382 ret i32 %r1383}1384 1385; Negative test - extra use1386 1387define i32 @lshr_add_use2(i1 %x, i1 %y, ptr %p) {1388; CHECK-LABEL: @lshr_add_use2(1389; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i321390; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i321391; CHECK-NEXT: store i32 [[YS]], ptr [[P:%.*]], align 41392; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]1393; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 311394; CHECK-NEXT: ret i32 [[R]]1395;1396 %xz = zext i1 %x to i321397 %ys = sext i1 %y to i321398 store i32 %ys, ptr %p1399 %sub = add i32 %xz, %ys1400 %r = lshr i32 %sub, 311401 ret i32 %r1402}1403 1404define i32 @lshr_add_sexts(i1 %x, i1 %y) {1405; CHECK-LABEL: @lshr_add_sexts(1406; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]1407; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i321408; CHECK-NEXT: ret i32 [[R]]1409;1410 %xs = sext i1 %x to i321411 %ys = sext i1 %y to i321412 %sub = add i32 %xs, %ys1413 %r = lshr i32 %sub, 311414 ret i32 %r1415}1416 1417define i5 @and_add_sexts(i1 %x, i1 %y) {1418; CHECK-LABEL: @and_add_sexts(1419; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]1420; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i5 -2, i5 01421; CHECK-NEXT: ret i5 [[R]]1422;1423 %xs = sext i1 %x to i51424 %ys = sext i1 %y to i51425 %sub = add i5 %xs, %ys1426 %r = and i5 %sub, 301427 ret i5 %r1428}1429 1430define <2 x i8> @ashr_add_sexts(<2 x i1> %x, <2 x i1> %y) {1431; CHECK-LABEL: @ashr_add_sexts(1432; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i1> [[Y:%.*]], [[X:%.*]]1433; CHECK-NEXT: [[TMP2:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>1434; CHECK-NEXT: ret <2 x i8> [[TMP2]]1435;1436 %xs = sext <2 x i1> %x to <2 x i8>1437 %ys = sext <2 x i1> %y to <2 x i8>1438 %sub = add nsw <2 x i8> %ys, %xs1439 %r = ashr <2 x i8> %sub, <i8 1, i8 1>1440 ret <2 x i8> %r1441}1442 1443define i32 @cmp_math_sexts(i32 %x, i32 %y) {1444; CHECK-LABEL: @cmp_math_sexts(1445; CHECK-NEXT: [[DOTNOT:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]1446; CHECK-NEXT: [[R:%.*]] = zext i1 [[DOTNOT]] to i321447; CHECK-NEXT: ret i32 [[R]]1448;1449 %gt = icmp ugt i32 %x, %y1450 %lt = icmp ult i32 %x, %y1451 %xz = sext i1 %gt to i321452 %yz = zext i1 %lt to i321453 %s = sub i32 %xz, %yz1454 %r = lshr i32 %s, 311455 ret i32 %r1456}1457 1458; Negative test - wrong type1459 1460define i32 @lshr_add_nonbool_sexts(i2 %x, i1 %y) {1461; CHECK-LABEL: @lshr_add_nonbool_sexts(1462; CHECK-NEXT: [[XS:%.*]] = sext i2 [[X:%.*]] to i321463; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i321464; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]1465; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 311466; CHECK-NEXT: ret i32 [[R]]1467;1468 %xs = sext i2 %x to i321469 %ys = sext i1 %y to i321470 %sub = add i32 %xs, %ys1471 %r = lshr i32 %sub, 311472 ret i32 %r1473}1474 1475; Negative test - wrong demand1476 1477define i32 @and31_add_sexts(i1 %x, i1 %y) {1478; CHECK-LABEL: @and31_add_sexts(1479; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i321480; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i321481; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]1482; CHECK-NEXT: [[R:%.*]] = and i32 [[SUB]], 311483; CHECK-NEXT: ret i32 [[R]]1484;1485 %xs = sext i1 %x to i321486 %ys = sext i1 %y to i321487 %sub = add i32 %xs, %ys1488 %r = and i32 %sub, 311489 ret i32 %r1490}1491 1492define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {1493; CHECK-LABEL: @lshr_add_use_sexts(1494; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i321495; CHECK-NEXT: store i32 [[YS]], ptr [[P:%.*]], align 41496; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y]]1497; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i321498; CHECK-NEXT: ret i32 [[R]]1499;1500 %xs = sext i1 %x to i321501 %ys = sext i1 %y to i321502 store i32 %ys, ptr %p1503 %sub = add i32 %xs, %ys1504 %r = lshr i32 %sub, 311505 ret i32 %r1506}1507 1508define i32 @lshr_add_use_sexts_2(i1 %x, i1 %y, ptr %p) {1509; CHECK-LABEL: @lshr_add_use_sexts_2(1510; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i321511; CHECK-NEXT: store i32 [[XS]], ptr [[P:%.*]], align 41512; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X]], [[Y:%.*]]1513; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i321514; CHECK-NEXT: ret i32 [[R]]1515;1516 %xs = sext i1 %x to i321517 store i32 %xs, ptr %p1518 %ys = sext i1 %y to i321519 %sub = add i32 %xs, %ys1520 %r = lshr i32 %sub, 311521 ret i32 %r1522}1523 1524; Negative test - extra use1525 1526declare void @use_sexts(i32, i32)1527 1528define i32 @lshr_add_use_sexts_both(i1 %x, i1 %y) {1529; CHECK-LABEL: @lshr_add_use_sexts_both(1530; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i321531; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i321532; CHECK-NEXT: call void @use_sexts(i32 [[XS]], i32 [[YS]])1533; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]1534; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 311535; CHECK-NEXT: ret i32 [[R]]1536;1537 %xs = sext i1 %x to i321538 %ys = sext i1 %y to i321539 call void @use_sexts(i32 %xs, i32 %ys)1540 %sub = add i32 %xs, %ys1541 %r = lshr i32 %sub, 311542 ret i32 %r1543}1544 1545define i8 @add_like_or_t0(i8 %x) {1546; CHECK-LABEL: @add_like_or_t0(1547; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 41548; CHECK-NEXT: [[R:%.*]] = add i8 [[I0]], 571549; CHECK-NEXT: ret i8 [[R]]1550;1551 %i0 = shl i8 %x, 41552 %i1 = or i8 %i0, 15 ; no common bits1553 %r = add i8 %i1, 421554 ret i8 %r1555}1556define i8 @add_like_or_n1(i8 %x) {1557; CHECK-LABEL: @add_like_or_n1(1558; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 41559; CHECK-NEXT: [[I1:%.*]] = or i8 [[I0]], 311560; CHECK-NEXT: [[R:%.*]] = add i8 [[I1]], 421561; CHECK-NEXT: ret i8 [[R]]1562;1563 %i0 = shl i8 %x, 41564 %i1 = or i8 %i0, 31 ; 4'th bit might be common-set1565 %r = add i8 %i1, 421566 ret i8 %r1567}1568define i8 @add_like_or_t2_extrause(i8 %x) {1569; CHECK-LABEL: @add_like_or_t2_extrause(1570; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 41571; CHECK-NEXT: [[I1:%.*]] = or disjoint i8 [[I0]], 151572; CHECK-NEXT: call void @use(i8 [[I1]])1573; CHECK-NEXT: [[R:%.*]] = add i8 [[I0]], 571574; CHECK-NEXT: ret i8 [[R]]1575;1576 %i0 = shl i8 %x, 41577 %i1 = or i8 %i0, 15 ; no common bits1578 call void @use(i8 %i1) ; extra use1579 %r = add i8 %i1, 421580 ret i8 %r1581}1582define i8 @fold_add_constant_preserve_nsw(i8 %x) {1583; CHECK-LABEL: @fold_add_constant_preserve_nsw(1584; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], -1201585; CHECK-NEXT: ret i8 [[ADD]]1586;1587 %or = or disjoint i8 %x, -1281588 %add = add nsw i8 %or, 81589 ret i8 %add1590}1591define i8 @fold_add_constant_no_nsw(i8 %x) {1592; CHECK-LABEL: @fold_add_constant_no_nsw(1593; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X:%.*]], 1201594; CHECK-NEXT: ret i8 [[ADD]]1595;1596 %or = or disjoint i8 %x, -1281597 %add = add nsw i8 %or, -81598 ret i8 %add1599}1600define i8 @fold_add_constant_preserve_nuw(i8 %x) {1601; CHECK-LABEL: @fold_add_constant_preserve_nuw(1602; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], -1161603; CHECK-NEXT: ret i8 [[ADD]]1604;1605 %or = or disjoint i8 %x, 1281606 %add = add nuw i8 %or, 121607 ret i8 %add1608}1609define i32 @sdiv_to_udiv(i32 %arg0, i32 %arg1) {1610; CHECK-LABEL: @sdiv_to_udiv(1611; CHECK-NEXT: [[T0:%.*]] = shl nuw nsw i32 [[ARG0:%.*]], 81612; CHECK-NEXT: [[T2:%.*]] = add nuw nsw i32 [[T0]], 62420491613; CHECK-NEXT: [[T3:%.*]] = udiv i32 [[T2]], 1921614; CHECK-NEXT: ret i32 [[T3]]1615;1616 %t0 = shl nuw nsw i32 %arg0, 81617 %t1 = or disjoint i32 %t0, 11618 %t2 = add nuw nsw i32 %t1, 62420481619 %t3 = sdiv i32 %t2, 1921620 ret i32 %t31621}1622 1623define i8 @add_like_or_disjoint(i8 %x) {1624; CHECK-LABEL: @add_like_or_disjoint(1625; CHECK-NEXT: [[R:%.*]] = add i8 [[X:%.*]], 571626; CHECK-NEXT: ret i8 [[R]]1627;1628 %i1 = or disjoint i8 %x, 151629 %r = add i8 %i1, 421630 ret i8 %r1631}1632 1633define i8 @add_and_xor(i8 noundef %x, i8 %y) {1634; CHECK-LABEL: @add_and_xor(1635; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]1636; CHECK-NEXT: ret i8 [[ADD]]1637;1638 %xor = xor i8 %x, -11639 %and = and i8 %xor, %y1640 %add = add i8 %and, %x1641 ret i8 %add1642}1643 1644define i8 @add_and_xor_wrong_const(i8 %x, i8 %y) {1645; CHECK-LABEL: @add_and_xor_wrong_const(1646; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -21647; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]]1648; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], [[X]]1649; CHECK-NEXT: ret i8 [[ADD]]1650;1651 %xor = xor i8 %x, -21652 %and = and i8 %xor, %y1653 %add = add i8 %and, %x1654 ret i8 %add1655}1656 1657define i8 @add_and_xor_wrong_op(i8 %x, i8 %y, i8 %z) {1658; CHECK-LABEL: @add_and_xor_wrong_op(1659; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Z:%.*]], -11660; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y:%.*]], [[XOR]]1661; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], [[X:%.*]]1662; CHECK-NEXT: ret i8 [[ADD]]1663;1664 %xor = xor i8 %z, -11665 %and = and i8 %xor, %y1666 %add = add i8 %and, %x1667 ret i8 %add1668}1669 1670define i8 @add_and_xor_commuted1(i8 noundef %x, i8 %_y) {1671; CHECK-LABEL: @add_and_xor_commuted1(1672; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]1673; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X:%.*]]1674; CHECK-NEXT: ret i8 [[ADD]]1675;1676 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization1677 %xor = xor i8 %x, -11678 %and = and i8 %y, %xor1679 %add = add i8 %and, %x1680 ret i8 %add1681}1682 1683define i8 @add_and_xor_commuted2(i8 noundef %_x, i8 %y) {1684; CHECK-LABEL: @add_and_xor_commuted2(1685; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]1686; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y:%.*]]1687; CHECK-NEXT: ret i8 [[ADD]]1688;1689 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization1690 %xor = xor i8 %x, -11691 %and = and i8 %xor, %y1692 %add = add i8 %x, %and1693 ret i8 %add1694}1695 1696define i8 @add_and_xor_commuted3(i8 noundef %_x, i8 %_y) {1697; CHECK-LABEL: @add_and_xor_commuted3(1698; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]1699; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]1700; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]]1701; CHECK-NEXT: ret i8 [[ADD]]1702;1703 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization1704 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization1705 %xor = xor i8 %x, -11706 %and = and i8 %y, %xor1707 %add = add i8 %x, %and1708 ret i8 %add1709}1710 1711define i8 @add_and_xor_extra_use(i8 noundef %x, i8 %y) {1712; CHECK-LABEL: @add_and_xor_extra_use(1713; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -11714; CHECK-NEXT: call void @use(i8 [[XOR]])1715; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y:%.*]], [[XOR]]1716; CHECK-NEXT: call void @use(i8 [[AND]])1717; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]1718; CHECK-NEXT: ret i8 [[ADD]]1719;1720 %xor = xor i8 %x, -11721 call void @use(i8 %xor)1722 %and = and i8 %xor, %y1723 call void @use(i8 %and)1724 %add = add i8 %and, %x1725 ret i8 %add1726}1727 1728define i8 @add_xor_and_const(i8 noundef %x) {1729; CHECK-LABEL: @add_xor_and_const(1730; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X:%.*]], 421731; CHECK-NEXT: ret i8 [[ADD]]1732;1733 %and = and i8 %x, 421734 %xor = xor i8 %and, 421735 %add = add i8 %xor, %x1736 ret i8 %add1737}1738 1739define i8 @add_xor_and_const_wrong_const(i8 %x) {1740; CHECK-LABEL: @add_xor_and_const_wrong_const(1741; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 421742; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], 881743; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[X]]1744; CHECK-NEXT: ret i8 [[ADD]]1745;1746 %and = and i8 %x, 421747 %xor = xor i8 %and, 881748 %add = add i8 %xor, %x1749 ret i8 %add1750}1751 1752define i8 @add_xor_and_var(i8 noundef %x, i8 noundef %y) {1753; CHECK-LABEL: @add_xor_and_var(1754; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]1755; CHECK-NEXT: call void @use(i8 [[AND]])1756; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]1757; CHECK-NEXT: ret i8 [[ADD]]1758;1759 %and = and i8 %x, %y1760 call void @use(i8 %and)1761 %xor = xor i8 %and, %y1762 %add = add i8 %xor, %x1763 ret i8 %add1764}1765 1766define i8 @add_xor_and_var_wrong_op1(i8 %x, i8 %y, i8 %z) {1767; CHECK-LABEL: @add_xor_and_var_wrong_op1(1768; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]1769; CHECK-NEXT: call void @use(i8 [[AND]])1770; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Z:%.*]]1771; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[X]]1772; CHECK-NEXT: ret i8 [[ADD]]1773;1774 %and = and i8 %x, %y1775 call void @use(i8 %and)1776 %xor = xor i8 %and, %z1777 %add = add i8 %xor, %x1778 ret i8 %add1779}1780 1781define i8 @add_xor_and_var_wrong_op2(i8 %x, i8 %y, i8 %z) {1782; CHECK-LABEL: @add_xor_and_var_wrong_op2(1783; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]1784; CHECK-NEXT: call void @use(i8 [[AND]])1785; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Y]]1786; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[Z:%.*]]1787; CHECK-NEXT: ret i8 [[ADD]]1788;1789 %and = and i8 %x, %y1790 call void @use(i8 %and)1791 %xor = xor i8 %and, %y1792 %add = add i8 %xor, %z1793 ret i8 %add1794}1795 1796define i8 @add_xor_and_var_commuted1(i8 noundef %x, i8 noundef %y) {1797; CHECK-LABEL: @add_xor_and_var_commuted1(1798; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y:%.*]], [[X:%.*]]1799; CHECK-NEXT: call void @use(i8 [[AND]])1800; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]1801; CHECK-NEXT: ret i8 [[ADD]]1802;1803 %and = and i8 %y, %x1804 call void @use(i8 %and)1805 %xor = xor i8 %and, %y1806 %add = add i8 %xor, %x1807 ret i8 %add1808}1809 1810define i8 @add_xor_and_var_commuted2(i8 noundef %_x, i8 noundef %_y) {1811; CHECK-LABEL: @add_xor_and_var_commuted2(1812; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]1813; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]1814; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]]1815; CHECK-NEXT: call void @use(i8 [[AND]])1816; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]1817; CHECK-NEXT: ret i8 [[ADD]]1818;1819 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization1820 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization1821 %and = and i8 %x, %y1822 call void @use(i8 %and)1823 %xor = xor i8 %y, %and1824 %add = add i8 %xor, %x1825 ret i8 %add1826}1827 1828define i8 @add_xor_and_var_commuted3(i8 noundef %x, i8 noundef %_y) {1829; CHECK-LABEL: @add_xor_and_var_commuted3(1830; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]1831; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X:%.*]]1832; CHECK-NEXT: call void @use(i8 [[AND]])1833; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]1834; CHECK-NEXT: ret i8 [[ADD]]1835;1836 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization1837 %and = and i8 %y, %x1838 call void @use(i8 %and)1839 %xor = xor i8 %y, %and1840 %add = add i8 %xor, %x1841 ret i8 %add1842}1843 1844define i8 @add_xor_and_var_commuted4(i8 noundef %_x, i8 noundef %y) {1845; CHECK-LABEL: @add_xor_and_var_commuted4(1846; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]1847; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y:%.*]]1848; CHECK-NEXT: call void @use(i8 [[AND]])1849; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]]1850; CHECK-NEXT: ret i8 [[ADD]]1851;1852 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization1853 %and = and i8 %x, %y1854 call void @use(i8 %and)1855 %xor = xor i8 %and, %y1856 %add = add i8 %x, %xor1857 ret i8 %add1858}1859 1860define i8 @add_xor_and_var_commuted5(i8 noundef %_x, i8 noundef %_y) {1861; CHECK-LABEL: @add_xor_and_var_commuted5(1862; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]1863; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]1864; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X]]1865; CHECK-NEXT: call void @use(i8 [[AND]])1866; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]]1867; CHECK-NEXT: ret i8 [[ADD]]1868;1869 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization1870 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization1871 %and = and i8 %y, %x1872 call void @use(i8 %and)1873 %xor = xor i8 %and, %y1874 %add = add i8 %x, %xor1875 ret i8 %add1876}1877 1878define i8 @add_xor_and_var_commuted6(i8 noundef %_x, i8 noundef %_y) {1879; CHECK-LABEL: @add_xor_and_var_commuted6(1880; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]1881; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]1882; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]]1883; CHECK-NEXT: call void @use(i8 [[AND]])1884; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]]1885; CHECK-NEXT: ret i8 [[ADD]]1886;1887 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization1888 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization1889 %and = and i8 %x, %y1890 call void @use(i8 %and)1891 %xor = xor i8 %y, %and1892 %add = add i8 %x, %xor1893 ret i8 %add1894}1895 1896define i8 @add_xor_and_var_commuted7(i8 noundef %_x, i8 noundef %_y) {1897; CHECK-LABEL: @add_xor_and_var_commuted7(1898; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]]1899; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]1900; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X]]1901; CHECK-NEXT: call void @use(i8 [[AND]])1902; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]]1903; CHECK-NEXT: ret i8 [[ADD]]1904;1905 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization1906 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization1907 %and = and i8 %y, %x1908 call void @use(i8 %and)1909 %xor = xor i8 %y, %and1910 %add = add i8 %x, %xor1911 ret i8 %add1912}1913 1914define i8 @add_xor_and_var_extra_use(i8 noundef %x, i8 noundef %y) {1915; CHECK-LABEL: @add_xor_and_var_extra_use(1916; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]1917; CHECK-NEXT: call void @use(i8 [[AND]])1918; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Y]]1919; CHECK-NEXT: call void @use(i8 [[XOR]])1920; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]]1921; CHECK-NEXT: ret i8 [[ADD]]1922;1923 %and = and i8 %x, %y1924 call void @use(i8 %and)1925 %xor = xor i8 %and, %y1926 call void @use(i8 %xor)1927 %add = add i8 %xor, %x1928 ret i8 %add1929}1930 1931define i32 @add_add_add(i32 %A, i32 %B, i32 %C, i32 %D) {1932; CHECK-LABEL: @add_add_add(1933; CHECK-NEXT: [[E:%.*]] = add i32 [[A:%.*]], [[B:%.*]]1934; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]]1935; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]]1936; CHECK-NEXT: ret i32 [[G]]1937;1938 %E = add i32 %A, %B1939 %F = add i32 %E, %C1940 %G = add i32 %F, %D1941 ret i32 %G1942}1943 1944define i32 @add_add_add_commute1(i32 %A, i32 %B, i32 %C, i32 %D) {1945; CHECK-LABEL: @add_add_add_commute1(1946; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]1947; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]]1948; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]]1949; CHECK-NEXT: ret i32 [[G]]1950;1951 %E = add i32 %B, %A1952 %F = add i32 %E, %C1953 %G = add i32 %F, %D1954 ret i32 %G1955}1956 1957define i32 @add_add_add_commute2(i32 %A, i32 %B, i32 %C, i32 %D) {1958; CHECK-LABEL: @add_add_add_commute2(1959; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]1960; CHECK-NEXT: [[F:%.*]] = add i32 [[C:%.*]], [[E]]1961; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]]1962; CHECK-NEXT: ret i32 [[G]]1963;1964 %E = add i32 %B, %A1965 %F = add i32 %C, %E1966 %G = add i32 %F, %D1967 ret i32 %G1968}1969 1970define i32 @add_add_add_commute3(i32 %A, i32 %B, i32 %C, i32 %D) {1971; CHECK-LABEL: @add_add_add_commute3(1972; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]1973; CHECK-NEXT: [[F:%.*]] = add i32 [[C:%.*]], [[E]]1974; CHECK-NEXT: [[G:%.*]] = add i32 [[D:%.*]], [[F]]1975; CHECK-NEXT: ret i32 [[G]]1976;1977 %E = add i32 %B, %A1978 %F = add i32 %C, %E1979 %G = add i32 %D, %F1980 ret i32 %G1981}1982 1983; x * y + x --> (y + 1) * x1984 1985define i8 @mul_add_common_factor_commute1(i8 %x, i8 %y) {1986; CHECK-LABEL: @mul_add_common_factor_commute1(1987; CHECK-NEXT: [[X1:%.*]] = add i8 [[Y:%.*]], 11988; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], [[X1]]1989; CHECK-NEXT: ret i8 [[A]]1990;1991 %m = mul nsw i8 %x, %y1992 %a = add nsw i8 %m, %x1993 ret i8 %a1994}1995 1996define <2 x i8> @mul_add_common_factor_commute2(<2 x i8> %x, <2 x i8> %y) {1997; CHECK-LABEL: @mul_add_common_factor_commute2(1998; CHECK-NEXT: [[M1:%.*]] = add <2 x i8> [[Y:%.*]], splat (i8 1)1999; CHECK-NEXT: [[A:%.*]] = mul nuw <2 x i8> [[M1]], [[X:%.*]]2000; CHECK-NEXT: ret <2 x i8> [[A]]2001;2002 %m = mul nuw <2 x i8> %y, %x2003 %a = add nuw <2 x i8> %m, %x2004 ret <2 x i8> %a2005}2006 2007define i8 @mul_add_common_factor_commute3(i8 %p, i8 %y) {2008; CHECK-LABEL: @mul_add_common_factor_commute3(2009; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]]2010; CHECK-NEXT: [[M1:%.*]] = add i8 [[Y:%.*]], 12011; CHECK-NEXT: [[A:%.*]] = mul i8 [[X]], [[M1]]2012; CHECK-NEXT: ret i8 [[A]]2013;2014 %x = mul i8 %p, %p ; thwart complexity-based canonicalization2015 %m = mul nuw i8 %x, %y2016 %a = add nsw i8 %x, %m2017 ret i8 %a2018}2019 2020define i8 @mul_add_common_factor_commute4(i8 %p, i8 %q) {2021; CHECK-LABEL: @mul_add_common_factor_commute4(2022; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]]2023; CHECK-NEXT: [[Y:%.*]] = mul i8 [[Q:%.*]], [[Q]]2024; CHECK-NEXT: [[M1:%.*]] = add i8 [[Y]], 12025; CHECK-NEXT: [[A:%.*]] = mul i8 [[X]], [[M1]]2026; CHECK-NEXT: ret i8 [[A]]2027;2028 %x = mul i8 %p, %p ; thwart complexity-based canonicalization2029 %y = mul i8 %q, %q ; thwart complexity-based canonicalization2030 %m = mul nsw i8 %y, %x2031 %a = add nuw i8 %x, %m2032 ret i8 %a2033}2034 2035; negative test - uses2036 2037define i8 @mul_add_common_factor_use(i8 %x, i8 %y) {2038; CHECK-LABEL: @mul_add_common_factor_use(2039; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]2040; CHECK-NEXT: call void @use(i8 [[M]])2041; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], [[X]]2042; CHECK-NEXT: ret i8 [[A]]2043;2044 %m = mul i8 %x, %y2045 call void @use(i8 %m)2046 %a = add i8 %m, %x2047 ret i8 %a2048}2049 2050define i8 @not_mul(i8 %x) {2051; CHECK-LABEL: @not_mul(2052; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], -412053; CHECK-NEXT: [[PLUSX:%.*]] = add i8 [[TMP1]], -12054; CHECK-NEXT: ret i8 [[PLUSX]]2055;2056 %mul = mul nsw i8 %x, 422057 %not = xor i8 %mul, -12058 %plusx = add nsw i8 %not, %x2059 ret i8 %plusx2060}2061 2062define <2 x i8> @not_mul_commute(<2 x i8> %p) {2063; CHECK-LABEL: @not_mul_commute(2064; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]2065; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i8> [[X]], splat (i8 43)2066; CHECK-NEXT: [[PLUSX:%.*]] = add <2 x i8> [[TMP1]], splat (i8 -1)2067; CHECK-NEXT: ret <2 x i8> [[PLUSX]]2068;2069 %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization2070 %mul = mul nuw <2 x i8> %x, <i8 -42, i8 -42>2071 %not = xor <2 x i8> %mul, <i8 -1, i8 -1>2072 %plusx = add nuw <2 x i8> %x, %not2073 ret <2 x i8> %plusx2074}2075 2076; negative test - need common operand2077 2078define i8 @not_mul_wrong_op(i8 %x, i8 %y) {2079; CHECK-LABEL: @not_mul_wrong_op(2080; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 422081; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[MUL]], -12082; CHECK-NEXT: [[PLUSX:%.*]] = add i8 [[Y:%.*]], [[NOT]]2083; CHECK-NEXT: ret i8 [[PLUSX]]2084;2085 %mul = mul i8 %x, 422086 %not = xor i8 %mul, -12087 %plusx = add i8 %not, %y2088 ret i8 %plusx2089}2090 2091; negative test - avoid creating an extra mul2092 2093define i8 @not_mul_use1(i8 %x) {2094; CHECK-LABEL: @not_mul_use1(2095; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[X:%.*]], 422096; CHECK-NEXT: call void @use(i8 [[MUL]])2097; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[MUL]], -12098; CHECK-NEXT: [[PLUSX:%.*]] = add nsw i8 [[X]], [[NOT]]2099; CHECK-NEXT: ret i8 [[PLUSX]]2100;2101 %mul = mul nsw i8 %x, 422102 call void @use(i8 %mul)2103 %not = xor i8 %mul, -12104 %plusx = add nsw i8 %not, %x2105 ret i8 %plusx2106}2107 2108; negative test - too many instructions2109 2110define i8 @not_mul_use2(i8 %x) {2111; CHECK-LABEL: @not_mul_use2(2112; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 422113; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[MUL]], -12114; CHECK-NEXT: call void @use(i8 [[NOT]])2115; CHECK-NEXT: [[PLUSX:%.*]] = add i8 [[X]], [[NOT]]2116; CHECK-NEXT: ret i8 [[PLUSX]]2117;2118 %mul = mul i8 %x, 422119 %not = xor i8 %mul, -12120 call void @use(i8 %not)2121 %plusx = add i8 %not, %x2122 ret i8 %plusx2123}2124 2125define i8 @full_ashr_inc(i8 %x) {2126; CHECK-LABEL: @full_ashr_inc(2127; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -12128; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i82129; CHECK-NEXT: ret i8 [[R]]2130;2131 %a = ashr i8 %x, 72132 %r = add i8 %a, 12133 ret i8 %r2134}2135 2136define <2 x i6> @full_ashr_inc_vec(<2 x i6> %x) {2137; CHECK-LABEL: @full_ashr_inc_vec(2138; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt <2 x i6> [[X:%.*]], splat (i6 -1)2139; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i6>2140; CHECK-NEXT: ret <2 x i6> [[R]]2141;2142 %a = ashr <2 x i6> %x, <i6 5, i6 poison>2143 %r = add <2 x i6> %a, <i6 1, i6 1>2144 ret <2 x i6> %r2145}2146 2147; negative test - extra use2148 2149define i8 @full_ashr_inc_use(i8 %x) {2150; CHECK-LABEL: @full_ashr_inc_use(2151; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 72152; CHECK-NEXT: call void @use(i8 [[A]])2153; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[A]], 12154; CHECK-NEXT: ret i8 [[R]]2155;2156 %a = ashr i8 %x, 72157 call void @use(i8 %a)2158 %r = add i8 %a, 12159 ret i8 %r2160}2161 2162; negative test - wrong shift amount2163 2164define i8 @not_full_ashr_inc(i8 %x) {2165; CHECK-LABEL: @not_full_ashr_inc(2166; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 62167; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[A]], 12168; CHECK-NEXT: ret i8 [[R]]2169;2170 %a = ashr i8 %x, 62171 %r = add i8 %a, 12172 ret i8 %r2173}2174 2175; negative test - wrong add amount2176 2177define i8 @full_ashr_not_inc(i8 %x) {2178; CHECK-LABEL: @full_ashr_not_inc(2179; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 72180; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[A]], 22181; CHECK-NEXT: ret i8 [[R]]2182;2183 %a = ashr i8 %x, 72184 %r = add i8 %a, 22185 ret i8 %r2186}2187 2188define i8 @select_negate_or_zero(i1 %b, i8 %x, i8 %y) {2189; CHECK-LABEL: @select_negate_or_zero(2190; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[X:%.*]]2191; CHECK-NEXT: [[ADD1:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]2192; CHECK-NEXT: ret i8 [[ADD1]]2193;2194 %negx = sub i8 0, %x2195 %sel = select i1 %b, i8 0, i8 %negx2196 %add = add i8 %sel, %y2197 ret i8 %add2198}2199 2200; commuted add operands - same result2201 2202define <2 x i8> @select_negate_or_zero_commute(<2 x i1> %b, <2 x i8> %x, <2 x i8> %p) {2203; CHECK-LABEL: @select_negate_or_zero_commute(2204; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]2205; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> zeroinitializer, <2 x i8> [[X:%.*]]2206; CHECK-NEXT: [[ADD1:%.*]] = sub <2 x i8> [[Y]], [[TMP1]]2207; CHECK-NEXT: ret <2 x i8> [[ADD1]]2208;2209 %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization2210 %negx = sub <2 x i8> <i8 poison, i8 0>, %x2211 %sel = select <2 x i1> %b, <2 x i8> <i8 poison, i8 0>, <2 x i8> %negx2212 %add = add <2 x i8> %y, %sel2213 ret <2 x i8> %add2214}2215 2216; swapped select operands and extra use are ok2217 2218define i8 @select_negate_or_zero_swap(i1 %b, i8 %x, i8 %y) {2219; CHECK-LABEL: @select_negate_or_zero_swap(2220; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]2221; CHECK-NEXT: call void @use(i8 [[NEGX]])2222; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i8 [[X]], i8 02223; CHECK-NEXT: [[ADD1:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]2224; CHECK-NEXT: ret i8 [[ADD1]]2225;2226 %negx = sub i8 0, %x2227 call void @use(i8 %negx)2228 %sel = select i1 %b, i8 %negx, i8 02229 %add = add i8 %sel, %y2230 ret i8 %add2231}2232 2233; commuted add operands - same result2234 2235define i8 @select_negate_or_zero_swap_commute(i1 %b, i8 %x, i8 %p) {2236; CHECK-LABEL: @select_negate_or_zero_swap_commute(2237; CHECK-NEXT: [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]2238; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i8 [[X:%.*]], i8 02239; CHECK-NEXT: [[ADD1:%.*]] = sub i8 [[Y]], [[TMP1]]2240; CHECK-NEXT: ret i8 [[ADD1]]2241;2242 %y = mul i8 %p, %p ; thwart complexity-based canonicalization2243 %negx = sub i8 0, %x2244 %sel = select i1 %b, i8 %negx, i8 02245 %add = add i8 %y, %sel2246 ret i8 %add2247}2248 2249; negative test - one arm of the select must simplify2250 2251define i8 @select_negate_or_nonzero(i1 %b, i8 %x, i8 %y) {2252; CHECK-LABEL: @select_negate_or_nonzero(2253; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]2254; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 42, i8 [[NEGX]]2255; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]2256; CHECK-NEXT: ret i8 [[ADD]]2257;2258 %negx = sub i8 0, %x2259 %sel = select i1 %b, i8 42, i8 %negx2260 %add = add i8 %sel, %y2261 ret i8 %add2262}2263 2264; negative test - must have a negate, not any subtract2265 2266define i8 @select_nonnegate_or_zero(i1 %b, i8 %x, i8 %y) {2267; CHECK-LABEL: @select_nonnegate_or_zero(2268; CHECK-NEXT: [[NEGX:%.*]] = sub i8 42, [[X:%.*]]2269; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[NEGX]]2270; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]2271; CHECK-NEXT: ret i8 [[ADD]]2272;2273 %negx = sub i8 42, %x2274 %sel = select i1 %b, i8 0, i8 %negx2275 %add = add i8 %sel, %y2276 ret i8 %add2277}2278 2279; negative test - don't create an extra instruction2280 2281define i8 @select_negate_or_nonzero_use(i1 %b, i8 %x, i8 %y) {2282; CHECK-LABEL: @select_negate_or_nonzero_use(2283; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]]2284; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[NEGX]]2285; CHECK-NEXT: call void @use(i8 [[SEL]])2286; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]2287; CHECK-NEXT: ret i8 [[ADD]]2288;2289 %negx = sub i8 0, %x2290 %sel = select i1 %b, i8 0, i8 %negx2291 call void @use(i8 %sel)2292 %add = add i8 %sel, %y2293 ret i8 %add2294}2295 2296; extra reduction because y + ~y -> -12297 2298define i5 @select_negate_not(i1 %b, i5 %x, i5 %y) {2299; CHECK-LABEL: @select_negate_not(2300; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y:%.*]], [[X:%.*]]2301; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 -1, i5 [[TMP1]]2302; CHECK-NEXT: ret i5 [[ADD1]]2303;2304 %negx = sub i5 0, %x2305 %noty = xor i5 %y, -12306 %sel = select i1 %b, i5 %noty, i5 %negx2307 %add = add i5 %sel, %y2308 ret i5 %add2309}2310 2311define i5 @select_negate_not_commute(i1 %b, i5 %x, i5 %p) {2312; CHECK-LABEL: @select_negate_not_commute(2313; CHECK-NEXT: [[Y:%.*]] = mul i5 [[P:%.*]], [[P]]2314; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y]], [[X:%.*]]2315; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 -1, i5 [[TMP1]]2316; CHECK-NEXT: ret i5 [[ADD1]]2317;2318 %y = mul i5 %p, %p ; thwart complexity-based canonicalization2319 %negx = sub i5 0, %x2320 %noty = xor i5 %y, -12321 %sel = select i1 %b, i5 %noty, i5 %negx2322 %add = add i5 %y, %sel2323 ret i5 %add2324}2325 2326define i5 @select_negate_not_swap(i1 %b, i5 %x, i5 %y) {2327; CHECK-LABEL: @select_negate_not_swap(2328; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y:%.*]], [[X:%.*]]2329; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 [[TMP1]], i5 -12330; CHECK-NEXT: ret i5 [[ADD1]]2331;2332 %negx = sub i5 0, %x2333 %noty = xor i5 %y, -12334 %sel = select i1 %b, i5 %negx, i5 %noty2335 %add = add i5 %sel, %y2336 ret i5 %add2337}2338 2339define i5 @select_negate_not_swap_commute(i1 %b, i5 %x, i5 %p) {2340; CHECK-LABEL: @select_negate_not_swap_commute(2341; CHECK-NEXT: [[Y:%.*]] = mul i5 [[P:%.*]], [[P]]2342; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y]], [[X:%.*]]2343; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 [[TMP1]], i5 -12344; CHECK-NEXT: ret i5 [[ADD1]]2345;2346 %y = mul i5 %p, %p ; thwart complexity-based canonicalization2347 %negx = sub i5 0, %x2348 %noty = xor i5 %y, -12349 %sel = select i1 %b, i5 %negx, i5 %noty2350 %add = add i5 %y, %sel2351 ret i5 %add2352}2353 2354define i32 @add_select_sub_both_arms_simplify(i1 %b, i32 %a) {2355; CHECK-LABEL: @add_select_sub_both_arms_simplify(2356; CHECK-NEXT: [[ADD:%.*]] = select i1 [[B:%.*]], i32 [[A:%.*]], i32 992357; CHECK-NEXT: ret i32 [[ADD]]2358;2359 %sub = sub i32 99, %a2360 %sel = select i1 %b, i32 0, i32 %sub2361 %add = add i32 %sel, %a2362 ret i32 %add2363}2364 2365define <2 x i8> @add_select_sub_both_arms_simplify_swap(<2 x i1> %b, <2 x i8> %a) {2366; CHECK-LABEL: @add_select_sub_both_arms_simplify_swap(2367; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> <i8 42, i8 99>, <2 x i8> [[A:%.*]]2368; CHECK-NEXT: ret <2 x i8> [[ADD]]2369;2370 %sub = sub <2 x i8> <i8 42, i8 99>, %a2371 %sel = select <2 x i1> %b, <2 x i8> %sub, <2 x i8> zeroinitializer2372 %add = add <2 x i8> %sel, %a2373 ret <2 x i8> %add2374}2375 2376define i8 @add_select_sub_both_arms_simplify_use1(i1 %b, i8 %a) {2377; CHECK-LABEL: @add_select_sub_both_arms_simplify_use1(2378; CHECK-NEXT: [[SUB:%.*]] = sub i8 42, [[A:%.*]]2379; CHECK-NEXT: call void @use(i8 [[SUB]])2380; CHECK-NEXT: [[ADD:%.*]] = select i1 [[B:%.*]], i8 [[A]], i8 422381; CHECK-NEXT: ret i8 [[ADD]]2382;2383 %sub = sub i8 42, %a2384 call void @use(i8 %sub)2385 %sel = select i1 %b, i8 0, i8 %sub2386 %add = add i8 %sel, %a2387 ret i8 %add2388}2389 2390define i8 @add_select_sub_both_arms_simplify_use2(i1 %b, i8 %a) {2391; CHECK-LABEL: @add_select_sub_both_arms_simplify_use2(2392; CHECK-NEXT: [[SUB:%.*]] = sub i8 42, [[A:%.*]]2393; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[SUB]]2394; CHECK-NEXT: call void @use(i8 [[SEL]])2395; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[A]]2396; CHECK-NEXT: ret i8 [[ADD]]2397;2398 %sub = sub i8 42, %a2399 %sel = select i1 %b, i8 0, i8 %sub2400 call void @use(i8 %sel)2401 %add = add i8 %sel, %a2402 ret i8 %add2403}2404 2405define i5 @demand_low_bits_uses(i8 %x, i8 %y) {2406; CHECK-LABEL: @demand_low_bits_uses(2407; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 52408; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]2409; CHECK-NEXT: call void @use(i8 [[A]])2410; CHECK-NEXT: [[R:%.*]] = trunc i8 [[Y]] to i52411; CHECK-NEXT: ret i5 [[R]]2412;2413 %m = mul i8 %x, -32 ; 0xE02414 %a = add i8 %m, %y2415 call void @use(i8 %a)2416 %r = trunc i8 %a to i52417 ret i5 %r2418}2419 2420; negative test - demands one more bit2421 2422define i6 @demand_low_bits_uses_extra_bit(i8 %x, i8 %y) {2423; CHECK-LABEL: @demand_low_bits_uses_extra_bit(2424; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 52425; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]2426; CHECK-NEXT: call void @use(i8 [[A]])2427; CHECK-NEXT: [[R:%.*]] = trunc i8 [[A]] to i62428; CHECK-NEXT: ret i6 [[R]]2429;2430 %m = mul i8 %x, -32 ; 0xE02431 %a = add i8 %m, %y2432 call void @use(i8 %a)2433 %r = trunc i8 %a to i62434 ret i6 %r2435}2436 2437define i8 @demand_low_bits_uses_commute(i8 %x, i8 %p, i8 %z) {2438; CHECK-LABEL: @demand_low_bits_uses_commute(2439; CHECK-NEXT: [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]2440; CHECK-NEXT: [[M:%.*]] = and i8 [[X:%.*]], -642441; CHECK-NEXT: [[A:%.*]] = add i8 [[Y]], [[M]]2442; CHECK-NEXT: call void @use(i8 [[A]])2443; CHECK-NEXT: [[S:%.*]] = sub i8 [[Y]], [[Z:%.*]]2444; CHECK-NEXT: [[R:%.*]] = shl i8 [[S]], 22445; CHECK-NEXT: ret i8 [[R]]2446;2447 %y = mul i8 %p, %p ; thwart complexity-based canonicalization2448 %m = and i8 %x, -64 ; 0xC02449 %a = add i8 %y, %m2450 call void @use(i8 %a)2451 %s = sub i8 %a, %z2452 %r = shl i8 %s, 22453 ret i8 %r2454}2455 2456; negative test - demands one more bit2457 2458define i8 @demand_low_bits_uses_commute_extra_bit(i8 %x, i8 %p, i8 %z) {2459; CHECK-LABEL: @demand_low_bits_uses_commute_extra_bit(2460; CHECK-NEXT: [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]2461; CHECK-NEXT: [[M:%.*]] = and i8 [[X:%.*]], -642462; CHECK-NEXT: [[A:%.*]] = add i8 [[Y]], [[M]]2463; CHECK-NEXT: call void @use(i8 [[A]])2464; CHECK-NEXT: [[S:%.*]] = sub i8 [[A]], [[Z:%.*]]2465; CHECK-NEXT: [[R:%.*]] = shl i8 [[S]], 12466; CHECK-NEXT: ret i8 [[R]]2467;2468 %y = mul i8 %p, %p ; thwart complexity-based canonicalization2469 %m = and i8 %x, -64 ; 0xC02470 %a = add i8 %y, %m2471 call void @use(i8 %a)2472 %s = sub i8 %a, %z2473 %r = shl i8 %s, 12474 ret i8 %r2475}2476 2477define { i64, i64 } @PR57576(i64 noundef %x, i64 noundef %y, i64 noundef %z, i64 noundef %w) {2478; CHECK-LABEL: @PR57576(2479; CHECK-NEXT: [[ZX:%.*]] = zext i64 [[X:%.*]] to i1282480; CHECK-NEXT: [[ZY:%.*]] = zext i64 [[Y:%.*]] to i1282481; CHECK-NEXT: [[ZZ:%.*]] = zext i64 [[Z:%.*]] to i1282482; CHECK-NEXT: [[SHY:%.*]] = shl nuw i128 [[ZY]], 642483; CHECK-NEXT: [[XY:%.*]] = or disjoint i128 [[SHY]], [[ZX]]2484; CHECK-NEXT: [[SUB:%.*]] = sub i128 [[XY]], [[ZZ]]2485; CHECK-NEXT: [[T:%.*]] = trunc i128 [[SUB]] to i642486; CHECK-NEXT: [[TMP1:%.*]] = lshr i128 [[SUB]], 642487; CHECK-NEXT: [[DOTTR:%.*]] = trunc nuw i128 [[TMP1]] to i642488; CHECK-NEXT: [[DOTNARROW:%.*]] = sub i64 [[DOTTR]], [[W:%.*]]2489; CHECK-NEXT: [[R1:%.*]] = insertvalue { i64, i64 } poison, i64 [[T]], 02490; CHECK-NEXT: [[R2:%.*]] = insertvalue { i64, i64 } [[R1]], i64 [[DOTNARROW]], 12491; CHECK-NEXT: ret { i64, i64 } [[R2]]2492;2493 %zx = zext i64 %x to i1282494 %zy = zext i64 %y to i1282495 %zw = zext i64 %w to i1282496 %zz = zext i64 %z to i1282497 %shy = shl nuw i128 %zy, 642498 %mw = mul i128 %zw, -184467440737095516162499 %xy = or i128 %shy, %zx2500 %sub = sub i128 %xy, %zz2501 %add = add i128 %sub, %mw2502 %t = trunc i128 %add to i642503 %h = lshr i128 %add, 642504 %t2 = trunc i128 %h to i642505 %r1 = insertvalue { i64, i64 } poison, i64 %t, 02506 %r2 = insertvalue { i64, i64 } %r1, i64 %t2, 12507 ret { i64, i64 } %r22508}2509 2510define i8 @mul_negpow2(i8 %x, i8 %y) {2511; CHECK-LABEL: @mul_negpow2(2512; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 12513; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]2514; CHECK-NEXT: ret i8 [[A]]2515;2516 %m = mul i8 %x, -22517 %a = add i8 %m, %y2518 ret i8 %a2519}2520 2521define <2 x i8> @mul_negpow2_commute_vec(<2 x i8> %x, <2 x i8> %p) {2522; CHECK-LABEL: @mul_negpow2_commute_vec(2523; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]2524; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 3)2525; CHECK-NEXT: [[A:%.*]] = sub <2 x i8> [[Y]], [[TMP1]]2526; CHECK-NEXT: ret <2 x i8> [[A]]2527;2528 %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization2529 %m = mul <2 x i8> %x, <i8 -8, i8 -8>2530 %a = add <2 x i8> %y, %m2531 ret <2 x i8> %a2532}2533 2534; negative test - extra use2535 2536define i8 @mul_negpow2_use(i8 %x) {2537; CHECK-LABEL: @mul_negpow2_use(2538; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -22539; CHECK-NEXT: call void @use(i8 [[M]])2540; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], 422541; CHECK-NEXT: ret i8 [[A]]2542;2543 %m = mul i8 %x, -22544 call void @use(i8 %m)2545 %a = add i8 %m, 422546 ret i8 %a2547}2548 2549; negative test - not negative-power-of-2 multiplier2550 2551define i8 @mul_not_negpow2(i8 %x) {2552; CHECK-LABEL: @mul_not_negpow2(2553; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -32554; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], 422555; CHECK-NEXT: ret i8 [[A]]2556;2557 %m = mul i8 %x, -32558 %a = add i8 %m, 422559 ret i8 %a2560}2561 2562define i16 @add_sub_zext(i8 %x, i8 %y) {2563; CHECK-LABEL: @add_sub_zext(2564; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i162565; CHECK-NEXT: ret i16 [[TMP1]]2566;2567 %1 = sub nuw i8 %y, %x2568 %2 = zext i8 %1 to i162569 %3 = zext i8 %x to i162570 %4 = add i16 %2, %32571 ret i16 %42572}2573 2574define i16 @add_commute_sub_zext(i8 %x, i8 %y) {2575; CHECK-LABEL: @add_commute_sub_zext(2576; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i162577; CHECK-NEXT: ret i16 [[TMP1]]2578;2579 %1 = sub nuw i8 %y, %x2580 %2 = zext i8 %1 to i162581 %3 = zext i8 %x to i162582 %4 = add i16 %3, %22583 ret i16 %42584}2585 2586define <2 x i8> @add_sub_2xi5_zext(<2 x i5> %x, <2 x i5> %y) {2587; CHECK-LABEL: @add_sub_2xi5_zext(2588; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i5> [[Y:%.*]] to <2 x i8>2589; CHECK-NEXT: ret <2 x i8> [[TMP1]]2590;2591 %1 = sub nuw <2 x i5> %y, %x2592 %2 = zext <2 x i5> %1 to <2 x i8>2593 %3 = zext <2 x i5> %x to <2 x i8>2594 %4 = add <2 x i8> %3, %22595 ret <2 x i8> %42596}2597 2598 2599define i3 @add_commute_sub_i2_zext_i3(i2 %x, i2 %y) {2600; CHECK-LABEL: @add_commute_sub_i2_zext_i3(2601; CHECK-NEXT: [[TMP1:%.*]] = zext i2 [[Y:%.*]] to i32602; CHECK-NEXT: ret i3 [[TMP1]]2603;2604 %1 = sub nuw i2 %y, %x2605 %2 = zext i2 %1 to i32606 %3 = zext i2 %x to i32607 %4 = add i3 %3, %22608 ret i3 %42609}2610 2611define i16 @add_sub_use_zext(i8 %x, i8 %y) {2612; CHECK-LABEL: @add_sub_use_zext(2613; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i8 [[Y:%.*]], [[X:%.*]]2614; CHECK-NEXT: call void @use(i8 [[TMP1]])2615; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[Y]] to i162616; CHECK-NEXT: ret i16 [[TMP2]]2617;2618 %1 = sub nuw i8 %y, %x2619 call void @use(i8 %1)2620 %2 = zext i8 %1 to i162621 %3 = zext i8 %x to i162622 %4 = add i16 %2, %32623 ret i16 %42624}2625 2626; Negative test: x - y + x != y2627define i16 @add_sub_commute_zext(i8 %x, i8 %y) {2628; CHECK-LABEL: @add_sub_commute_zext(2629; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]]2630; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i162631; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[X]] to i162632; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i16 [[TMP2]], [[TMP3]]2633; CHECK-NEXT: ret i16 [[TMP4]]2634;2635 %1 = sub nuw i8 %x, %y2636 %2 = zext i8 %1 to i162637 %3 = zext i8 %x to i162638 %4 = add i16 %2, %32639 ret i16 %42640}2641 2642; Negative test: no nuw flags2643define i16 @add_no_nuw_sub_zext(i8 %x, i8 %y) {2644; CHECK-LABEL: @add_no_nuw_sub_zext(2645; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]]2646; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i162647; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[X]] to i162648; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i16 [[TMP3]], [[TMP2]]2649; CHECK-NEXT: ret i16 [[TMP4]]2650;2651 %1 = sub i8 %y, %x2652 %2 = zext i8 %1 to i162653 %3 = zext i8 %x to i162654 %4 = add i16 %3, %22655 ret i16 %42656}2657 2658define i16 @add_no_nuw_sub_commute_zext(i8 %x, i8 %y) {2659; CHECK-LABEL: @add_no_nuw_sub_commute_zext(2660; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]2661; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i162662; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[X]] to i162663; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i16 [[TMP3]], [[TMP2]]2664; CHECK-NEXT: ret i16 [[TMP4]]2665;2666 %1 = sub i8 %x, %y2667 %2 = zext i8 %1 to i162668 %3 = zext i8 %x to i162669 %4 = add i16 %3, %22670 ret i16 %42671}2672 2673define i16 @add_sub_zext_constant(i8 %x) {2674; CHECK-LABEL: @add_sub_zext_constant(2675; CHECK-NEXT: ret i16 2542676;2677 %1 = sub nuw i8 254, %x2678 %2 = zext i8 %1 to i162679 %3 = zext i8 %x to i162680 %4 = add i16 %2, %32681 ret i16 %42682}2683 2684define <vscale x 1 x i32> @add_to_or_scalable(<vscale x 1 x i32> %in) {2685; CHECK-LABEL: @add_to_or_scalable(2686; CHECK-NEXT: [[SHL:%.*]] = shl <vscale x 1 x i32> [[IN:%.*]], splat (i32 1)2687; CHECK-NEXT: [[ADD:%.*]] = or disjoint <vscale x 1 x i32> [[SHL]], splat (i32 1)2688; CHECK-NEXT: ret <vscale x 1 x i32> [[ADD]]2689;2690 %shl = shl <vscale x 1 x i32> %in, splat (i32 1)2691 %add = add <vscale x 1 x i32> %shl, splat (i32 1)2692 ret <vscale x 1 x i32> %add2693}2694 2695define i5 @zext_zext_not(i3 noundef %x) {2696; CHECK-LABEL: @zext_zext_not(2697; CHECK-NEXT: ret i5 72698;2699 %zx = zext i3 %x to i52700 %notx = xor i3 %x, -12701 %znotx = zext i3 %notx to i52702 %r = add i5 %zx, %znotx2703 ret i5 %r2704}2705 2706define <2 x i5> @zext_zext_not_commute(<2 x i3> noundef %x) {2707; CHECK-LABEL: @zext_zext_not_commute(2708; CHECK-NEXT: ret <2 x i5> splat (i5 7)2709;2710 %zx = zext <2 x i3> %x to <2 x i5>2711 %notx = xor <2 x i3> %x, <i3 -1, i3 poison>2712 %znotx = zext <2 x i3> %notx to <2 x i5>2713 %r = add <2 x i5> %znotx, %zx2714 ret <2 x i5> %r2715}2716 2717define i9 @sext_sext_not(i3 noundef %x) {2718; CHECK-LABEL: @sext_sext_not(2719; CHECK-NEXT: ret i9 -12720;2721 %sx = sext i3 %x to i92722 %notx = xor i3 %x, -12723 %snotx = sext i3 %notx to i92724 %r = add i9 %sx, %snotx2725 ret i9 %r2726}2727 2728define i8 @sext_sext_not_commute(i3 noundef %x) {2729; CHECK-LABEL: @sext_sext_not_commute(2730; CHECK-NEXT: [[SX:%.*]] = sext i3 [[X:%.*]] to i82731; CHECK-NEXT: call void @use(i8 [[SX]])2732; CHECK-NEXT: ret i8 -12733;2734 2735 %sx = sext i3 %x to i82736 call void @use(i8 %sx)2737 %notx = xor i3 %x, -12738 %snotx = sext i3 %notx to i82739 %r = add i8 %snotx, %sx2740 ret i8 %r2741}2742 2743define i5 @zext_sext_not(i4 noundef %x) {2744; CHECK-LABEL: @zext_sext_not(2745; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i52746; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -12747; CHECK-NEXT: [[SNOTX:%.*]] = sext i4 [[NOTX]] to i52748; CHECK-NEXT: [[R:%.*]] = or disjoint i5 [[ZX]], [[SNOTX]]2749; CHECK-NEXT: ret i5 [[R]]2750;2751 %zx = zext i4 %x to i52752 %notx = xor i4 %x, -12753 %snotx = sext i4 %notx to i52754 %r = add i5 %zx, %snotx2755 ret i5 %r2756}2757 2758define i8 @zext_sext_not_commute(i4 noundef %x) {2759; CHECK-LABEL: @zext_sext_not_commute(2760; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i82761; CHECK-NEXT: call void @use(i8 [[ZX]])2762; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -12763; CHECK-NEXT: [[SNOTX:%.*]] = sext i4 [[NOTX]] to i82764; CHECK-NEXT: call void @use(i8 [[SNOTX]])2765; CHECK-NEXT: [[R:%.*]] = or disjoint i8 [[SNOTX]], [[ZX]]2766; CHECK-NEXT: ret i8 [[R]]2767;2768 %zx = zext i4 %x to i82769 call void @use(i8 %zx)2770 %notx = xor i4 %x, -12771 %snotx = sext i4 %notx to i82772 call void @use(i8 %snotx)2773 %r = add i8 %snotx, %zx2774 ret i8 %r2775}2776 2777define i9 @sext_zext_not(i4 noundef %x) {2778; CHECK-LABEL: @sext_zext_not(2779; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i92780; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -12781; CHECK-NEXT: [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i92782; CHECK-NEXT: [[R:%.*]] = or disjoint i9 [[SX]], [[ZNOTX]]2783; CHECK-NEXT: ret i9 [[R]]2784;2785 %sx = sext i4 %x to i92786 %notx = xor i4 %x, -12787 %znotx = zext i4 %notx to i92788 %r = add i9 %sx, %znotx2789 ret i9 %r2790}2791 2792define i9 @sext_zext_not_commute(i4 noundef %x) {2793; CHECK-LABEL: @sext_zext_not_commute(2794; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i92795; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -12796; CHECK-NEXT: [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i92797; CHECK-NEXT: [[R:%.*]] = or disjoint i9 [[ZNOTX]], [[SX]]2798; CHECK-NEXT: ret i9 [[R]]2799;2800 %sx = sext i4 %x to i92801 %notx = xor i4 %x, -12802 %znotx = zext i4 %notx to i92803 %r = add i9 %znotx, %sx2804 ret i9 %r2805}2806 2807; PR577412808 2809define i32 @floor_sdiv(i32 %x) {2810; CHECK-LABEL: @floor_sdiv(2811; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X:%.*]], 22812; CHECK-NEXT: ret i32 [[R]]2813;2814 %d = sdiv i32 %x, 42815 %a = and i32 %x, -21474836452816 %i = icmp ugt i32 %a, -21474836482817 %s = sext i1 %i to i322818 %r = add i32 %d, %s2819 ret i32 %r2820}2821 2822define i8 @floor_sdiv_by_2(i8 %x) {2823; CHECK-LABEL: @floor_sdiv_by_2(2824; CHECK-NEXT: [[RV:%.*]] = ashr i8 [[X:%.*]], 12825; CHECK-NEXT: ret i8 [[RV]]2826;2827 %div = sdiv i8 %x, 22828 %and = and i8 %x, -1272829 %icmp = icmp eq i8 %and, -1272830 %sext = sext i1 %icmp to i82831 %rv = add nsw i8 %div, %sext2832 ret i8 %rv2833}2834 2835define i8 @floor_sdiv_by_2_wrong_mask(i8 %x) {2836; CHECK-LABEL: @floor_sdiv_by_2_wrong_mask(2837; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X:%.*]], 22838; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], 1272839; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i8 [[AND]], 1272840; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i82841; CHECK-NEXT: [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]2842; CHECK-NEXT: ret i8 [[RV]]2843;2844 %div = sdiv i8 %x, 22845 %and = and i8 %x, 1272846 %icmp = icmp eq i8 %and, 1272847 %sext = sext i1 %icmp to i82848 %rv = add nsw i8 %div, %sext2849 ret i8 %rv2850}2851 2852define i8 @floor_sdiv_by_2_wrong_constant(i8 %x) {2853; CHECK-LABEL: @floor_sdiv_by_2_wrong_constant(2854; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X:%.*]], 42855; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -1252856; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i8 [[AND]], -1252857; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i82858; CHECK-NEXT: [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]2859; CHECK-NEXT: ret i8 [[RV]]2860;2861 %div = sdiv i8 %x, 42862 %and = and i8 %x, -1252863 %icmp = icmp eq i8 %and, -1252864 %sext = sext i1 %icmp to i82865 %rv = add nsw i8 %div, %sext2866 ret i8 %rv2867}2868 2869define i8 @floor_sdiv_by_2_wrong_cast(i8 %x) {2870; CHECK-LABEL: @floor_sdiv_by_2_wrong_cast(2871; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X:%.*]], 22872; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -1272873; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i8 [[AND]], -1272874; CHECK-NEXT: [[SEXT:%.*]] = zext i1 [[ICMP]] to i82875; CHECK-NEXT: [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]2876; CHECK-NEXT: ret i8 [[RV]]2877;2878 %div = sdiv i8 %x, 22879 %and = and i8 %x, -1272880 %icmp = icmp eq i8 %and, -1272881 %sext = zext i1 %icmp to i82882 %rv = add nsw i8 %div, %sext2883 ret i8 %rv2884}2885 2886; vectors work too and commute is handled by complexity-based canonicalization2887 2888define <2 x i32> @floor_sdiv_vec_commute(<2 x i32> %x) {2889; CHECK-LABEL: @floor_sdiv_vec_commute(2890; CHECK-NEXT: [[R:%.*]] = ashr <2 x i32> [[X:%.*]], splat (i32 2)2891; CHECK-NEXT: ret <2 x i32> [[R]]2892;2893 %d = sdiv <2 x i32> %x, <i32 4, i32 4>2894 %a = and <2 x i32> %x, <i32 -2147483645, i32 -2147483645>2895 %i = icmp ugt <2 x i32> %a, <i32 -2147483648, i32 -2147483648>2896 %s = sext <2 x i1> %i to <2 x i32>2897 %r = add <2 x i32> %s, %d2898 ret <2 x i32> %r2899}2900 2901; extra uses are ok2902 2903define i8 @floor_sdiv_uses(i8 %x) {2904; CHECK-LABEL: @floor_sdiv_uses(2905; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], 162906; CHECK-NEXT: call void @use(i8 [[D]])2907; CHECK-NEXT: [[A:%.*]] = and i8 [[X]], -1132908; CHECK-NEXT: call void @use(i8 [[A]])2909; CHECK-NEXT: [[I:%.*]] = icmp ugt i8 [[A]], -1282910; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i82911; CHECK-NEXT: call void @use(i8 [[S]])2912; CHECK-NEXT: [[R:%.*]] = ashr i8 [[X]], 42913; CHECK-NEXT: ret i8 [[R]]2914;2915 %d = sdiv i8 %x, 162916 call void @use(i8 %d)2917 %a = and i8 %x, 143 ; 128 + 152918 call void @use(i8 %a)2919 %i = icmp ugt i8 %a, 1282920 %s = sext i1 %i to i82921 call void @use(i8 %s)2922 %r = add i8 %d, %s2923 ret i8 %r2924}2925 2926; negative test2927 2928define i32 @floor_sdiv_wrong_div(i32 %x) {2929; CHECK-LABEL: @floor_sdiv_wrong_div(2930; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 82931; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -21474836452932; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -21474836482933; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i322934; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]]2935; CHECK-NEXT: ret i32 [[R]]2936;2937 %d = sdiv i32 %x, 82938 %a = and i32 %x, -21474836452939 %i = icmp ugt i32 %a, -21474836482940 %s = sext i1 %i to i322941 %r = add i32 %d, %s2942 ret i32 %r2943}2944 2945; negative test2946 2947define i32 @floor_sdiv_wrong_mask(i32 %x) {2948; CHECK-LABEL: @floor_sdiv_wrong_mask(2949; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 42950; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -21474836442951; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -21474836482952; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i322953; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]]2954; CHECK-NEXT: ret i32 [[R]]2955;2956 %d = sdiv i32 %x, 42957 %a = and i32 %x, -21474836442958 %i = icmp ugt i32 %a, -21474836482959 %s = sext i1 %i to i322960 %r = add i32 %d, %s2961 ret i32 %r2962}2963 2964; negative test2965 2966define i32 @floor_sdiv_wrong_cmp(i32 %x) {2967; CHECK-LABEL: @floor_sdiv_wrong_cmp(2968; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 42969; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -21474836462970; CHECK-NEXT: [[I:%.*]] = icmp eq i32 [[A]], -21474836462971; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i322972; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]]2973; CHECK-NEXT: ret i32 [[R]]2974;2975 %d = sdiv i32 %x, 42976 %a = and i32 %x, -21474836452977 %i = icmp ugt i32 %a, -21474836472978 %s = sext i1 %i to i322979 %r = add i32 %d, %s2980 ret i32 %r2981}2982 2983; negative test2984 2985define i32 @floor_sdiv_wrong_ext(i32 %x) {2986; CHECK-LABEL: @floor_sdiv_wrong_ext(2987; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 42988; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -21474836452989; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -21474836482990; CHECK-NEXT: [[S:%.*]] = zext i1 [[I]] to i322991; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]]2992; CHECK-NEXT: ret i32 [[R]]2993;2994 %d = sdiv i32 %x, 42995 %a = and i32 %x, -21474836452996 %i = icmp ugt i32 %a, -21474836482997 %s = zext i1 %i to i322998 %r = add i32 %d, %s2999 ret i32 %r3000}3001 3002; negative test3003 3004define i32 @floor_sdiv_wrong_op(i32 %x, i32 %y) {3005; CHECK-LABEL: @floor_sdiv_wrong_op(3006; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 43007; CHECK-NEXT: [[A:%.*]] = and i32 [[Y:%.*]], -21474836453008; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -21474836483009; CHECK-NEXT: [[S:%.*]] = zext i1 [[I]] to i323010; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]]3011; CHECK-NEXT: ret i32 [[R]]3012;3013 %d = sdiv i32 %x, 43014 %a = and i32 %y, -21474836453015 %i = icmp ugt i32 %a, -21474836483016 %s = zext i1 %i to i323017 %r = add i32 %d, %s3018 ret i32 %r3019}3020 3021define i32 @floor_sdiv_using_srem_by_8(i32 %x) {3022; CHECK-LABEL: @floor_sdiv_using_srem_by_8(3023; CHECK-NEXT: [[F:%.*]] = ashr i32 [[X:%.*]], 33024; CHECK-NEXT: ret i32 [[F]]3025;3026 %d = sdiv i32 %x, 83027 %r = srem i32 %x, 83028 %i = icmp ugt i32 %r, -21474836483029 %s = sext i1 %i to i323030 %f = add i32 %d, %s3031 ret i32 %f3032}3033 3034define i32 @floor_sdiv_using_srem_by_2(i32 %x) {3035; CHECK-LABEL: @floor_sdiv_using_srem_by_2(3036; CHECK-NEXT: [[F:%.*]] = ashr i32 [[X:%.*]], 13037; CHECK-NEXT: ret i32 [[F]]3038;3039 %d = sdiv i32 %x, 23040 %r = srem i32 %x, 23041 %i = icmp ugt i32 %r, -21474836483042 %s = sext i1 %i to i323043 %f = add i32 %d, %s3044 ret i32 %f3045}3046 3047; (X s>> (BW - 1)) + (zext (X s> 0)) --> (X s>> (BW - 1)) | (zext (X != 0))3048 3049define i8 @signum_i8_i8(i8 %x) {3050; CHECK-LABEL: @signum_i8_i8(3051; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 73052; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne i8 [[X]], 03053; CHECK-NEXT: [[ISNOTNULL_ZEXT:%.*]] = zext i1 [[ISNOTNULL]] to i83054; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGNBIT]], [[ISNOTNULL_ZEXT]]3055; CHECK-NEXT: ret i8 [[R]]3056;3057 %sgt0 = icmp sgt i8 %x, 03058 %zgt0 = zext i1 %sgt0 to i83059 %signbit = ashr i8 %x, 73060 %r = add i8 %zgt0, %signbit3061 ret i8 %r3062}3063 3064; extra use of shift is ok3065 3066define i8 @signum_i8_i8_use1(i8 %x) {3067; CHECK-LABEL: @signum_i8_i8_use1(3068; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 73069; CHECK-NEXT: call void @use(i8 [[SIGNBIT]])3070; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne i8 [[X]], 03071; CHECK-NEXT: [[ISNOTNULL_ZEXT:%.*]] = zext i1 [[ISNOTNULL]] to i83072; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGNBIT]], [[ISNOTNULL_ZEXT]]3073; CHECK-NEXT: ret i8 [[R]]3074;3075 %sgt0 = icmp sgt i8 %x, 03076 %zgt0 = zext i1 %sgt0 to i83077 %signbit = ashr i8 %x, 73078 call void @use(i8 %signbit)3079 %r = add i8 %zgt0, %signbit3080 ret i8 %r3081}3082 3083; negative test3084 3085define i8 @signum_i8_i8_use2(i8 %x) {3086; CHECK-LABEL: @signum_i8_i8_use2(3087; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 03088; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i83089; CHECK-NEXT: call void @use(i8 [[ZGT0]])3090; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 73091; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]3092; CHECK-NEXT: ret i8 [[R]]3093;3094 %sgt0 = icmp sgt i8 %x, 03095 %zgt0 = zext i1 %sgt0 to i83096 call void @use(i8 %zgt0)3097 %signbit = ashr i8 %x, 73098 %r = add i8 %zgt0, %signbit3099 ret i8 %r3100}3101 3102; negative test3103 3104define i8 @signum_i8_i8_use3(i8 %x) {3105; CHECK-LABEL: @signum_i8_i8_use3(3106; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 03107; CHECK-NEXT: call void @use_i1(i1 [[SGT0]])3108; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i83109; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 73110; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]3111; CHECK-NEXT: ret i8 [[R]]3112;3113 %sgt0 = icmp sgt i8 %x, 03114 call void @use_i1(i1 %sgt0)3115 %zgt0 = zext i1 %sgt0 to i83116 %signbit = ashr i8 %x, 73117 %r = add i8 %zgt0, %signbit3118 ret i8 %r3119}3120 3121; poison is ok to propagate in shift amount3122; complexity canonicalization guarantees that shift is op0 of add3123 3124define <2 x i5> @signum_v2i5_v2i5(<2 x i5> %x) {3125; CHECK-LABEL: @signum_v2i5_v2i5(3126; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr <2 x i5> [[X:%.*]], <i5 4, i5 poison>3127; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne <2 x i5> [[X]], zeroinitializer3128; CHECK-NEXT: [[ISNOTNULL_ZEXT:%.*]] = zext <2 x i1> [[ISNOTNULL]] to <2 x i5>3129; CHECK-NEXT: [[R:%.*]] = or <2 x i5> [[SIGNBIT]], [[ISNOTNULL_ZEXT]]3130; CHECK-NEXT: ret <2 x i5> [[R]]3131;3132 %sgt0 = icmp sgt <2 x i5> %x, zeroinitializer3133 %zgt0 = zext <2 x i1> %sgt0 to <2 x i5>3134 %signbit = ashr <2 x i5> %x, <i5 4, i5 poison>3135 %r = add <2 x i5> %signbit, %zgt03136 ret <2 x i5> %r3137}3138 3139; negative test3140 3141define i8 @signum_i8_i8_wrong_sh_amt(i8 %x) {3142; CHECK-LABEL: @signum_i8_i8_wrong_sh_amt(3143; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 03144; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i83145; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 63146; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]3147; CHECK-NEXT: ret i8 [[R]]3148;3149 %sgt0 = icmp sgt i8 %x, 03150 %zgt0 = zext i1 %sgt0 to i83151 %signbit = ashr i8 %x, 63152 %r = add i8 %zgt0, %signbit3153 ret i8 %r3154}3155 3156; negative test3157 3158define i8 @signum_i8_i8_wrong_ext(i8 %x) {3159; CHECK-LABEL: @signum_i8_i8_wrong_ext(3160; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 03161; CHECK-NEXT: [[ZGT0:%.*]] = sext i1 [[SGT0]] to i83162; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 73163; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]3164; CHECK-NEXT: ret i8 [[R]]3165;3166 %sgt0 = icmp sgt i8 %x, 03167 %zgt0 = sext i1 %sgt0 to i83168 %signbit = ashr i8 %x, 73169 %r = add i8 %zgt0, %signbit3170 ret i8 %r3171}3172 3173; negative test3174 3175define i8 @signum_i8_i8_wrong_pred(i8 %x) {3176; CHECK-LABEL: @signum_i8_i8_wrong_pred(3177; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], -13178; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i83179; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 73180; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]3181; CHECK-NEXT: ret i8 [[R]]3182;3183 %sgt0 = icmp sge i8 %x, 03184 %zgt0 = zext i1 %sgt0 to i83185 %signbit = ashr i8 %x, 73186 %r = add i8 %zgt0, %signbit3187 ret i8 %r3188}3189 3190define i32 @dec_zext_add_assume_nonzero(i8 %x) {3191; CHECK-LABEL: @dec_zext_add_assume_nonzero(3192; CHECK-NEXT: [[Z:%.*]] = icmp ne i8 [[X:%.*]], 03193; CHECK-NEXT: call void @llvm.assume(i1 [[Z]])3194; CHECK-NEXT: [[C:%.*]] = zext i8 [[X]] to i323195; CHECK-NEXT: ret i32 [[C]]3196;3197 %z = icmp ne i8 %x, 03198 call void @llvm.assume(i1 %z)3199 %a = add i8 %x, -13200 %b = zext i8 %a to i323201 %c = add i32 %b, 13202 ret i32 %c3203}3204 3205define i32 @dec_zext_add_nonzero(i8 %x) {3206; CHECK-LABEL: @dec_zext_add_nonzero(3207; CHECK-NEXT: [[O:%.*]] = or i8 [[X:%.*]], 43208; CHECK-NEXT: [[C:%.*]] = zext i8 [[O]] to i323209; CHECK-NEXT: ret i32 [[C]]3210;3211 %o = or i8 %x, 43212 %a = add i8 %o, -13213 %b = zext i8 %a to i323214 %c = add i32 %b, 13215 ret i32 %c3216}3217 3218define <2 x i32> @dec_zext_add_nonzero_vec(<2 x i8> %x) {3219; CHECK-LABEL: @dec_zext_add_nonzero_vec(3220; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 8)3221; CHECK-NEXT: [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>3222; CHECK-NEXT: ret <2 x i32> [[C]]3223;3224 %o = or <2 x i8> %x, <i8 8, i8 8>3225 %a = add <2 x i8> %o, <i8 -1, i8 -1>3226 %b = zext <2 x i8> %a to <2 x i32>3227 %c = add <2 x i32> %b, <i32 1, i32 1>3228 ret <2 x i32> %c3229}3230 3231; Negative test: Folding this with undef is not safe.3232 3233define <2 x i32> @dec_zext_add_nonzero_vec_undef0(<2 x i8> %x) {3234; CHECK-LABEL: @dec_zext_add_nonzero_vec_undef0(3235; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 undef>3236; CHECK-NEXT: [[A:%.*]] = add <2 x i8> [[O]], splat (i8 -1)3237; CHECK-NEXT: [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32>3238; CHECK-NEXT: [[C:%.*]] = add nuw nsw <2 x i32> [[B]], splat (i32 1)3239; CHECK-NEXT: ret <2 x i32> [[C]]3240;3241 %o = or <2 x i8> %x, <i8 8, i8 undef>3242 %a = add <2 x i8> %o, <i8 -1, i8 -1>3243 %b = zext <2 x i8> %a to <2 x i32>3244 %c = add <2 x i32> %b, <i32 1, i32 1>3245 ret <2 x i32> %c3246}3247 3248define <2 x i32> @dec_zext_add_nonzero_poison0(<2 x i8> %x) {3249; CHECK-LABEL: @dec_zext_add_nonzero_poison0(3250; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 poison>3251; CHECK-NEXT: [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>3252; CHECK-NEXT: ret <2 x i32> [[C]]3253;3254 %o = or <2 x i8> %x, <i8 8, i8 poison>3255 %a = add <2 x i8> %o, <i8 -1, i8 -1>3256 %b = zext <2 x i8> %a to <2 x i32>3257 %c = add <2 x i32> %b, <i32 1, i32 1>3258 ret <2 x i32> %c3259}3260 3261define <2 x i32> @dec_zext_add_nonzero_vec_poison1(<2 x i8> %x) {3262; CHECK-LABEL: @dec_zext_add_nonzero_vec_poison1(3263; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 8)3264; CHECK-NEXT: [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>3265; CHECK-NEXT: ret <2 x i32> [[C]]3266;3267 %o = or <2 x i8> %x, <i8 8, i8 8>3268 %a = add <2 x i8> %o, <i8 -1, i8 poison>3269 %b = zext <2 x i8> %a to <2 x i32>3270 %c = add <2 x i32> %b, <i32 1, i32 1>3271 ret <2 x i32> %c3272}3273 3274define <2 x i32> @dec_zext_add_nonzero_vec_poison2(<2 x i8> %x) {3275; CHECK-LABEL: @dec_zext_add_nonzero_vec_poison2(3276; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 8)3277; CHECK-NEXT: [[A:%.*]] = add nsw <2 x i8> [[O]], splat (i8 -1)3278; CHECK-NEXT: [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32>3279; CHECK-NEXT: [[C:%.*]] = add nuw nsw <2 x i32> [[B]], <i32 1, i32 poison>3280; CHECK-NEXT: ret <2 x i32> [[C]]3281;3282 %o = or <2 x i8> %x, <i8 8, i8 8>3283 %a = add <2 x i8> %o, <i8 -1, i8 -1>3284 %b = zext <2 x i8> %a to <2 x i32>3285 %c = add <2 x i32> %b, <i32 1, i32 poison>3286 ret <2 x i32> %c3287}3288 3289define i32 @add_zext_sext_i1(i1 %a) {3290; CHECK-LABEL: @add_zext_sext_i1(3291; CHECK-NEXT: ret i32 03292;3293 %zext = zext i1 %a to i323294 %sext = sext i1 %a to i323295 %add = add i32 %zext, %sext3296 ret i32 %add3297}3298 3299define i32 @add_sext_zext_i1(i1 %a) {3300; CHECK-LABEL: @add_sext_zext_i1(3301; CHECK-NEXT: ret i32 03302;3303 %zext = zext i1 %a to i323304 %sext = sext i1 %a to i323305 %add = add i32 %sext, %zext3306 ret i32 %add3307}3308 3309define <2 x i32> @add_zext_sext_i1_vec(<2 x i1> %a) {3310; CHECK-LABEL: @add_zext_sext_i1_vec(3311; CHECK-NEXT: ret <2 x i32> zeroinitializer3312;3313 %zext = zext <2 x i1> %a to <2 x i32>3314 %sext = sext <2 x i1> %a to <2 x i32>3315 %add = add <2 x i32> %zext, %sext3316 ret <2 x i32> %add3317}3318 3319define i32 @add_zext_zext_i1(i1 %a) {3320; CHECK-LABEL: @add_zext_zext_i1(3321; CHECK-NEXT: [[ADD:%.*]] = select i1 [[A:%.*]], i32 2, i32 03322; CHECK-NEXT: ret i32 [[ADD]]3323;3324 %zext = zext i1 %a to i323325 %add = add i32 %zext, %zext3326 ret i32 %add3327}3328 3329define i32 @add_sext_sext_i1(i1 %a) {3330; CHECK-LABEL: @add_sext_sext_i1(3331; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i323332; CHECK-NEXT: [[ADD:%.*]] = shl nsw i32 [[SEXT]], 13333; CHECK-NEXT: ret i32 [[ADD]]3334;3335 %sext = sext i1 %a to i323336 %add = add i32 %sext, %sext3337 ret i32 %add3338}3339 3340define i32 @add_zext_sext_not_i1(i8 %a) {3341; CHECK-LABEL: @add_zext_sext_not_i1(3342; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[A:%.*]] to i323343; CHECK-NEXT: [[SEXT:%.*]] = sext i8 [[A]] to i323344; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]]3345; CHECK-NEXT: ret i32 [[ADD]]3346;3347 %zext = zext i8 %a to i323348 %sext = sext i8 %a to i323349 %add = add i32 %zext, %sext3350 ret i32 %add3351}3352 3353define i32 @add_zext_sext_i1_different_values(i1 %a, i1 %b) {3354; CHECK-LABEL: @add_zext_sext_i1_different_values(3355; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[A:%.*]] to i323356; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[B:%.*]] to i323357; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]]3358; CHECK-NEXT: ret i32 [[ADD]]3359;3360 %zext = zext i1 %a to i323361 %sext = sext i1 %b to i323362 %add = add i32 %zext, %sext3363 ret i32 %add3364}3365 3366define i32 @add_reduce_sqr_sum_nsw(i32 %a, i32 %b) {3367; CHECK-LABEL: @add_reduce_sqr_sum_nsw(3368; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3369; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]3370; CHECK-NEXT: ret i32 [[ADD]]3371;3372 %a_sq = mul nsw i32 %a, %a3373 %two_a = shl i32 %a, 13374 %two_a_plus_b = add i32 %two_a, %b3375 %mul = mul i32 %two_a_plus_b, %b3376 %add = add i32 %mul, %a_sq3377 ret i32 %add3378}3379 3380define i32 @add_reduce_sqr_sum_u(i32 %a, i32 %b) {3381; CHECK-LABEL: @add_reduce_sqr_sum_u(3382; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3383; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]3384; CHECK-NEXT: ret i32 [[ADD]]3385;3386 %a_sq = mul i32 %a, %a3387 %two_a = shl i32 %a, 13388 %two_a_plus_b = add i32 %two_a, %b3389 %mul = mul i32 %two_a_plus_b, %b3390 %add = add i32 %mul, %a_sq3391 ret i32 %add3392}3393 3394define i32 @add_reduce_sqr_sum_nuw(i32 %a, i32 %b) {3395; CHECK-LABEL: @add_reduce_sqr_sum_nuw(3396; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3397; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]3398; CHECK-NEXT: ret i32 [[ADD]]3399;3400 %a_sq = mul nuw i32 %a, %a3401 %two_a = mul i32 %a, 23402 %two_a_plus_b = add i32 %two_a, %b3403 %mul = mul nuw i32 %two_a_plus_b, %b3404 %add = add i32 %mul, %a_sq3405 ret i32 %add3406}3407 3408define i32 @add_reduce_sqr_sum_flipped(i32 %a, i32 %b) {3409; CHECK-LABEL: @add_reduce_sqr_sum_flipped(3410; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3411; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]3412; CHECK-NEXT: ret i32 [[ADD]]3413;3414 %a_sq = mul nsw i32 %a, %a3415 %two_a = shl i32 %a, 13416 %two_a_plus_b = add i32 %two_a, %b3417 %mul = mul i32 %two_a_plus_b, %b3418 %add = add i32 %a_sq, %mul3419 ret i32 %add3420}3421 3422define i32 @add_reduce_sqr_sum_flipped2(i32 %a, i32 %bx) {3423; CHECK-LABEL: @add_reduce_sqr_sum_flipped2(3424; CHECK-NEXT: [[B:%.*]] = xor i32 [[BX:%.*]], 423425; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B]]3426; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]3427; CHECK-NEXT: ret i32 [[ADD]]3428;3429 %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization3430 %a_sq = mul nsw i32 %a, %a3431 %two_a = shl i32 %a, 13432 %two_a_plus_b = add i32 %two_a, %b3433 %mul = mul i32 %b, %two_a_plus_b3434 %add = add i32 %mul, %a_sq3435 ret i32 %add3436}3437 3438define i32 @add_reduce_sqr_sum_flipped3(i32 %a, i32 %b) {3439; CHECK-LABEL: @add_reduce_sqr_sum_flipped3(3440; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3441; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]3442; CHECK-NEXT: ret i32 [[ADD]]3443;3444 %a_sq = mul nsw i32 %a, %a3445 %two_a = shl i32 %a, 13446 %two_a_plus_b = add i32 %b, %two_a3447 %mul = mul i32 %two_a_plus_b, %b3448 %add = add i32 %mul, %a_sq3449 ret i32 %add3450}3451 3452define i32 @add_reduce_sqr_sum_order2(i32 %a, i32 %b) {3453; CHECK-LABEL: @add_reduce_sqr_sum_order2(3454; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3455; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3456; CHECK-NEXT: ret i32 [[AB2]]3457;3458 %a_sq = mul nsw i32 %a, %a3459 %twoa = mul i32 %a, 23460 %twoab = mul i32 %twoa, %b3461 %b_sq = mul i32 %b, %b3462 %twoab_b2 = add i32 %twoab, %b_sq3463 %ab2 = add i32 %a_sq, %twoab_b23464 ret i32 %ab23465}3466 3467define i32 @add_reduce_sqr_sum_order2_flipped(i32 %a, i32 %b) {3468; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped(3469; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3470; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3471; CHECK-NEXT: ret i32 [[AB2]]3472;3473 %a_sq = mul nsw i32 %a, %a3474 %twoa = mul i32 %a, 23475 %twoab = mul i32 %twoa, %b3476 %b_sq = mul i32 %b, %b3477 %twoab_b2 = add i32 %twoab, %b_sq3478 %ab2 = add i32 %twoab_b2, %a_sq3479 ret i32 %ab23480}3481 3482define i32 @add_reduce_sqr_sum_order2_flipped2(i32 %a, i32 %bx) {3483; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped2(3484; CHECK-NEXT: [[B:%.*]] = xor i32 [[BX:%.*]], 423485; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B]]3486; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3487; CHECK-NEXT: ret i32 [[AB2]]3488;3489 %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization3490 %a_sq = mul nsw i32 %a, %a3491 %twoa = mul i32 %a, 23492 %twoab = mul i32 %twoa, %b3493 %b_sq = mul i32 %b, %b3494 %twoab_b2 = add i32 %b_sq, %twoab3495 %ab2 = add i32 %a_sq, %twoab_b23496 ret i32 %ab23497}3498 3499define i32 @add_reduce_sqr_sum_order2_flipped3(i32 %a, i32 %bx) {3500; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped3(3501; CHECK-NEXT: [[B:%.*]] = xor i32 [[BX:%.*]], 423502; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B]]3503; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3504; CHECK-NEXT: ret i32 [[AB2]]3505;3506 %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization3507 %a_sq = mul nsw i32 %a, %a3508 %twoa = mul i32 %a, 23509 %twoab = mul i32 %b, %twoa3510 %b_sq = mul i32 %b, %b3511 %twoab_b2 = add i32 %twoab, %b_sq3512 %ab2 = add i32 %a_sq, %twoab_b23513 ret i32 %ab23514}3515 3516define i32 @add_reduce_sqr_sum_order3(i32 %a, i32 %b) {3517; CHECK-LABEL: @add_reduce_sqr_sum_order3(3518; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3519; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3520; CHECK-NEXT: ret i32 [[AB2]]3521;3522 %a_sq = mul nsw i32 %a, %a3523 %twoa = mul i32 %a, 23524 %twoab = mul i32 %twoa, %b3525 %b_sq = mul i32 %b, %b3526 %a2_b2 = add i32 %a_sq, %b_sq3527 %ab2 = add i32 %twoab, %a2_b23528 ret i32 %ab23529}3530 3531define i32 @add_reduce_sqr_sum_order3_flipped(i32 %a, i32 %b) {3532; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped(3533; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3534; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3535; CHECK-NEXT: ret i32 [[AB2]]3536;3537 %a_sq = mul nsw i32 %a, %a3538 %twoa = mul i32 %a, 23539 %twoab = mul i32 %twoa, %b3540 %b_sq = mul i32 %b, %b3541 %a2_b2 = add i32 %a_sq, %b_sq3542 %ab2 = add i32 %a2_b2, %twoab3543 ret i32 %ab23544}3545 3546define i32 @add_reduce_sqr_sum_order3_flipped2(i32 %a, i32 %b) {3547; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped2(3548; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3549; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3550; CHECK-NEXT: ret i32 [[AB2]]3551;3552 %a_sq = mul nsw i32 %a, %a3553 %twoa = mul i32 %a, 23554 %twoab = mul i32 %twoa, %b3555 %b_sq = mul i32 %b, %b3556 %a2_b2 = add i32 %b_sq, %a_sq3557 %ab2 = add i32 %twoab, %a2_b23558 ret i32 %ab23559}3560 3561define i32 @add_reduce_sqr_sum_order3_flipped3(i32 %a, i32 %b) {3562; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped3(3563; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3564; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3565; CHECK-NEXT: ret i32 [[AB2]]3566;3567 %a_sq = mul nsw i32 %a, %a3568 %twoa = mul i32 %a, 23569 %twoab = mul i32 %b, %twoa3570 %b_sq = mul i32 %b, %b3571 %a2_b2 = add i32 %a_sq, %b_sq3572 %ab2 = add i32 %twoab, %a2_b23573 ret i32 %ab23574}3575 3576define i32 @add_reduce_sqr_sum_order4(i32 %a, i32 %b) {3577; CHECK-LABEL: @add_reduce_sqr_sum_order4(3578; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3579; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3580; CHECK-NEXT: ret i32 [[AB2]]3581;3582 %a_sq = mul nsw i32 %a, %a3583 %ab = mul i32 %a, %b3584 %twoab = mul i32 %ab, 23585 %b_sq = mul i32 %b, %b3586 %a2_b2 = add i32 %a_sq, %b_sq3587 %ab2 = add i32 %twoab, %a2_b23588 ret i32 %ab23589}3590 3591define i32 @add_reduce_sqr_sum_order4_flipped(i32 %a, i32 %b) {3592; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped(3593; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3594; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3595; CHECK-NEXT: ret i32 [[AB2]]3596;3597 %a_sq = mul nsw i32 %a, %a3598 %ab = mul i32 %a, %b3599 %twoab = mul i32 %ab, 23600 %b_sq = mul i32 %b, %b3601 %a2_b2 = add i32 %a_sq, %b_sq3602 %ab2 = add i32 %a2_b2, %twoab3603 ret i32 %ab23604}3605 3606define i32 @add_reduce_sqr_sum_order4_flipped2(i32 %a, i32 %b) {3607; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped2(3608; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3609; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3610; CHECK-NEXT: ret i32 [[AB2]]3611;3612 %a_sq = mul nsw i32 %a, %a3613 %ab = mul i32 %a, %b3614 %twoab = mul i32 %ab, 23615 %b_sq = mul i32 %b, %b3616 %a2_b2 = add i32 %b_sq, %a_sq3617 %ab2 = add i32 %twoab, %a2_b23618 ret i32 %ab23619}3620 3621define i32 @add_reduce_sqr_sum_order4_flipped3(i32 %a, i32 %b) {3622; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped3(3623; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]3624; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3625; CHECK-NEXT: ret i32 [[AB2]]3626;3627 %a_sq = mul nsw i32 %a, %a3628 %ab = mul i32 %a, %b3629 %twoab = mul i32 2, %ab3630 %b_sq = mul i32 %b, %b3631 %a2_b2 = add i32 %a_sq, %b_sq3632 %ab2 = add i32 %twoab, %a2_b23633 ret i32 %ab23634}3635 3636define i32 @add_reduce_sqr_sum_order4_flipped4(i32 %a, i32 %b) {3637; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped4(3638; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]3639; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3640; CHECK-NEXT: ret i32 [[AB2]]3641;3642 %a_sq = mul nsw i32 %a, %a3643 %ab = mul i32 %b, %a3644 %twoab = mul i32 %ab, 23645 %b_sq = mul i32 %b, %b3646 %a2_b2 = add i32 %a_sq, %b_sq3647 %ab2 = add i32 %twoab, %a2_b23648 ret i32 %ab23649}3650 3651define i32 @add_reduce_sqr_sum_order5(i32 %a, i32 %b) {3652; CHECK-LABEL: @add_reduce_sqr_sum_order5(3653; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]3654; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3655; CHECK-NEXT: ret i32 [[AB2]]3656;3657 %a_sq = mul nsw i32 %a, %a3658 %twob = mul i32 %b, 23659 %twoab = mul i32 %twob, %a3660 %b_sq = mul i32 %b, %b3661 %a2_b2 = add i32 %a_sq, %b_sq3662 %ab2 = add i32 %twoab, %a2_b23663 ret i32 %ab23664}3665 3666define i32 @add_reduce_sqr_sum_order5_flipped(i32 %a, i32 %b) {3667; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped(3668; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]3669; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3670; CHECK-NEXT: ret i32 [[AB2]]3671;3672 %a_sq = mul nsw i32 %a, %a3673 %twob = mul i32 %b, 23674 %twoab = mul i32 %twob, %a3675 %b_sq = mul i32 %b, %b3676 %a2_b2 = add i32 %a_sq, %b_sq3677 %ab2 = add i32 %a2_b2, %twoab3678 ret i32 %ab23679}3680 3681define i32 @add_reduce_sqr_sum_order5_flipped2(i32 %a, i32 %b) {3682; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped2(3683; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]3684; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3685; CHECK-NEXT: ret i32 [[AB2]]3686;3687 %a_sq = mul nsw i32 %a, %a3688 %twob = mul i32 %b, 23689 %twoab = mul i32 %twob, %a3690 %b_sq = mul i32 %b, %b3691 %a2_b2 = add i32 %b_sq, %a_sq3692 %ab2 = add i32 %twoab, %a2_b23693 ret i32 %ab23694}3695 3696define i32 @add_reduce_sqr_sum_order5_flipped3(i32 %ax, i32 %b) {3697; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped3(3698; CHECK-NEXT: [[A:%.*]] = xor i32 [[AX:%.*]], 423699; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A]]3700; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3701; CHECK-NEXT: ret i32 [[AB2]]3702;3703 %a = xor i32 %ax, 42 ; thwart complexity-based canonicalization3704 %a_sq = mul nsw i32 %a, %a3705 %twob = mul i32 %b, 23706 %twoab = mul i32 %a, %twob3707 %b_sq = mul i32 %b, %b3708 %a2_b2 = add i32 %a_sq, %b_sq3709 %ab2 = add i32 %twoab, %a2_b23710 ret i32 %ab23711}3712 3713define i32 @add_reduce_sqr_sum_order5_flipped4(i32 %a, i32 %b) {3714; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped4(3715; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]3716; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]3717; CHECK-NEXT: ret i32 [[AB2]]3718;3719 %a_sq = mul nsw i32 %a, %a3720 %twob = mul i32 2, %b3721 %twoab = mul i32 %twob, %a3722 %b_sq = mul i32 %b, %b3723 %a2_b2 = add i32 %a_sq, %b_sq3724 %ab2 = add i32 %twoab, %a2_b23725 ret i32 %ab23726}3727 3728define i32 @add_reduce_sqr_sum_not_one_use(i32 %a, i32 %b) {3729; CHECK-LABEL: @add_reduce_sqr_sum_not_one_use(3730; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3731; CHECK-NEXT: [[TWO_A:%.*]] = shl i32 [[A]], 13732; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]3733; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]3734; CHECK-NEXT: tail call void @fake_func(i32 [[MUL]])3735; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]3736; CHECK-NEXT: ret i32 [[ADD]]3737;3738 %a_sq = mul nsw i32 %a, %a3739 %two_a = shl i32 %a, 13740 %two_a_plus_b = add i32 %two_a, %b3741 %mul = mul i32 %two_a_plus_b, %b3742 tail call void @fake_func (i32 %mul)3743 %add = add i32 %mul, %a_sq3744 ret i32 %add3745}3746 3747define i32 @add_reduce_sqr_sum_not_one_use2(i32 %a, i32 %b) {3748; CHECK-LABEL: @add_reduce_sqr_sum_not_one_use2(3749; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3750; CHECK-NEXT: [[TWO_A:%.*]] = shl i32 [[A]], 13751; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]3752; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]3753; CHECK-NEXT: tail call void @fake_func(i32 [[A_SQ]])3754; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]3755; CHECK-NEXT: ret i32 [[ADD]]3756;3757 %a_sq = mul nsw i32 %a, %a3758 %two_a = shl i32 %a, 13759 %two_a_plus_b = add i32 %two_a, %b3760 %mul = mul i32 %two_a_plus_b, %b3761 tail call void @fake_func (i32 %a_sq)3762 %add = add i32 %mul, %a_sq3763 ret i32 %add3764}3765 3766define i32 @add_reduce_sqr_sum_order2_not_one_use(i32 %a, i32 %b) {3767; CHECK-LABEL: @add_reduce_sqr_sum_order2_not_one_use(3768; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3769; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 13770; CHECK-NEXT: [[TWOAB1:%.*]] = add i32 [[TWOA]], [[B:%.*]]3771; CHECK-NEXT: [[TWOAB_B2:%.*]] = mul i32 [[TWOAB1]], [[B]]3772; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB_B2]])3773; CHECK-NEXT: [[AB2:%.*]] = add i32 [[A_SQ]], [[TWOAB_B2]]3774; CHECK-NEXT: ret i32 [[AB2]]3775;3776 %a_sq = mul nsw i32 %a, %a3777 %twoa = mul i32 %a, 23778 %twoab = mul i32 %twoa, %b3779 %b_sq = mul i32 %b, %b3780 %twoab_b2 = add i32 %twoab, %b_sq3781 tail call void @fake_func (i32 %twoab_b2)3782 %ab2 = add i32 %a_sq, %twoab_b23783 ret i32 %ab23784}3785 3786define i32 @add_reduce_sqr_sum_order2_not_one_use2(i32 %a, i32 %b) {3787; CHECK-LABEL: @add_reduce_sqr_sum_order2_not_one_use2(3788; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3789; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 13790; CHECK-NEXT: [[TWOAB1:%.*]] = add i32 [[TWOA]], [[B:%.*]]3791; CHECK-NEXT: [[TWOAB_B2:%.*]] = mul i32 [[TWOAB1]], [[B]]3792; CHECK-NEXT: tail call void @fake_func(i32 [[A_SQ]])3793; CHECK-NEXT: [[AB2:%.*]] = add i32 [[A_SQ]], [[TWOAB_B2]]3794; CHECK-NEXT: ret i32 [[AB2]]3795;3796 %a_sq = mul nsw i32 %a, %a3797 %twoa = mul i32 %a, 23798 %twoab = mul i32 %twoa, %b3799 %b_sq = mul i32 %b, %b3800 %twoab_b2 = add i32 %twoab, %b_sq3801 tail call void @fake_func (i32 %a_sq)3802 %ab2 = add i32 %a_sq, %twoab_b23803 ret i32 %ab23804}3805 3806define i32 @add_reduce_sqr_sum_order3_not_one_use(i32 %a, i32 %b) {3807; CHECK-LABEL: @add_reduce_sqr_sum_order3_not_one_use(3808; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3809; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 13810; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOA]], [[B:%.*]]3811; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]3812; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]3813; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB]])3814; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]3815; CHECK-NEXT: ret i32 [[AB2]]3816;3817 %a_sq = mul nsw i32 %a, %a3818 %twoa = mul i32 %a, 23819 %twoab = mul i32 %twoa, %b3820 %b_sq = mul i32 %b, %b3821 %a2_b2 = add i32 %a_sq, %b_sq3822 tail call void @fake_func (i32 %twoab)3823 %ab2 = add i32 %twoab, %a2_b23824 ret i32 %ab23825}3826 3827define i32 @add_reduce_sqr_sum_order3_not_one_use2(i32 %a, i32 %b) {3828; CHECK-LABEL: @add_reduce_sqr_sum_order3_not_one_use2(3829; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3830; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 13831; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOA]], [[B:%.*]]3832; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]3833; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]3834; CHECK-NEXT: tail call void @fake_func(i32 [[A2_B2]])3835; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]3836; CHECK-NEXT: ret i32 [[AB2]]3837;3838 %a_sq = mul nsw i32 %a, %a3839 %twoa = mul i32 %a, 23840 %twoab = mul i32 %twoa, %b3841 %b_sq = mul i32 %b, %b3842 %a2_b2 = add i32 %a_sq, %b_sq3843 tail call void @fake_func (i32 %a2_b2)3844 %ab2 = add i32 %twoab, %a2_b23845 ret i32 %ab23846}3847 3848define i32 @add_reduce_sqr_sum_order4_not_one_use(i32 %a, i32 %b) {3849; CHECK-LABEL: @add_reduce_sqr_sum_order4_not_one_use(3850; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3851; CHECK-NEXT: [[AB:%.*]] = mul i32 [[A]], [[B:%.*]]3852; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[AB]], 13853; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]3854; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]3855; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB]])3856; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]3857; CHECK-NEXT: ret i32 [[AB2]]3858;3859 %a_sq = mul nsw i32 %a, %a3860 %ab = mul i32 %a, %b3861 %twoab = mul i32 %ab, 23862 %b_sq = mul i32 %b, %b3863 %a2_b2 = add i32 %a_sq, %b_sq3864 tail call void @fake_func (i32 %twoab)3865 %ab2 = add i32 %twoab, %a2_b23866 ret i32 %ab23867}3868 3869define i32 @add_reduce_sqr_sum_order4_not_one_use2(i32 %a, i32 %b) {3870; CHECK-LABEL: @add_reduce_sqr_sum_order4_not_one_use2(3871; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3872; CHECK-NEXT: [[AB:%.*]] = mul i32 [[A]], [[B:%.*]]3873; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[AB]], 13874; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]3875; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]3876; CHECK-NEXT: tail call void @fake_func(i32 [[A2_B2]])3877; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]3878; CHECK-NEXT: ret i32 [[AB2]]3879;3880 %a_sq = mul nsw i32 %a, %a3881 %ab = mul i32 %a, %b3882 %twoab = mul i32 %ab, 23883 %b_sq = mul i32 %b, %b3884 %a2_b2 = add i32 %a_sq, %b_sq3885 tail call void @fake_func (i32 %a2_b2)3886 %ab2 = add i32 %twoab, %a2_b23887 ret i32 %ab23888}3889 3890define i32 @add_reduce_sqr_sum_order5_not_one_use(i32 %a, i32 %b) {3891; CHECK-LABEL: @add_reduce_sqr_sum_order5_not_one_use(3892; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3893; CHECK-NEXT: [[TWOB:%.*]] = shl i32 [[B:%.*]], 13894; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOB]], [[A]]3895; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]3896; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]3897; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB]])3898; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]3899; CHECK-NEXT: ret i32 [[AB2]]3900;3901 %a_sq = mul nsw i32 %a, %a3902 %twob = mul i32 %b, 23903 %twoab = mul i32 %twob, %a3904 %b_sq = mul i32 %b, %b3905 %a2_b2 = add i32 %a_sq, %b_sq3906 tail call void @fake_func (i32 %twoab)3907 %ab2 = add i32 %twoab, %a2_b23908 ret i32 %ab23909}3910 3911define i32 @add_reduce_sqr_sum_order5_not_one_use2(i32 %a, i32 %b) {3912; CHECK-LABEL: @add_reduce_sqr_sum_order5_not_one_use2(3913; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3914; CHECK-NEXT: [[TWOB:%.*]] = shl i32 [[B:%.*]], 13915; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOB]], [[A]]3916; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]3917; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]3918; CHECK-NEXT: tail call void @fake_func(i32 [[A2_B2]])3919; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]3920; CHECK-NEXT: ret i32 [[AB2]]3921;3922 %a_sq = mul nsw i32 %a, %a3923 %twob = mul i32 %b, 23924 %twoab = mul i32 %twob, %a3925 %b_sq = mul i32 %b, %b3926 %a2_b2 = add i32 %a_sq, %b_sq3927 tail call void @fake_func (i32 %a2_b2)3928 %ab2 = add i32 %twoab, %a2_b23929 ret i32 %ab23930}3931 3932define i32 @add_reduce_sqr_sum_invalid0(i32 %a, i32 %b) {3933; CHECK-LABEL: @add_reduce_sqr_sum_invalid0(3934; CHECK-NEXT: [[TWO_A:%.*]] = shl i32 [[A:%.*]], 13935; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]3936; CHECK-NEXT: [[MUL1:%.*]] = add i32 [[TWO_A_PLUS_B]], [[A]]3937; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[MUL1]], [[B]]3938; CHECK-NEXT: ret i32 [[ADD]]3939;3940 %not_a_sq = mul nsw i32 %a, %b3941 %two_a = shl i32 %a, 13942 %two_a_plus_b = add i32 %two_a, %b3943 %mul = mul i32 %two_a_plus_b, %b3944 %add = add i32 %mul, %not_a_sq3945 ret i32 %add3946}3947 3948define i32 @add_reduce_sqr_sum_invalid1(i32 %a, i32 %b) {3949; CHECK-LABEL: @add_reduce_sqr_sum_invalid1(3950; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3951; CHECK-NEXT: [[NOT_TWO_A_PLUS_B:%.*]] = mul i32 [[A]], 33952; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[NOT_TWO_A_PLUS_B]], [[B:%.*]]3953; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]3954; CHECK-NEXT: ret i32 [[ADD]]3955;3956 %a_sq = mul nsw i32 %a, %a3957 %two_a = shl i32 %a, 13958 %not_two_a_plus_b = add i32 %two_a, %a3959 %mul = mul i32 %not_two_a_plus_b, %b3960 %add = add i32 %mul, %a_sq3961 ret i32 %add3962}3963 3964define i32 @add_reduce_sqr_sum_invalid2(i32 %a, i32 %b) {3965; CHECK-LABEL: @add_reduce_sqr_sum_invalid2(3966; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3967; CHECK-NEXT: [[NOT_TWO_A:%.*]] = shl i32 [[A]], 23968; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[NOT_TWO_A]], [[B:%.*]]3969; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]3970; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]3971; CHECK-NEXT: ret i32 [[ADD]]3972;3973 %a_sq = mul nsw i32 %a, %a3974 %not_two_a = shl i32 %a, 23975 %two_a_plus_b = add i32 %not_two_a, %b3976 %mul = mul i32 %two_a_plus_b, %b3977 %add = add i32 %mul, %a_sq3978 ret i32 %add3979}3980 3981define i32 @add_reduce_sqr_sum_invalid3(i32 %a, i32 %b) {3982; CHECK-LABEL: @add_reduce_sqr_sum_invalid3(3983; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = mul i32 [[B:%.*]], 33984; CHECK-NEXT: [[MUL1:%.*]] = add i32 [[TWO_A_PLUS_B]], [[A:%.*]]3985; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[MUL1]], [[A]]3986; CHECK-NEXT: ret i32 [[ADD]]3987;3988 %a_sq = mul nsw i32 %a, %a3989 %not_two_a = shl i32 %b, 13990 %two_a_plus_b = add i32 %not_two_a, %b3991 %mul = mul i32 %two_a_plus_b, %a3992 %add = add i32 %mul, %a_sq3993 ret i32 %add3994}3995 3996define i32 @add_reduce_sqr_sum_invalid4(i32 %a, i32 %b) {3997; CHECK-LABEL: @add_reduce_sqr_sum_invalid4(3998; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]3999; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = mul i32 [[B:%.*]], 34000; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]4001; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]4002; CHECK-NEXT: ret i32 [[ADD]]4003;4004 %a_sq = mul nsw i32 %a, %a4005 %not_two_a = shl i32 %b, 14006 %two_a_plus_b = add i32 %not_two_a, %b4007 %mul = mul i32 %two_a_plus_b, %b4008 %add = add i32 %mul, %a_sq4009 ret i32 %add4010}4011 4012define i32 @add_reduce_sqr_sum_varB_invalid0(i32 %a, i32 %b) {4013; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid0(4014; CHECK-NEXT: [[NOT_A_B:%.*]] = mul nsw i32 [[A:%.*]], [[A]]4015; CHECK-NEXT: [[TWOAB:%.*]] = shl nuw i32 [[NOT_A_B]], 14016; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]]4017; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B:%.*]], [[B]]4018; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]4019; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]4020; CHECK-NEXT: ret i32 [[AB2]]4021;4022 %not_a_b = mul nsw i32 %a, %a4023 %twoab = mul i32 %not_a_b, 24024 %a_sq = mul i32 %a, %a4025 %b_sq = mul i32 %b, %b4026 %a2_b2 = add i32 %a_sq, %b_sq4027 %ab2 = add i32 %twoab, %a2_b24028 ret i32 %ab24029}4030 4031define i32 @add_reduce_sqr_sum_varB_invalid1(i32 %a, i32 %b) {4032; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid1(4033; CHECK-NEXT: [[NOT_A_B:%.*]] = mul nsw i32 [[B:%.*]], [[B]]4034; CHECK-NEXT: [[TWOAB:%.*]] = shl nuw i32 [[NOT_A_B]], 14035; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A:%.*]], [[A]]4036; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]4037; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]4038; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]4039; CHECK-NEXT: ret i32 [[AB2]]4040;4041 %not_a_b = mul nsw i32 %b, %b4042 %twoab = mul i32 %not_a_b, 24043 %a_sq = mul i32 %a, %a4044 %b_sq = mul i32 %b, %b4045 %a2_b2 = add i32 %a_sq, %b_sq4046 %ab2 = add i32 %twoab, %a2_b24047 ret i32 %ab24048}4049 4050define i32 @add_reduce_sqr_sum_varB_invalid2(i32 %a, i32 %b) {4051; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid2(4052; CHECK-NEXT: [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]4053; CHECK-NEXT: [[NOT_TWOAB:%.*]] = shl i32 [[A_B]], 24054; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]]4055; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]4056; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]4057; CHECK-NEXT: [[AB2:%.*]] = add i32 [[NOT_TWOAB]], [[A2_B2]]4058; CHECK-NEXT: ret i32 [[AB2]]4059;4060 %a_b = mul nsw i32 %a, %b4061 %not_twoab = mul i32 %a_b, 44062 %a_sq = mul i32 %a, %a4063 %b_sq = mul i32 %b, %b4064 %a2_b2 = add i32 %a_sq, %b_sq4065 %ab2 = add i32 %not_twoab, %a2_b24066 ret i32 %ab24067}4068 4069define i32 @add_reduce_sqr_sum_varB_invalid3(i32 %a, i32 %b) {4070; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid3(4071; CHECK-NEXT: [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]4072; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[A_B]], 14073; CHECK-NEXT: [[B_SQ1:%.*]] = add i32 [[A]], [[B]]4074; CHECK-NEXT: [[A2_B2:%.*]] = mul i32 [[B]], [[B_SQ1]]4075; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]4076; CHECK-NEXT: ret i32 [[AB2]]4077;4078 %a_b = mul nsw i32 %a, %b4079 %twoab = mul i32 %a_b, 24080 %not_a_sq = mul i32 %b, %a4081 %b_sq = mul i32 %b, %b4082 %a2_b2 = add i32 %not_a_sq, %b_sq4083 %ab2 = add i32 %twoab, %a2_b24084 ret i32 %ab24085}4086 4087define i32 @add_reduce_sqr_sum_varB_invalid4(i32 %a, i32 %b) {4088; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid4(4089; CHECK-NEXT: [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]4090; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[A_B]], 14091; CHECK-NEXT: [[NOT_B_SQ1:%.*]] = add i32 [[A]], [[B]]4092; CHECK-NEXT: [[A2_B2:%.*]] = mul i32 [[A]], [[NOT_B_SQ1]]4093; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]4094; CHECK-NEXT: ret i32 [[AB2]]4095;4096 %a_b = mul nsw i32 %a, %b4097 %twoab = mul i32 %a_b, 24098 %a_sq = mul i32 %a, %a4099 %not_b_sq = mul i32 %b, %a4100 %a2_b2 = add i32 %a_sq, %not_b_sq4101 %ab2 = add i32 %twoab, %a2_b24102 ret i32 %ab24103}4104 4105define i32 @add_reduce_sqr_sum_varC_invalid0(i32 %a, i32 %b) {4106; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid0(4107; CHECK-NEXT: [[NOT_TWOA:%.*]] = shl nsw i32 [[B:%.*]], 14108; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[NOT_TWOA]], [[B]]4109; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A:%.*]], [[A]]4110; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]4111; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]4112; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]4113; CHECK-NEXT: ret i32 [[AB2]]4114;4115 %not_twoa = mul nsw i32 %b, 24116 %twoab = mul i32 %not_twoa, %b4117 %a_sq = mul i32 %a, %a4118 %b_sq = mul i32 %b, %b4119 %a2_b2 = add i32 %a_sq, %b_sq4120 %ab2 = add i32 %twoab, %a2_b24121 ret i32 %ab24122}4123 4124define i32 @add_reduce_sqr_sum_varC_invalid1(i32 %a, i32 %b) {4125; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid1(4126; CHECK-NEXT: [[NOT_TWOA:%.*]] = shl nsw i32 [[A:%.*]], 24127; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[NOT_TWOA]], [[B:%.*]]4128; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]]4129; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]]4130; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]4131; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]4132; CHECK-NEXT: ret i32 [[AB2]]4133;4134 %not_twoa = mul nsw i32 %a, 44135 %twoab = mul i32 %not_twoa, %b4136 %a_sq = mul i32 %a, %a4137 %b_sq = mul i32 %b, %b4138 %a2_b2 = add i32 %a_sq, %b_sq4139 %ab2 = add i32 %twoab, %a2_b24140 ret i32 %ab24141}4142 4143define i32 @add_reduce_sqr_sum_varC_invalid2(i32 %a, i32 %b) {4144; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid2(4145; CHECK-NEXT: [[TWOA:%.*]] = shl nsw i32 [[A:%.*]], 14146; CHECK-NEXT: [[NOT_TWOAB:%.*]] = mul i32 [[TWOA]], [[A]]4147; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]]4148; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B:%.*]], [[B]]4149; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]4150; CHECK-NEXT: [[AB2:%.*]] = add i32 [[NOT_TWOAB]], [[A2_B2]]4151; CHECK-NEXT: ret i32 [[AB2]]4152;4153 %twoa = mul nsw i32 %a, 24154 %not_twoab = mul i32 %twoa, %a4155 %a_sq = mul i32 %a, %a4156 %b_sq = mul i32 %b, %b4157 %a2_b2 = add i32 %a_sq, %b_sq4158 %ab2 = add i32 %not_twoab, %a2_b24159 ret i32 %ab24160}4161 4162define i32 @fold_sext_addition_or_disjoint(i8 %x) {4163; CHECK-LABEL: @fold_sext_addition_or_disjoint(4164; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i324165; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 12464166; CHECK-NEXT: ret i32 [[R]]4167;4168 %xx = or disjoint i8 %x, 124169 %se = sext i8 %xx to i324170 %r = add i32 %se, 12344171 ret i32 %r4172}4173 4174define i32 @fold_sext_addition_fail(i8 %x) {4175; CHECK-LABEL: @fold_sext_addition_fail(4176; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 124177; CHECK-NEXT: [[SE:%.*]] = sext i8 [[XX]] to i324178; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], 12344179; CHECK-NEXT: ret i32 [[R]]4180;4181 %xx = or i8 %x, 124182 %se = sext i8 %xx to i324183 %r = add i32 %se, 12344184 ret i32 %r4185}4186 4187define i32 @fold_zext_addition_or_disjoint(i8 %x) {4188; CHECK-LABEL: @fold_zext_addition_or_disjoint(4189; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i324190; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[TMP1]], 12464191; CHECK-NEXT: ret i32 [[R]]4192;4193 %xx = or disjoint i8 %x, 124194 %se = zext i8 %xx to i324195 %r = add i32 %se, 12344196 ret i32 %r4197}4198 4199define i32 @fold_zext_addition_or_disjoint2(i8 %x) {4200; CHECK-LABEL: @fold_zext_addition_or_disjoint2(4201; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 44202; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP1]] to i324203; CHECK-NEXT: ret i32 [[R]]4204;4205 %xx = or disjoint i8 %x, 184206 %se = zext i8 %xx to i324207 %r = add i32 %se, -144208 ret i32 %r4209}4210 4211define i32 @fold_zext_addition_fail(i8 %x) {4212; CHECK-LABEL: @fold_zext_addition_fail(4213; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 124214; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i324215; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SE]], 12344216; CHECK-NEXT: ret i32 [[R]]4217;4218 %xx = or i8 %x, 124219 %se = zext i8 %xx to i324220 %r = add i32 %se, 12344221 ret i32 %r4222}4223 4224define i32 @fold_zext_addition_fail2(i8 %x) {4225; CHECK-LABEL: @fold_zext_addition_fail2(4226; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 184227; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i324228; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], -144229; CHECK-NEXT: ret i32 [[R]]4230;4231 %xx = or i8 %x, 184232 %se = zext i8 %xx to i324233 %r = add i32 %se, -144234 ret i32 %r4235}4236 4237define i32 @fold_zext_nneg_add_const(i8 %x) {4238; CHECK-LABEL: @fold_zext_nneg_add_const(4239; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i324240; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 984241; CHECK-NEXT: ret i32 [[R]]4242;4243 %xx = add nsw i8 %x, 1234244 %ze = zext nneg i8 %xx to i324245 %r = add nsw i32 %ze, -254246 ret i32 %r4247}4248 4249define i32 @fold_zext_nneg_add_const_fail1(i8 %x) {4250; CHECK-LABEL: @fold_zext_nneg_add_const_fail1(4251; CHECK-NEXT: [[XX:%.*]] = add nsw i8 [[X:%.*]], 1234252; CHECK-NEXT: [[ZE:%.*]] = zext i8 [[XX]] to i324253; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[ZE]], -254254; CHECK-NEXT: ret i32 [[R]]4255;4256 %xx = add nsw i8 %x, 1234257 %ze = zext i8 %xx to i324258 %r = add nsw i32 %ze, -254259 ret i32 %r4260}4261 4262define i32 @fold_zext_nneg_add_const_fail2(i8 %x) {4263; CHECK-LABEL: @fold_zext_nneg_add_const_fail2(4264; CHECK-NEXT: [[XX:%.*]] = add i8 [[X:%.*]], 1234265; CHECK-NEXT: [[ZE:%.*]] = zext nneg i8 [[XX]] to i324266; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[ZE]], -254267; CHECK-NEXT: ret i32 [[R]]4268;4269 %xx = add i8 %x, 1234270 %ze = zext nneg i8 %xx to i324271 %r = add nsw i32 %ze, -254272 ret i32 %r4273}4274 4275declare void @llvm.assume(i1)4276declare i32 @llvm.ctlz.i32(i32, i1)4277 4278; Ceiling division by power-of-2: (x >> log2(N)) + ((x & (N-1)) != 0) -> (x + (N-1)) >> log2(N)4279; This is only valid when x + (N-1) doesn't overflow4280 4281; Test with known range that prevents overflow4282define i32 @ceil_div_by_8_known_range(i32 range(i32 0, 100) %x) {4283; CHECK-LABEL: @ceil_div_by_8_known_range(4284; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[X:%.*]], 74285; CHECK-NEXT: [[R:%.*]] = lshr i32 [[TMP1]], 34286; CHECK-NEXT: ret i32 [[R]]4287;4288 %shr = lshr i32 %x, 34289 %and = and i32 %x, 74290 %cmp = icmp ne i32 %and, 04291 %ext = zext i1 %cmp to i324292 %r = add i32 %shr, %ext4293 ret i32 %r4294}4295 4296; Test with the exact IR from the original testcase4297define i32 @ceil_div_from_clz(i32 %v) {4298; CHECK-LABEL: @ceil_div_from_clz(4299; CHECK-NEXT: [[CTLZ:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[V:%.*]], i1 false)4300; CHECK-NEXT: [[TMP1:%.*]] = sub nuw nsw i32 39, [[CTLZ]]4301; CHECK-NEXT: [[R:%.*]] = lshr i32 [[TMP1]], 34302; CHECK-NEXT: ret i32 [[R]]4303;4304 %ctlz = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 %v, i1 false)4305 %sub = sub nuw nsw i32 32, %ctlz4306 %shr = lshr i32 %sub, 34307 %and = and i32 %sub, 74308 %cmp = icmp ne i32 %and, 04309 %ext = zext i1 %cmp to i324310 %r = add nuw nsw i32 %shr, %ext4311 ret i32 %r4312}4313 4314; Vector version with known range4315define <2 x i32> @ceil_div_by_8_vec_range(<2 x i32> range(i32 0, 1000) %x) {4316; CHECK-LABEL: @ceil_div_by_8_vec_range(4317; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw <2 x i32> [[X:%.*]], splat (i32 7)4318; CHECK-NEXT: [[R:%.*]] = lshr <2 x i32> [[TMP1]], splat (i32 3)4319; CHECK-NEXT: ret <2 x i32> [[R]]4320;4321 %shr = lshr <2 x i32> %x, <i32 3, i32 3>4322 %and = and <2 x i32> %x, <i32 7, i32 7>4323 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>4324 %ext = zext <2 x i1> %cmp to <2 x i32>4325 %r = add <2 x i32> %shr, %ext4326 ret <2 x i32> %r4327}4328 4329; Ceiling division by 16 with known range4330define i16 @ceil_div_by_16_i16(i16 range(i16 0, 1000) %x) {4331; CHECK-LABEL: @ceil_div_by_16_i16(4332; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i16 [[X:%.*]], 154333; CHECK-NEXT: [[R:%.*]] = lshr i16 [[TMP1]], 44334; CHECK-NEXT: ret i16 [[R]]4335;4336 %shr = lshr i16 %x, 44337 %and = and i16 %x, 154338 %cmp = icmp ne i16 %and, 04339 %ext = zext i1 %cmp to i164340 %r = add i16 %shr, %ext4341 ret i16 %r4342}4343 4344; Negative test: no overflow guarantee - should NOT optimize4345define i32 @ceil_div_by_8_no_overflow_info(i32 %x) {4346; CHECK-LABEL: @ceil_div_by_8_no_overflow_info(4347; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 34348; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 74349; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 04350; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i324351; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SHR]], [[EXT]]4352; CHECK-NEXT: ret i32 [[R]]4353;4354 %shr = lshr i32 %x, 34355 %and = and i32 %x, 74356 %cmp = icmp ne i32 %and, 04357 %ext = zext i1 %cmp to i324358 %r = add i32 %shr, %ext4359 ret i32 %r4360}4361 4362; Negative test: nuw on final add doesn't help4363define i32 @ceil_div_by_8_only_nuw_on_add(i32 %x) {4364; CHECK-LABEL: @ceil_div_by_8_only_nuw_on_add(4365; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 34366; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 74367; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 04368; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i324369; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SHR]], [[EXT]]4370; CHECK-NEXT: ret i32 [[R]]4371;4372 %shr = lshr i32 %x, 34373 %and = and i32 %x, 74374 %cmp = icmp ne i32 %and, 04375 %ext = zext i1 %cmp to i324376 %r = add nuw i32 %shr, %ext ; nuw here doesn't prove x+7 won't overflow4377 ret i32 %r4378}4379 4380; Negative test: wrong mask4381define i32 @ceil_div_wrong_mask(i32 range(i32 0, 100) %x) {4382; CHECK-LABEL: @ceil_div_wrong_mask(4383; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 34384; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 64385; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 04386; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i324387; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SHR]], [[EXT]]4388; CHECK-NEXT: ret i32 [[R]]4389;4390 %shr = lshr i32 %x, 34391 %and = and i32 %x, 6 ; Wrong mask: should be 74392 %cmp = icmp ne i32 %and, 04393 %ext = zext i1 %cmp to i324394 %r = add i32 %shr, %ext4395 ret i32 %r4396}4397 4398; Negative test: wrong shift amount4399define i32 @ceil_div_wrong_shift(i32 range(i32 0, 100) %x) {4400; CHECK-LABEL: @ceil_div_wrong_shift(4401; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 44402; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 74403; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 04404; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i324405; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SHR]], [[EXT]]4406; CHECK-NEXT: ret i32 [[R]]4407;4408 %shr = lshr i32 %x, 4 ; Shift by 4, but mask is 7 (should be 15)4409 %and = and i32 %x, 74410 %cmp = icmp ne i32 %and, 04411 %ext = zext i1 %cmp to i324412 %r = add i32 %shr, %ext4413 ret i32 %r4414}4415 4416; Negative test: wrong comparison4417define i32 @ceil_div_wrong_cmp(i32 range(i32 0, 100) %x) {4418; CHECK-LABEL: @ceil_div_wrong_cmp(4419; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 34420; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 74421; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 04422; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i324423; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SHR]], [[EXT]]4424; CHECK-NEXT: ret i32 [[R]]4425;4426 %shr = lshr i32 %x, 34427 %and = and i32 %x, 74428 %cmp = icmp eq i32 %and, 0 ; Wrong: should be ne4429 %ext = zext i1 %cmp to i324430 %r = add i32 %shr, %ext4431 ret i32 %r4432}4433 4434; Multi-use test: all intermediate values have uses4435define i32 @ceil_div_multi_use(i32 range(i32 0, 100) %x) {4436; CHECK-LABEL: @ceil_div_multi_use(4437; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 34438; CHECK-NEXT: call void @use_i32(i32 [[SHR]])4439; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 74440; CHECK-NEXT: call void @use_i32(i32 [[AND]])4441; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 04442; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i324443; CHECK-NEXT: call void @use_i32(i32 [[EXT]])4444; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SHR]], [[EXT]]4445; CHECK-NEXT: ret i32 [[R]]4446;4447 %shr = lshr i32 %x, 34448 call void @use_i32(i32 %shr)4449 %and = and i32 %x, 74450 call void @use_i32(i32 %and)4451 %cmp = icmp ne i32 %and, 04452 %ext = zext i1 %cmp to i324453 call void @use_i32(i32 %ext)4454 %r = add i32 %shr, %ext4455 ret i32 %r4456}4457 4458; Commuted test: add operands are swapped 4459define i32 @ceil_div_commuted(i32 range(i32 0, 100) %x) {4460; CHECK-LABEL: @ceil_div_commuted(4461; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[X:%.*]], 74462; CHECK-NEXT: [[R:%.*]] = lshr i32 [[TMP1]], 34463; CHECK-NEXT: ret i32 [[R]]4464;4465 %shr = lshr i32 %x, 34466 %and = and i32 %x, 74467 %cmp = icmp ne i32 %and, 04468 %ext = zext i1 %cmp to i324469 %r = add i32 %ext, %shr ; Operands swapped4470 ret i32 %r4471}4472 4473; Commuted with multi-use4474define i32 @ceil_div_commuted_multi_use(i32 range(i32 0, 100) %x) {4475; CHECK-LABEL: @ceil_div_commuted_multi_use(4476; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 34477; CHECK-NEXT: call void @use_i32(i32 [[SHR]])4478; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 74479; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 04480; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i324481; CHECK-NEXT: call void @use_i32(i32 [[EXT]])4482; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SHR]], [[EXT]]4483; CHECK-NEXT: ret i32 [[R]]4484;4485 %shr = lshr i32 %x, 34486 call void @use_i32(i32 %shr)4487 %and = and i32 %x, 74488 %cmp = icmp ne i32 %and, 04489 %ext = zext i1 %cmp to i324490 call void @use_i32(i32 %ext)4491 %r = add i32 %ext, %shr ; Operands swapped4492 ret i32 %r4493}4494 4495; Multi-use test where only zext has multiple uses - should still optimize4496define i32 @ceil_div_zext_multi_use(i32 range(i32 0, 100) %x) {4497; CHECK-LABEL: @ceil_div_zext_multi_use(4498; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 74499; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 04500; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i324501; CHECK-NEXT: call void @use_i32(i32 [[EXT]])4502; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[X]], 74503; CHECK-NEXT: [[R:%.*]] = lshr i32 [[TMP1]], 34504; CHECK-NEXT: ret i32 [[R]]4505;4506 %shr = lshr i32 %x, 34507 %and = and i32 %x, 74508 %cmp = icmp ne i32 %and, 04509 %ext = zext i1 %cmp to i324510 call void @use_i32(i32 %ext)4511 %r = add i32 %shr, %ext4512 ret i32 %r4513}4514 4515; Multi-use with vector type4516define <2 x i32> @ceil_div_vec_multi_use(<2 x i32> range(i32 0, 1000) %x) {4517; CHECK-LABEL: @ceil_div_vec_multi_use(4518; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 3)4519; CHECK-NEXT: call void @use_vec(<2 x i32> [[SHR]])4520; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X]], splat (i32 7)4521; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer4522; CHECK-NEXT: [[EXT:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>4523; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i32> [[SHR]], [[EXT]]4524; CHECK-NEXT: ret <2 x i32> [[R]]4525;4526 %shr = lshr <2 x i32> %x, <i32 3, i32 3>4527 call void @use_vec(<2 x i32> %shr)4528 %and = and <2 x i32> %x, <i32 7, i32 7>4529 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>4530 %ext = zext <2 x i1> %cmp to <2 x i32>4531 %r = add <2 x i32> %shr, %ext4532 ret <2 x i32> %r4533}4534 4535declare void @use_i32(i32)4536declare void @use_vec(<2 x i32>)4537declare void @fake_func(i32)4538