brintos

brintos / llvm-project-archived public Read only

0
0
Text · 134.2 KiB · a16e30b Raw
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