brintos

brintos / llvm-project-archived public Read only

0
0
Text · 53.0 KiB · f0fdc5f Raw
1871 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(i32)6 7define i32 @test1(i32 %A) {8; CHECK-LABEL: @test1(9; CHECK-NEXT:    ret i32 [[A:%.*]]10;11  %B = sdiv i32 %A, 112  ret i32 %B13}14 15define i32 @test2(i32 %A) {16; CHECK-LABEL: @test2(17; CHECK-NEXT:    [[B1:%.*]] = lshr i32 [[A:%.*]], 318; CHECK-NEXT:    ret i32 [[B1]]19;20  %B = udiv i32 %A, 821  ret i32 %B22}23 24define i32 @sdiv_by_minus1(i32 %A) {25; CHECK-LABEL: @sdiv_by_minus1(26; CHECK-NEXT:    [[B:%.*]] = sub nsw i32 0, [[A:%.*]]27; CHECK-NEXT:    ret i32 [[B]]28;29  %B = sdiv i32 %A, -130  ret i32 %B31}32 33define <2 x i64> @sdiv_by_minus1_vec(<2 x i64> %x) {34; CHECK-LABEL: @sdiv_by_minus1_vec(35; CHECK-NEXT:    [[DIV:%.*]] = sub nsw <2 x i64> zeroinitializer, [[X:%.*]]36; CHECK-NEXT:    ret <2 x i64> [[DIV]]37;38  %div = sdiv <2 x i64> %x, <i64 -1, i64 -1>39  ret <2 x i64> %div40}41 42define <2 x i64> @sdiv_by_minus1_vec_poison_elt(<2 x i64> %x) {43; CHECK-LABEL: @sdiv_by_minus1_vec_poison_elt(44; CHECK-NEXT:    ret <2 x i64> poison45;46  %div = sdiv <2 x i64> %x, <i64 -1, i64 poison>47  ret <2 x i64> %div48}49 50define i32 @sdiv_by_sext_minus1(i1 %x, i32 %y) {51; CHECK-LABEL: @sdiv_by_sext_minus1(52; CHECK-NEXT:    [[DIV:%.*]] = sub nsw i32 0, [[Y:%.*]]53; CHECK-NEXT:    ret i32 [[DIV]]54;55  %sext = sext i1 %x to i3256  %div = sdiv i32 %y, %sext57  ret i32 %div58}59 60define <2 x i32> @sdiv_by_sext_minus1_vec(<2 x i1> %x, <2 x i32> %y) {61; CHECK-LABEL: @sdiv_by_sext_minus1_vec(62; CHECK-NEXT:    [[DIV:%.*]] = sub nsw <2 x i32> zeroinitializer, [[Y:%.*]]63; CHECK-NEXT:    ret <2 x i32> [[DIV]]64;65  %sext = sext <2 x i1> %x to <2 x i32>66  %div = sdiv <2 x i32> %y, %sext67  ret <2 x i32> %div68}69 70define i8 @udiv_by_negative(i8 %x) {71; CHECK-LABEL: @udiv_by_negative(72; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], -773; CHECK-NEXT:    [[A:%.*]] = zext i1 [[TMP1]] to i874; CHECK-NEXT:    ret i8 [[A]]75;76  %A = udiv i8 %x, 25077  ret i8 %A78}79 80define i32 @udiv_by_minus1(i32 %A) {81; CHECK-LABEL: @udiv_by_minus1(82; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], -183; CHECK-NEXT:    [[B:%.*]] = zext i1 [[TMP1]] to i3284; CHECK-NEXT:    ret i32 [[B]]85;86  %B = udiv i32 %A, -187  ret i32 %B88}89 90define <2 x i64> @udiv_by_minus1_vec(<2 x i64> %x) {91; CHECK-LABEL: @udiv_by_minus1_vec(92; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], splat (i64 -1)93; CHECK-NEXT:    [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64>94; CHECK-NEXT:    ret <2 x i64> [[DIV]]95;96  %div = udiv <2 x i64> %x, <i64 -1, i64 -1>97  ret <2 x i64> %div98}99 100define i32 @udiv_by_sext_all_ones(i1 %x, i32 %y) {101; CHECK-LABEL: @udiv_by_sext_all_ones(102; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[Y:%.*]], -1103; CHECK-NEXT:    [[DIV:%.*]] = zext i1 [[TMP1]] to i32104; CHECK-NEXT:    ret i32 [[DIV]]105;106  %sext = sext i1 %x to i32107  %div = udiv i32 %y, %sext108  ret i32 %div109}110 111define <2 x i32> @udiv_by_sext_all_ones_vec(<2 x i1> %x, <2 x i32> %y) {112; CHECK-LABEL: @udiv_by_sext_all_ones_vec(113; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32> [[Y:%.*]], splat (i32 -1)114; CHECK-NEXT:    [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>115; CHECK-NEXT:    ret <2 x i32> [[DIV]]116;117  %sext = sext <2 x i1> %x to <2 x i32>118  %div = udiv <2 x i32> %y, %sext119  ret <2 x i32> %div120}121 122define i32 @test5(i32 %A) {123; CHECK-LABEL: @test5(124; CHECK-NEXT:    ret i32 0125;126  %B = udiv i32 %A, -16127  %C = udiv i32 %B, -4128  ret i32 %C129}130 131define i1 @test6(i32 %A) {132; CHECK-LABEL: @test6(133; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A:%.*]], 123134; CHECK-NEXT:    ret i1 [[C]]135;136  %B = udiv i32 %A, 123137  ; A < 123138  %C = icmp eq i32 %B, 0139  ret i1 %C140}141 142define i1 @test7(i32 %A) {143; CHECK-LABEL: @test7(144; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -20145; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A_OFF]], 10146; CHECK-NEXT:    ret i1 [[C]]147;148  %B = udiv i32 %A, 10149  ; A >= 20 && A < 30150  %C = icmp eq i32 %B, 2151  ret i1 %C152}153 154define <2 x i1> @test7vec(<2 x i32> %A) {155; CHECK-LABEL: @test7vec(156; CHECK-NEXT:    [[A_OFF:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -20)157; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> [[A_OFF]], splat (i32 10)158; CHECK-NEXT:    ret <2 x i1> [[C]]159;160  %B = udiv <2 x i32> %A, <i32 10, i32 10>161  %C = icmp eq <2 x i32> %B, <i32 2, i32 2>162  ret <2 x i1> %C163}164 165define i1 @test8(i8 %A) {166; CHECK-LABEL: @test8(167; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[A:%.*]], -11168; CHECK-NEXT:    ret i1 [[C]]169;170  %B = udiv i8 %A, 123171  ; A >= 246172  %C = icmp eq i8 %B, 2173  ret i1 %C174}175 176define <2 x i1> @test8vec(<2 x i8> %A) {177; CHECK-LABEL: @test8vec(178; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i8> [[A:%.*]], splat (i8 -11)179; CHECK-NEXT:    ret <2 x i1> [[C]]180;181  %B = udiv <2 x i8> %A, <i8 123, i8 123>182  %C = icmp eq <2 x i8> %B, <i8 2, i8 2>183  ret <2 x i1> %C184}185 186define i1 @test9(i8 %A) {187; CHECK-LABEL: @test9(188; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[A:%.*]], -10189; CHECK-NEXT:    ret i1 [[C]]190;191  %B = udiv i8 %A, 123192  ; A < 246193  %C = icmp ne i8 %B, 2194  ret i1 %C195}196 197define <2 x i1> @test9vec(<2 x i8> %A) {198; CHECK-LABEL: @test9vec(199; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i8> [[A:%.*]], splat (i8 -10)200; CHECK-NEXT:    ret <2 x i1> [[C]]201;202  %B = udiv <2 x i8> %A, <i8 123, i8 123>203  %C = icmp ne <2 x i8> %B, <i8 2, i8 2>204  ret <2 x i1> %C205}206 207define i32 @test10(i32 %X, i1 %C) {208; CHECK-LABEL: @test10(209; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i32 6, i32 3210; CHECK-NEXT:    [[R1:%.*]] = lshr i32 [[X:%.*]], [[TMP1]]211; CHECK-NEXT:    ret i32 [[R1]]212;213  %V = select i1 %C, i32 64, i32 8214  %R = udiv i32 %X, %V215  ret i32 %R216}217 218define i32 @test11(i32 %X, i1 %C) {219; CHECK-LABEL: @test11(220; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i32 10, i32 5221; CHECK-NEXT:    [[B1:%.*]] = lshr i32 [[X:%.*]], [[TMP1]]222; CHECK-NEXT:    ret i32 [[B1]]223;224  %A = select i1 %C, i32 1024, i32 32225  %B = udiv i32 %X, %A226  ret i32 %B227}228 229; PR2328230define i32 @test12(i32 %x) {231; CHECK-LABEL: @test12(232; CHECK-NEXT:    ret i32 1233;234  %tmp3 = udiv i32 %x, %x		; 1235  ret i32 %tmp3236}237 238define i32 @test13(i32 %x) {239; CHECK-LABEL: @test13(240; CHECK-NEXT:    ret i32 1241;242  %tmp3 = sdiv i32 %x, %x		; 1243  ret i32 %tmp3244}245 246define i32 @test14(i8 %x) {247; CHECK-LABEL: @test14(248; CHECK-NEXT:    ret i32 0249;250  %zext = zext i8 %x to i32251  %div = udiv i32 %zext, 257	; 0252  ret i32 %div253}254 255; PR9814256define i32 @test15(i32 %a, i32 %b) {257; CHECK-LABEL: @test15(258; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], -2259; CHECK-NEXT:    [[DIV21:%.*]] = lshr i32 [[A:%.*]], [[TMP1]]260; CHECK-NEXT:    ret i32 [[DIV21]]261;262  %shl = shl i32 1, %b263  %div = lshr i32 %shl, 2264  %div2 = udiv i32 %a, %div265  ret i32 %div2266}267 268define <2 x i64> @test16(<2 x i64> %x) {269; CHECK-LABEL: @test16(270; CHECK-NEXT:    [[DIV:%.*]] = udiv <2 x i64> [[X:%.*]], splat (i64 192)271; CHECK-NEXT:    ret <2 x i64> [[DIV]]272;273  %shr = lshr <2 x i64> %x, <i64 5, i64 5>274  %div = udiv <2 x i64> %shr, <i64 6, i64 6>275  ret <2 x i64> %div276}277 278define i32 @test19(i32 %x) {279; CHECK-LABEL: @test19(280; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 1281; CHECK-NEXT:    [[A:%.*]] = zext i1 [[TMP1]] to i32282; CHECK-NEXT:    ret i32 [[A]]283;284  %A = udiv i32 1, %x285  ret i32 %A286}287 288define <2 x i32> @test19vec(<2 x i32> %x) {289; CHECK-LABEL: @test19vec(290; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 1)291; CHECK-NEXT:    [[A:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>292; CHECK-NEXT:    ret <2 x i32> [[A]]293;294  %A = udiv <2 x i32> <i32 1, i32 1>, %x295  ret <2 x i32> %A296}297 298define i32 @test20(i32 %x) {299; CHECK-LABEL: @test20(300; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X:%.*]]301; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X_FR]], 1302; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3303; CHECK-NEXT:    [[A:%.*]] = select i1 [[TMP2]], i32 [[X_FR]], i32 0304; CHECK-NEXT:    ret i32 [[A]]305;306  %A = sdiv i32 1, %x307  ret i32 %A308}309 310define <2 x i32> @test20vec(<2 x i32> %x) {311; CHECK-LABEL: @test20vec(312; CHECK-NEXT:    [[X_FR:%.*]] = freeze <2 x i32> [[X:%.*]]313; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X_FR]], splat (i32 1)314; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 3)315; CHECK-NEXT:    [[A:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[X_FR]], <2 x i32> zeroinitializer316; CHECK-NEXT:    ret <2 x i32> [[A]]317;318  %A = sdiv <2 x i32> <i32 1, i32 1>, %x319  ret <2 x i32> %A320}321 322define i32 @test21(i32 %a) {323; CHECK-LABEL: @test21(324; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], 3325; CHECK-NEXT:    ret i32 [[DIV]]326;327  %shl = shl nsw i32 %a, 2328  %div = sdiv i32 %shl, 12329  ret i32 %div330}331 332define i32 @test22(i32 %a) {333; CHECK-LABEL: @test22(334; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], 4335; CHECK-NEXT:    ret i32 [[DIV]]336;337  %mul = mul nsw i32 %a, 3338  %div = sdiv i32 %mul, 12339  ret i32 %div340}341 342define i32 @test23(i32 %a) {343; CHECK-LABEL: @test23(344; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[A:%.*]], 3345; CHECK-NEXT:    ret i32 [[DIV]]346;347  %shl = shl nuw i32 %a, 2348  %div = udiv i32 %shl, 12349  ret i32 %div350}351 352define i32 @test24(i32 %a) {353; CHECK-LABEL: @test24(354; CHECK-NEXT:    [[DIV1:%.*]] = lshr i32 [[A:%.*]], 2355; CHECK-NEXT:    ret i32 [[DIV1]]356;357  %mul = mul nuw i32 %a, 3358  %div = udiv i32 %mul, 12359  ret i32 %div360}361 362define i32 @test25(i32 %a) {363; CHECK-LABEL: @test25(364; CHECK-NEXT:    [[DIV:%.*]] = shl nsw i32 [[A:%.*]], 1365; CHECK-NEXT:    ret i32 [[DIV]]366;367  %shl = shl nsw i32 %a, 2368  %div = sdiv i32 %shl, 2369  ret i32 %div370}371 372define i32 @test26(i32 %a) {373; CHECK-LABEL: @test26(374; CHECK-NEXT:    [[DIV:%.*]] = shl nsw i32 [[A:%.*]], 2375; CHECK-NEXT:    ret i32 [[DIV]]376;377  %mul = mul nsw i32 %a, 12378  %div = sdiv i32 %mul, 3379  ret i32 %div380}381 382define i32 @test27(i32 %a) {383; CHECK-LABEL: @test27(384; CHECK-NEXT:    [[DIV:%.*]] = shl nuw i32 [[A:%.*]], 1385; CHECK-NEXT:    ret i32 [[DIV]]386;387  %shl = shl nuw i32 %a, 2388  %div = udiv i32 %shl, 2389  ret i32 %div390}391 392define i32 @test28(i32 %a) {393; CHECK-LABEL: @test28(394; CHECK-NEXT:    [[DIV:%.*]] = mul nuw i32 [[A:%.*]], 12395; CHECK-NEXT:    ret i32 [[DIV]]396;397  %mul = mul nuw i32 %a, 36398  %div = udiv i32 %mul, 3399  ret i32 %div400}401 402define i32 @test29(i32 %a) {403; CHECK-LABEL: @test29(404; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], 0405; CHECK-NEXT:    [[DIV:%.*]] = zext i1 [[TMP1]] to i32406; CHECK-NEXT:    ret i32 [[DIV]]407;408  %mul = shl nsw i32 %a, 31409  %div = sdiv i32 %mul, -2147483648410  ret i32 %div411}412 413define i32 @test30(i32 %a) {414; CHECK-LABEL: @test30(415; CHECK-NEXT:    ret i32 [[A:%.*]]416;417  %mul = shl nuw i32 %a, 31418  %div = udiv i32 %mul, -2147483648419  ret i32 %div420}421 422define <2 x i32> @test31(<2 x i32> %x) {423; CHECK-LABEL: @test31(424; CHECK-NEXT:    ret <2 x i32> zeroinitializer425;426  %shr = lshr <2 x i32> %x, <i32 31, i32 31>427  %div = udiv <2 x i32> %shr, <i32 2147483647, i32 2147483647>428  ret <2 x i32> %div429}430 431define i32 @test32(i32 %a, i32 %b) {432; CHECK-LABEL: @test32(433; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], -1434; CHECK-NEXT:    [[DIV2:%.*]] = lshr i32 [[A:%.*]], [[TMP1]]435; CHECK-NEXT:    ret i32 [[DIV2]]436;437  %shl = shl i32 2, %b438  %div = lshr i32 %shl, 2439  %div2 = udiv i32 %a, %div440  ret i32 %div2441}442 443define <2 x i64> @test33(<2 x i64> %x) {444; CHECK-LABEL: @test33(445; CHECK-NEXT:    [[DIV:%.*]] = udiv exact <2 x i64> [[X:%.*]], splat (i64 192)446; CHECK-NEXT:    ret <2 x i64> [[DIV]]447;448  %shr = lshr exact <2 x i64> %x, <i64 5, i64 5>449  %div = udiv exact <2 x i64> %shr, <i64 6, i64 6>450  ret <2 x i64> %div451}452 453; -X / C --> X / -C (if negation does not overflow)454 455define i8 @sdiv_negated_dividend_constant_divisor(i8 %x) {456; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor(457; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[X:%.*]], 42458; CHECK-NEXT:    ret i8 [[D]]459;460  %neg = sub nsw i8 0, %x461  %d = sdiv i8 %neg, -42462  ret i8 %d463}464 465define <2 x i8> @sdiv_negated_dividend_constant_divisor_vec_splat(<2 x i8> %x) {466; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec_splat(467; CHECK-NEXT:    [[D:%.*]] = sdiv <2 x i8> [[X:%.*]], splat (i8 42)468; CHECK-NEXT:    ret <2 x i8> [[D]]469;470  %neg = sub nsw <2 x i8> zeroinitializer, %x471  %d = sdiv <2 x i8> %neg, <i8 -42, i8 -42>472  ret <2 x i8> %d473}474 475define i8 @sdiv_exact_negated_dividend_constant_divisor(i8 %x) {476; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor(477; CHECK-NEXT:    [[D:%.*]] = sdiv exact i8 [[X:%.*]], 42478; CHECK-NEXT:    ret i8 [[D]]479;480  %neg = sub nsw i8 0, %x481  %d = sdiv exact i8 %neg, -42482  ret i8 %d483}484 485define <2 x i8> @sdiv_exact_negated_dividend_constant_divisor_vec_splat(<2 x i8> %x) {486; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor_vec_splat(487; CHECK-NEXT:    [[D:%.*]] = sdiv exact <2 x i8> [[X:%.*]], splat (i8 42)488; CHECK-NEXT:    ret <2 x i8> [[D]]489;490  %neg = sub nsw <2 x i8> zeroinitializer, %x491  %d = sdiv exact <2 x i8> %neg, <i8 -42, i8 -42>492  ret <2 x i8> %d493}494 495define i8 @sdiv_negated_dividend_constant_divisor_smin(i8 %x) {496; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_smin(497; CHECK-NEXT:    ret i8 0498;499  %neg = sub nsw i8 0, %x500  %d = sdiv i8 %neg, -128501  ret i8 %d502}503 504define <2 x i8> @sdiv_negated_dividend_constant_divisor_vec_splat_smin(<2 x i8> %x) {505; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec_splat_smin(506; CHECK-NEXT:    ret <2 x i8> zeroinitializer507;508  %neg = sub nsw <2 x i8> zeroinitializer, %x509  %d = sdiv <2 x i8> %neg, <i8 -128, i8 -128>510  ret <2 x i8> %d511}512 513define <2 x i8> @sdiv_negated_dividend_constant_divisor_vec_poison(<2 x i8> %x) {514; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec_poison(515; CHECK-NEXT:    ret <2 x i8> poison516;517  %neg = sub nsw <2 x i8> zeroinitializer, %x518  %d = sdiv <2 x i8> %neg, <i8 -128, i8 poison>519  ret <2 x i8> %d520}521 522define <2 x i64> @sdiv_negated_dividend_constant_divisor_vec(<2 x i64> %x) {523; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec(524; CHECK-NEXT:    [[DIV1_NEG:%.*]] = sdiv <2 x i64> [[X:%.*]], <i64 -3, i64 -4>525; CHECK-NEXT:    ret <2 x i64> [[DIV1_NEG]]526;527  %neg = sub nsw <2 x i64> zeroinitializer, %x528  %div = sdiv <2 x i64> %neg, <i64 3, i64 4>529  ret <2 x i64> %div530}531 532define <2 x i64> @sdiv_exact_negated_dividend_constant_divisor_vec(<2 x i64> %x) {533; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor_vec(534; CHECK-NEXT:    [[DIV1_NEG:%.*]] = sdiv exact <2 x i64> [[X:%.*]], <i64 -3, i64 -4>535; CHECK-NEXT:    ret <2 x i64> [[DIV1_NEG]]536;537  %neg = sub nsw <2 x i64> zeroinitializer, %x538  %div = sdiv exact <2 x i64> %neg, <i64 3, i64 4>539  ret <2 x i64> %div540}541 542; Can't negate signed min vector element.543 544define <2 x i8> @sdiv_exact_negated_dividend_constant_divisor_vec_overflow(<2 x i8> %x) {545; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor_vec_overflow(546; CHECK-NEXT:    [[DIV1:%.*]] = sdiv exact <2 x i8> [[X:%.*]], <i8 -128, i8 42>547; CHECK-NEXT:    [[DIV:%.*]] = sub nsw <2 x i8> zeroinitializer, [[DIV1]]548; CHECK-NEXT:    ret <2 x i8> [[DIV]]549;550  %neg = sub nsw <2 x i8> zeroinitializer, %x551  %div = sdiv exact <2 x i8> %neg, <i8 -128, i8 42>552  ret <2 x i8> %div553}554 555define i32 @test35(i32 %A) {556; CHECK-LABEL: @test35(557; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 2147483647558; CHECK-NEXT:    [[MUL:%.*]] = udiv exact i32 [[AND]], 2147483647559; CHECK-NEXT:    ret i32 [[MUL]]560;561  %and = and i32 %A, 2147483647562  %mul = sdiv exact i32 %and, 2147483647563  ret i32 %mul564}565 566define <2 x i32> @test35vec(<2 x i32> %A) {567; CHECK-LABEL: @test35vec(568; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 2147483647)569; CHECK-NEXT:    [[MUL:%.*]] = udiv exact <2 x i32> [[AND]], splat (i32 2147483647)570; CHECK-NEXT:    ret <2 x i32> [[MUL]]571;572  %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647>573  %mul = sdiv exact <2 x i32> %and, <i32 2147483647, i32 2147483647>574  ret <2 x i32> %mul575}576 577define i32 @test36(i32 %A) {578; CHECK-LABEL: @test36(579; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 2147483647580; CHECK-NEXT:    [[MUL:%.*]] = lshr exact i32 [[AND]], [[A]]581; CHECK-NEXT:    ret i32 [[MUL]]582;583  %and = and i32 %A, 2147483647584  %shl = shl nsw i32 1, %A585  %mul = sdiv exact i32 %and, %shl586  ret i32 %mul587}588 589define <2 x i32> @test36vec(<2 x i32> %A) {590; CHECK-LABEL: @test36vec(591; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 2147483647)592; CHECK-NEXT:    [[MUL:%.*]] = lshr exact <2 x i32> [[AND]], [[A]]593; CHECK-NEXT:    ret <2 x i32> [[MUL]]594;595  %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647>596  %shl = shl nsw <2 x i32> <i32 1, i32 1>, %A597  %mul = sdiv exact <2 x i32> %and, %shl598  ret <2 x i32> %mul599}600 601define i32 @test37(ptr %b, i1 %c1) {602; CHECK-LABEL: @test37(603; CHECK-NEXT:  entry:604; CHECK-NEXT:    store i32 0, ptr [[B:%.*]], align 4605; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LOR_RHS:%.*]], label [[LOR_END:%.*]]606; CHECK:       lor.rhs:607; CHECK-NEXT:    br label [[LOR_END]]608; CHECK:       lor.end:609; CHECK-NEXT:    ret i32 0610;611entry:612  store i32 0, ptr %b, align 4613  %0 = load i32, ptr %b, align 4614  br i1 %c1, label %lor.rhs, label %lor.end615 616lor.rhs:                                          ; preds = %entry617  %mul = mul nsw i32 1, %0618  br label %lor.end619 620lor.end:                                          ; preds = %lor.rhs, %entry621  %t.0 = phi i32 [ %0, %entry ], [ %mul, %lor.rhs ]622  %div = sdiv i32 %t.0, 2623  ret i32 %div624}625 626; We can perform the division in the smaller type.627 628define i32 @shrink(i8 %x) {629; CHECK-LABEL: @shrink(630; CHECK-NEXT:    [[TMP1:%.*]] = sdiv i8 [[X:%.*]], 127631; CHECK-NEXT:    [[DIV:%.*]] = sext i8 [[TMP1]] to i32632; CHECK-NEXT:    ret i32 [[DIV]]633;634  %conv = sext i8 %x to i32635  %div = sdiv i32 %conv, 127636  ret i32 %div637}638 639; Division in the smaller type can lead to more optimizations.640 641define i32 @zap(i8 %x) {642; CHECK-LABEL: @zap(643; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128644; CHECK-NEXT:    [[DIV:%.*]] = zext i1 [[TMP1]] to i32645; CHECK-NEXT:    ret i32 [[DIV]]646;647  %conv = sext i8 %x to i32648  %div = sdiv i32 %conv, -128649  ret i32 %div650}651 652; Splat constant divisors should get the same folds.653 654define <3 x i32> @shrink_vec(<3 x i8> %x) {655; CHECK-LABEL: @shrink_vec(656; CHECK-NEXT:    [[TMP1:%.*]] = sdiv <3 x i8> [[X:%.*]], splat (i8 127)657; CHECK-NEXT:    [[DIV:%.*]] = sext <3 x i8> [[TMP1]] to <3 x i32>658; CHECK-NEXT:    ret <3 x i32> [[DIV]]659;660  %conv = sext <3 x i8> %x to <3 x i32>661  %div = sdiv <3 x i32> %conv, <i32 127, i32 127, i32 127>662  ret <3 x i32> %div663}664 665define <2 x i32> @zap_vec(<2 x i8> %x) {666; CHECK-LABEL: @zap_vec(667; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128)668; CHECK-NEXT:    [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>669; CHECK-NEXT:    ret <2 x i32> [[DIV]]670;671  %conv = sext <2 x i8> %x to <2 x i32>672  %div = sdiv <2 x i32> %conv, <i32 -128, i32 -128>673  ret <2 x i32> %div674}675 676; But we can't do this if the signed constant won't fit in the original type.677 678define i32 @shrink_no(i8 %x) {679; CHECK-LABEL: @shrink_no(680; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[X:%.*]] to i32681; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], 128682; CHECK-NEXT:    ret i32 [[DIV]]683;684  %conv = sext i8 %x to i32685  %div = sdiv i32 %conv, 128686  ret i32 %div687}688 689; When the divisor is known larger than the quotient,690; InstSimplify should kill it before InstCombine sees it.691 692define i32 @shrink_no2(i8 %x) {693; CHECK-LABEL: @shrink_no2(694; CHECK-NEXT:    ret i32 0695;696  %conv = sext i8 %x to i32697  %div = sdiv i32 %conv, -129698  ret i32 %div699}700 701define i32 @shrink_no3(i16 %x) {702; CHECK-LABEL: @shrink_no3(703; CHECK-NEXT:    ret i32 0704;705  %conv = sext i16 %x to i32706  %div = sdiv i32 %conv, 65535707  ret i32 %div708}709 710; This previously crashed when trying to simplify the zext/icmp this becomes.711define <2 x i8> @PR34841(<2 x i8> %x) {712; CHECK-LABEL: @PR34841(713; CHECK-NEXT:    ret <2 x i8> zeroinitializer714;715  %neg = and <2 x i8> %x, <i8 2, i8 2>716  %div = udiv <2 x i8> <i8 1, i8 1>, %neg717  ret <2 x i8> %div718}719 720; X / (X * Y) -> 1 / Y if the multiplication does not overflow721 722define i8 @div_factor_signed(i8 %x, i8 %y) {723; CHECK-LABEL: @div_factor_signed(724; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i8 [[Y:%.*]]725; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y_FR]], 1726; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], 3727; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i8 [[Y_FR]], i8 0728; CHECK-NEXT:    ret i8 [[R]]729;730  %a = mul nsw i8 %x, %y731  %r = sdiv i8 %x, %a732  ret i8 %r733}734 735; X / (Y * X) -> 1 / Y if the multiplication does not overflow736 737define <2 x i8> @div_factor_signed_vec(<2 x i8> %x, <2 x i8> %y) {738; CHECK-LABEL: @div_factor_signed_vec(739; CHECK-NEXT:    [[Y_FR:%.*]] = freeze <2 x i8> [[Y:%.*]]740; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[Y_FR]], splat (i8 1)741; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i8> [[TMP1]], splat (i8 3)742; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i8> [[Y_FR]], <2 x i8> zeroinitializer743; CHECK-NEXT:    ret <2 x i8> [[R]]744;745  %a = mul nsw <2 x i8> %y, %x746  %r = sdiv <2 x i8> %x, %a747  ret <2 x i8> %r748}749 750; X / (Y * X) -> 1 / Y if the multiplication does not overflow751 752define i8 @div_factor_unsigned(i8 %x, i8 %y) {753; CHECK-LABEL: @div_factor_unsigned(754; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 1755; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP1]] to i8756; CHECK-NEXT:    ret i8 [[R]]757;758  %a = mul nuw i8 %y, %x759  %r = udiv i8 %x, %a760  ret i8 %r761}762 763; X / (X * Y) -> 1 / Y if the multiplication does not overflow764 765define <2 x i8> @div_factor_unsigned_vec(<2 x i8> %x, <2 x i8> %y) {766; CHECK-LABEL: @div_factor_unsigned_vec(767; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[Y:%.*]], splat (i8 1)768; CHECK-NEXT:    [[R:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>769; CHECK-NEXT:    ret <2 x i8> [[R]]770;771  %a = mul nuw <2 x i8> %x, %y772  %r = udiv <2 x i8> %x, %a773  ret <2 x i8> %r774}775 776define i8 @udiv_common_factor(i8 %x, i8 %y, i8 %z) {777; CHECK-LABEL: @udiv_common_factor(778; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]779; CHECK-NEXT:    ret i8 [[C]]780;781  %a = mul nuw i8 %z, %x782  %b = mul nuw i8 %z, %y783  %c = udiv i8 %a, %b784  ret i8 %c785}786 787define <2 x i8> @udiv_common_factor_commute1_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {788; CHECK-LABEL: @udiv_common_factor_commute1_vec(789; CHECK-NEXT:    [[C:%.*]] = udiv <2 x i8> [[X:%.*]], [[Y:%.*]]790; CHECK-NEXT:    ret <2 x i8> [[C]]791;792  %a = mul nuw <2 x i8> %x, %z793  %b = mul nuw <2 x i8> %z, %y794  %c = udiv <2 x i8> %a, %b795  ret <2 x i8> %c796}797 798define i8 @udiv_common_factor_commute2(i8 %x, i8 %y, i8 %z) {799; CHECK-LABEL: @udiv_common_factor_commute2(800; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]801; CHECK-NEXT:    ret i8 [[C]]802;803  %a = mul nuw i8 %x, %z804  %b = mul nuw i8 %y, %z805  %c = udiv i8 %a, %b806  ret i8 %c807}808 809define i8 @udiv_common_factor_commute3(i8 %x, i8 %y, i8 %z) {810; CHECK-LABEL: @udiv_common_factor_commute3(811; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]812; CHECK-NEXT:    ret i8 [[C]]813;814  %a = mul nuw i8 %z, %x815  %b = mul nuw i8 %y, %z816  %c = udiv i8 %a, %b817  ret i8 %c818}819 820; Negative test: both mul must be 'nuw'.821 822define i8 @udiv_common_factor_not_nuw(i8 %x, i8 %y, i8 %z) {823; CHECK-LABEL: @udiv_common_factor_not_nuw(824; CHECK-NEXT:    [[A:%.*]] = mul i8 [[Z:%.*]], [[X:%.*]]825; CHECK-NEXT:    [[B:%.*]] = mul nuw i8 [[Z]], [[Y:%.*]]826; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[A]], [[B]]827; CHECK-NEXT:    ret i8 [[C]]828;829  %a = mul i8 %z, %x830  %b = mul nuw i8 %z, %y831  %c = udiv i8 %a, %b832  ret i8 %c833}834 835; Negative test: both mul must be 'nuw'.836 837define <2 x i8> @udiv_common_factor_not_nuw_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {838; CHECK-LABEL: @udiv_common_factor_not_nuw_vec(839; CHECK-NEXT:    [[A:%.*]] = mul nuw <2 x i8> [[Z:%.*]], [[X:%.*]]840; CHECK-NEXT:    [[B:%.*]] = mul <2 x i8> [[Z]], [[Y:%.*]]841; CHECK-NEXT:    [[C:%.*]] = udiv <2 x i8> [[A]], [[B]]842; CHECK-NEXT:    ret <2 x i8> [[C]]843;844  %a = mul nuw <2 x i8> %z, %x845  %b = mul <2 x i8> %z, %y846  %c = udiv <2 x i8> %a, %b847  ret <2 x i8> %c848}849 850define i32 @test_exact_nsw_exact(i32 %x) {851; CHECK-LABEL: @test_exact_nsw_exact(852; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv exact i32 [[X:%.*]], -3853; CHECK-NEXT:    ret i32 [[DIV_NEG]]854;855  %div = sdiv exact i32 %x, 3856  %neg = sub nsw i32 0, %div857  ret i32 %neg858}859 860define <2 x i64> @test_exact_vec(<2 x i64> %x) {861; CHECK-LABEL: @test_exact_vec(862; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv exact <2 x i64> [[X:%.*]], <i64 -3, i64 -4>863; CHECK-NEXT:    ret <2 x i64> [[DIV_NEG]]864;865  %div = sdiv exact <2 x i64> %x, <i64 3, i64 4>866  %neg = sub nsw <2 x i64> zeroinitializer, %div867  ret <2 x i64> %neg868}869 870; Constant is safe to negate.871 872define <2 x i8> @negate_sdiv_vec_splat(<2 x i8> %x) {873; CHECK-LABEL: @negate_sdiv_vec_splat(874; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv <2 x i8> [[X:%.*]], splat (i8 -42)875; CHECK-NEXT:    ret <2 x i8> [[DIV_NEG]]876;877  %div = sdiv <2 x i8> %x, <i8 42, i8 42>878  %neg = sub <2 x i8> zeroinitializer, %div879  ret <2 x i8> %neg880}881 882; Dividing by poison is UB.883 884define <2 x i8> @negate_sdiv_vec_poison_elt(<2 x i8> %x) {885; CHECK-LABEL: @negate_sdiv_vec_poison_elt(886; CHECK-NEXT:    ret <2 x i8> poison887;888  %div = sdiv <2 x i8> %x, <i8 poison, i8 42>889  %neg = sub <2 x i8> zeroinitializer, %div890  ret <2 x i8> %neg891}892 893; Division by -1 may be UB (if numerator is the signed min val), but div-by-1 can be simplified.894 895define <2 x i8> @negate_sdiv_vec_splat_one(<2 x i8> %x) {896; CHECK-LABEL: @negate_sdiv_vec_splat_one(897; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]]898; CHECK-NEXT:    ret <2 x i8> [[NEG]]899;900  %div = sdiv <2 x i8> %x, <i8 1, i8 1>901  %neg = sub <2 x i8> zeroinitializer, %div902  ret <2 x i8> %neg903}904 905; Can't negate signed-min constant, but can convert to a compare..906 907define <2 x i8> @negate_sdiv_vec_splat_signed_min(<2 x i8> %x) {908; CHECK-LABEL: @negate_sdiv_vec_splat_signed_min(909; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128)910; CHECK-NEXT:    [[DIV_NEG:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>911; CHECK-NEXT:    ret <2 x i8> [[DIV_NEG]]912;913  %div = sdiv <2 x i8> %x, <i8 -128, i8 -128>914  %neg = sub <2 x i8> zeroinitializer, %div915  ret <2 x i8> %neg916}917 918; Division by -1 may be UB for any element of a vector.919 920define <2 x i8> @negate_sdiv_vec_one_element(<2 x i8> %x) {921; CHECK-LABEL: @negate_sdiv_vec_one_element(922; CHECK-NEXT:    [[DIV:%.*]] = sdiv <2 x i8> [[X:%.*]], <i8 -1, i8 1>923; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[DIV]]924; CHECK-NEXT:    ret <2 x i8> [[NEG]]925;926  %div = sdiv <2 x i8> %x, <i8 -1, i8 1>927  %neg = sub <2 x i8> zeroinitializer, %div928  ret <2 x i8> %neg929}930 931; Can't negate signed-min constant for any element of a vector.932 933define <2 x i8> @negate_sdiv_vec_signed_min_elt(<2 x i8> %x) {934; CHECK-LABEL: @negate_sdiv_vec_signed_min_elt(935; CHECK-NEXT:    [[DIV:%.*]] = sdiv <2 x i8> [[X:%.*]], <i8 -1, i8 -128>936; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[DIV]]937; CHECK-NEXT:    ret <2 x i8> [[NEG]]938;939  %div = sdiv <2 x i8> %x, <i8 -1, i8 -128>940  %neg = sub <2 x i8> zeroinitializer, %div941  ret <2 x i8> %neg942}943 944; Division by -1 may be UB and can't negate signed-min.945 946define <2 x i8> @negate_sdiv_vec_signed_min_and_one_elt(<2 x i8> %x) {947; CHECK-LABEL: @negate_sdiv_vec_signed_min_and_one_elt(948; CHECK-NEXT:    [[DIV:%.*]] = sdiv <2 x i8> [[X:%.*]], <i8 1, i8 -128>949; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[DIV]]950; CHECK-NEXT:    ret <2 x i8> [[NEG]]951;952  %div = sdiv <2 x i8> %x, <i8 1, i8 -128>953  %neg = sub <2 x i8> zeroinitializer, %div954  ret <2 x i8> %neg955}956 957define i32 @test_exact_nonsw_exact(i32 %x) {958; CHECK-LABEL: @test_exact_nonsw_exact(959; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv exact i32 [[X:%.*]], -3960; CHECK-NEXT:    ret i32 [[DIV_NEG]]961;962  %div = sdiv exact i32 %x, 3963  %neg = sub i32 0, %div964  ret i32 %neg965}966 967define i32 @test_exact_nsw_noexact(i32 %x) {968; CHECK-LABEL: @test_exact_nsw_noexact(969; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv i32 [[X:%.*]], -3970; CHECK-NEXT:    ret i32 [[DIV_NEG]]971;972  %div = sdiv i32 %x, 3973  %neg = sub nsw i32 0, %div974  ret i32 %neg975}976 977define i32 @test_exact_nonsw_noexact(i32 %x) {978; CHECK-LABEL: @test_exact_nonsw_noexact(979; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv i32 [[X:%.*]], -3980; CHECK-NEXT:    ret i32 [[DIV_NEG]]981;982  %div = sdiv i32 %x, 3983  %neg = sub i32 0, %div984  ret i32 %neg985}986 987define i32 @test_exact_div_nonconst(i32 %x, i32 %y) {988; CHECK-LABEL: @test_exact_div_nonconst(989; CHECK-NEXT:    [[DIV:%.*]] = sdiv exact i32 [[X:%.*]], [[Y:%.*]]990; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[DIV]]991; CHECK-NEXT:    ret i32 [[NEG]]992;993  %div = sdiv exact i32 %x, %y994  %neg = sub nsw i32 0, %div995  ret i32 %neg996}997 998define i32 @test_exact_div_one(i32 %x) {999; CHECK-LABEL: @test_exact_div_one(1000; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[X:%.*]]1001; CHECK-NEXT:    ret i32 [[NEG]]1002;1003  %div = sdiv exact i32 %x, 11004  %neg = sub nsw i32 0, %div1005  ret i32 %neg1006}1007 1008define i8 @test_exact_div_minSigned(i8 %x) {1009; CHECK-LABEL: @test_exact_div_minSigned(1010; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -1281011; CHECK-NEXT:    [[DIV_NEG:%.*]] = sext i1 [[TMP1]] to i81012; CHECK-NEXT:    ret i8 [[DIV_NEG]]1013;1014  %div = sdiv exact i8 %x, -1281015  %neg = sub nsw i8 0, %div1016  ret i8 %neg1017}1018 1019; X / INT_MIN --> X == INT_MIN1020 1021define i8 @sdiv_by_int_min(i8 %x) {1022; CHECK-LABEL: @sdiv_by_int_min(1023; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -1281024; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP1]] to i81025; CHECK-NEXT:    ret i8 [[D]]1026;1027  %d = sdiv i8 %x, -1281028  ret i8 %d1029}1030 1031define <2 x i8> @sdiv_by_int_min_vec_splat(<2 x i8> %x) {1032; CHECK-LABEL: @sdiv_by_int_min_vec_splat(1033; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128)1034; CHECK-NEXT:    [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>1035; CHECK-NEXT:    ret <2 x i8> [[D]]1036;1037  %d = sdiv <2 x i8> %x, <i8 -128, i8 -128>1038  ret <2 x i8> %d1039}1040 1041define <2 x i8> @sdiv_by_int_min_vec_splat_poison(<2 x i8> %x) {1042; CHECK-LABEL: @sdiv_by_int_min_vec_splat_poison(1043; CHECK-NEXT:    ret <2 x i8> poison1044;1045  %d = sdiv <2 x i8> %x, <i8 -128, i8 poison>1046  ret <2 x i8> %d1047}1048 1049define <2 x i8> @sdiv_by_negconst_v2i8(<2 x i8> %x) {1050; CHECK-LABEL: @sdiv_by_negconst_v2i8(1051; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv <2 x i8> [[X:%.*]], splat (i8 108)1052; CHECK-NEXT:    ret <2 x i8> [[DIV_NEG]]1053;1054  %div = sdiv <2 x i8> %x, <i8 -108, i8 -108>1055  %sub = sub <2 x i8> zeroinitializer, %div1056  ret <2 x i8> %sub1057}1058 1059define <vscale x 2 x i8> @sdiv_by_negconst_nxv2i8(<vscale x 2 x i8> %x) {1060; CHECK-LABEL: @sdiv_by_negconst_nxv2i8(1061; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv <vscale x 2 x i8> [[X:%.*]], splat (i8 108)1062; CHECK-NEXT:    ret <vscale x 2 x i8> [[DIV_NEG]]1063;1064  %div = sdiv <vscale x 2 x i8> %x, splat (i8 -108)1065  %sub = sub <vscale x 2 x i8> zeroinitializer, %div1066  ret <vscale x 2 x i8> %sub1067}1068 1069define <2 x i8> @sdiv_by_minSigned_v2i8(<2 x i8> %x) {1070; CHECK-LABEL: @sdiv_by_minSigned_v2i8(1071; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128)1072; CHECK-NEXT:    [[DIV_NEG:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>1073; CHECK-NEXT:    ret <2 x i8> [[DIV_NEG]]1074;1075  %div = sdiv <2 x i8> %x, <i8 -128, i8 -128>1076  %sub = sub <2 x i8> zeroinitializer, %div1077  ret <2 x i8> %sub1078}1079 1080define <vscale x 2 x i8> @sdiv_by_minSigned_nxv2i8(<vscale x 2 x i8> %x) {1081; CHECK-LABEL: @sdiv_by_minSigned_nxv2i8(1082; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <vscale x 2 x i8> [[X:%.*]], splat (i8 -128)1083; CHECK-NEXT:    [[DIV_NEG:%.*]] = sext <vscale x 2 x i1> [[TMP1]] to <vscale x 2 x i8>1084; CHECK-NEXT:    ret <vscale x 2 x i8> [[DIV_NEG]]1085;1086  %div = sdiv <vscale x 2 x i8> %x, splat (i8 -128)1087  %sub = sub <vscale x 2 x i8> zeroinitializer, %div1088  ret <vscale x 2 x i8> %sub1089}1090 1091define i32 @sdiv_constant_dividend_select_of_constants_divisor(i1 %b) {1092; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor(1093; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], i32 3, i32 -141094; CHECK-NEXT:    ret i32 [[R]]1095;1096  %s = select i1 %b, i32 12, i32 -31097  %r = sdiv i32 42, %s1098  ret i32 %r1099}1100 1101define i32 @sdiv_constant_dividend_select_of_constants_divisor_use(i1 %b) {1102; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_use(1103; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -31104; CHECK-NEXT:    call void @use(i32 [[S]])1105; CHECK-NEXT:    [[R:%.*]] = select i1 [[B]], i32 3, i32 -141106; CHECK-NEXT:    ret i32 [[R]]1107;1108  %s = select i1 %b, i32 12, i32 -31109  call void @use(i32 %s)1110  %r = sdiv i32 42, %s1111  ret i32 %r1112}1113 1114define i32 @sdiv_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) {1115; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_0_arm(1116; CHECK-NEXT:    ret i32 31117;1118  %s = select i1 %b, i32 12, i32 01119  %r = sdiv i32 42, %s1120  ret i32 %r1121}1122 1123; negative test - not safe to speculate div with variable divisor1124 1125define i32 @sdiv_constant_dividend_select_divisor1(i1 %b, i32 %x) {1126; CHECK-LABEL: @sdiv_constant_dividend_select_divisor1(1127; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -31128; CHECK-NEXT:    [[R:%.*]] = sdiv i32 42, [[S]]1129; CHECK-NEXT:    ret i32 [[R]]1130;1131  %s = select i1 %b, i32 %x, i32 -31132  %r = sdiv i32 42, %s1133  ret i32 %r1134}1135 1136; negative test - not safe to speculate div with variable divisor1137 1138define i32 @sdiv_constant_dividend_select_divisor2(i1 %b, i32 %x) {1139; CHECK-LABEL: @sdiv_constant_dividend_select_divisor2(1140; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]]1141; CHECK-NEXT:    [[R:%.*]] = sdiv i32 42, [[S]]1142; CHECK-NEXT:    ret i32 [[R]]1143;1144  %s = select i1 %b, i32 12, i32 %x1145  %r = sdiv i32 42, %s1146  ret i32 %r1147}1148 1149define <2 x i8> @sdiv_constant_dividend_select_of_constants_divisor_vec(i1 %b) {1150; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_vec(1151; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 8>, <2 x i8> splat (i8 -10)1152; CHECK-NEXT:    ret <2 x i8> [[R]]1153;1154  %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4>1155  %r = sdiv <2 x i8> <i8 42, i8 -42>, %s1156  ret <2 x i8> %r1157}1158 1159; Div-by-0 element is immediate UB, so select is simplified.1160 1161define <2 x i8> @sdiv_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) {1162; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_vec_ub1(1163; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 poison, i8 8>, <2 x i8> splat (i8 -10)1164; CHECK-NEXT:    ret <2 x i8> [[R]]1165;1166  %s = select i1 %b, <2 x i8> <i8 0, i8 -5>, <2 x i8> <i8 -4, i8 4>1167  %r = sdiv <2 x i8> <i8 42, i8 -42>, %s1168  ret <2 x i8> %r1169}1170 1171; SMIN / -1 element is poison.1172 1173define <2 x i8> @sdiv_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) {1174; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_vec_ub2(1175; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 25>, <2 x i8> <i8 -10, i8 poison>1176; CHECK-NEXT:    ret <2 x i8> [[R]]1177;1178  %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1>1179  %r = sdiv <2 x i8> <i8 42, i8 -128>, %s1180  ret <2 x i8> %r1181}1182 1183; negative test - must have constant dividend1184 1185define i32 @sdiv_select_of_constants_divisor(i1 %b, i32 %x) {1186; CHECK-LABEL: @sdiv_select_of_constants_divisor(1187; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -31188; CHECK-NEXT:    [[R:%.*]] = sdiv i32 [[X:%.*]], [[S]]1189; CHECK-NEXT:    ret i32 [[R]]1190;1191  %s = select i1 %b, i32 12, i32 -31192  %r = sdiv i32 %x, %s1193  ret i32 %r1194}1195 1196define i32 @udiv_constant_dividend_select_of_constants_divisor(i1 %b) {1197; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor(1198; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], i32 3, i32 01199; CHECK-NEXT:    ret i32 [[R]]1200;1201  %s = select i1 %b, i32 12, i32 -31202  %r = udiv i32 42, %s1203  ret i32 %r1204}1205 1206define i32 @udiv_constant_dividend_select_of_constants_divisor_use(i1 %b) {1207; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_use(1208; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -31209; CHECK-NEXT:    call void @use(i32 [[S]])1210; CHECK-NEXT:    [[R:%.*]] = select i1 [[B]], i32 3, i32 01211; CHECK-NEXT:    ret i32 [[R]]1212;1213  %s = select i1 %b, i32 12, i32 -31214  call void @use(i32 %s)1215  %r = udiv i32 42, %s1216  ret i32 %r1217}1218 1219; Div-by-0 is immediate UB, so select is simplified.1220 1221define i32 @udiv_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) {1222; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_0_arm(1223; CHECK-NEXT:    ret i32 31224;1225  %s = select i1 %b, i32 12, i32 01226  %r = udiv i32 42, %s1227  ret i32 %r1228}1229 1230; negative test - not safe to speculate div with variable divisor1231 1232define i32 @udiv_constant_dividend_select_divisor1(i1 %b, i32 %x) {1233; CHECK-LABEL: @udiv_constant_dividend_select_divisor1(1234; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -31235; CHECK-NEXT:    [[R:%.*]] = udiv i32 42, [[S]]1236; CHECK-NEXT:    ret i32 [[R]]1237;1238  %s = select i1 %b, i32 %x, i32 -31239  %r = udiv i32 42, %s1240  ret i32 %r1241}1242 1243; negative test - not safe to speculate div with variable divisor1244 1245define i32 @udiv_constant_dividend_select_divisor2(i1 %b, i32 %x) {1246; CHECK-LABEL: @udiv_constant_dividend_select_divisor2(1247; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]]1248; CHECK-NEXT:    [[R:%.*]] = udiv i32 42, [[S]]1249; CHECK-NEXT:    ret i32 [[R]]1250;1251  %s = select i1 %b, i32 12, i32 %x1252  %r = udiv i32 42, %s1253  ret i32 %r1254}1255 1256define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec(i1 %b) {1257; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec(1258; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 0>, <2 x i8> <i8 0, i8 53>1259; CHECK-NEXT:    ret <2 x i8> [[R]]1260;1261  %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4>1262  %r = udiv <2 x i8> <i8 42, i8 -42>, %s1263  ret <2 x i8> %r1264}1265 1266; Div-by-0 element is immediate UB, so select is simplified.1267 1268define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) {1269; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec_ub1(1270; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 poison, i8 0>, <2 x i8> <i8 0, i8 53>1271; CHECK-NEXT:    ret <2 x i8> [[R]]1272;1273  %s = select i1 %b, <2 x i8> <i8 0, i8 -5>, <2 x i8> <i8 -4, i8 4>1274  %r = udiv <2 x i8> <i8 42, i8 -42>, %s1275  ret <2 x i8> %r1276}1277 1278; There's no unsigned equivalent to "SMIN / -1", so this is just the usual constant folding.1279 1280define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) {1281; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec_ub2(1282; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 0>, <2 x i8> zeroinitializer1283; CHECK-NEXT:    ret <2 x i8> [[R]]1284;1285  %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1>1286  %r = udiv <2 x i8> <i8 42, i8 -128>, %s1287  ret <2 x i8> %r1288}1289 1290; negative test - must have constant dividend1291 1292define i32 @udiv_select_of_constants_divisor(i1 %b, i32 %x) {1293; CHECK-LABEL: @udiv_select_of_constants_divisor(1294; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -31295; CHECK-NEXT:    [[R:%.*]] = udiv i32 [[X:%.*]], [[S]]1296; CHECK-NEXT:    ret i32 [[R]]1297;1298  %s = select i1 %b, i32 12, i32 -31299  %r = udiv i32 %x, %s1300  ret i32 %r1301}1302 1303; PR340631304; 1 / X !=/== -11305 1306define i1 @sdiv_one_icmpeq_one(i32 %x) {1307; CHECK-LABEL: @sdiv_one_icmpeq_one(1308; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X:%.*]]1309; CHECK-NEXT:    [[B1:%.*]] = icmp eq i32 [[X_FR]], 11310; CHECK-NEXT:    ret i1 [[B1]]1311;1312  %A = sdiv i32 1, %x1313  %B = icmp eq i32 %A, 11314  ret i1 %B1315}1316 1317define i1 @sdiv_one_icmpeq_negone(i32 %x) {1318; CHECK-LABEL: @sdiv_one_icmpeq_negone(1319; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X:%.*]]1320; CHECK-NEXT:    [[B1:%.*]] = icmp eq i32 [[X_FR]], -11321; CHECK-NEXT:    ret i1 [[B1]]1322;1323  %A = sdiv i32 1, %x1324  %B = icmp eq i32 %A, -11325  ret i1 %B1326}1327 1328define i1 @udiv_one_icmpeq_one(i32 %x) {1329; CHECK-LABEL: @udiv_one_icmpeq_one(1330; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 11331; CHECK-NEXT:    ret i1 [[TMP1]]1332;1333  %A = udiv i32 1, %x1334  %B = icmp eq i32 %A, 11335  ret i1 %B1336}1337 1338define i1 @udiv_one_icmpne_one(i32 %x) {1339; CHECK-LABEL: @udiv_one_icmpne_one(1340; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 11341; CHECK-NEXT:    ret i1 [[TMP1]]1342;1343  %A = udiv i32 1, %x1344  %B = icmp ne i32 %A, 11345  ret i1 %B1346}1347 1348; ((X * Y) / Z) / X --> Y / Z1349 1350define i8 @udiv_udiv_mul_nuw(i8 %x, i8 %y, i8 %z) {1351; CHECK-LABEL: @udiv_udiv_mul_nuw(1352; CHECK-NEXT:    [[R:%.*]] = udiv i8 [[Y:%.*]], [[Z:%.*]]1353; CHECK-NEXT:    ret i8 [[R]]1354;1355  %m = mul nuw i8 %x, %y1356  %d = udiv i8 %m, %z1357  %r = udiv i8 %d, %x1358  ret i8 %r1359}1360 1361; exact propagates and commute is ok1362 1363define i8 @udiv_udiv_mul_nuw_exact_exact(i8 %x, i8 %y, i8 %z) {1364; CHECK-LABEL: @udiv_udiv_mul_nuw_exact_exact(1365; CHECK-NEXT:    [[R:%.*]] = udiv exact i8 [[Y:%.*]], [[Z:%.*]]1366; CHECK-NEXT:    ret i8 [[R]]1367;1368  %m = mul nuw i8 %y, %x1369  %d = udiv exact i8 %m, %z1370  %r = udiv exact i8 %d, %x1371  ret i8 %r1372}1373 1374; extra uses are ok1375 1376define i32 @udiv_udiv_mul_nuw_exact_use(i32 %x, i32 %y, i32 %z) {1377; CHECK-LABEL: @udiv_udiv_mul_nuw_exact_use(1378; CHECK-NEXT:    [[M:%.*]] = mul nuw i32 [[X:%.*]], [[Y:%.*]]1379; CHECK-NEXT:    call void @use(i32 [[M]])1380; CHECK-NEXT:    [[R:%.*]] = udiv i32 [[Y]], [[Z:%.*]]1381; CHECK-NEXT:    ret i32 [[R]]1382;1383  %m = mul nuw i32 %x, %y1384  call void @use(i32 %m)1385  %d = udiv exact i32 %m, %z1386  %r = udiv i32 %d, %x1387  ret i32 %r1388}1389 1390; negative test - must have nuw1391 1392define i8 @udiv_udiv_mul_nsw(i8 %x, i8 %y, i8 %z) {1393; CHECK-LABEL: @udiv_udiv_mul_nsw(1394; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]]1395; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[M]], [[Z:%.*]]1396; CHECK-NEXT:    [[R:%.*]] = udiv i8 [[D]], [[X]]1397; CHECK-NEXT:    ret i8 [[R]]1398;1399  %m = mul nsw i8 %x, %y1400  %d = udiv i8 %m, %z1401  %r = udiv i8 %d, %x1402  ret i8 %r1403}1404 1405; negative test - opcode mismatch1406 1407define i8 @udiv_sdiv_mul_nuw(i8 %x, i8 %y, i8 %z) {1408; CHECK-LABEL: @udiv_sdiv_mul_nuw(1409; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]1410; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[M]], [[Z:%.*]]1411; CHECK-NEXT:    [[R:%.*]] = udiv i8 [[D]], [[X]]1412; CHECK-NEXT:    ret i8 [[R]]1413;1414  %m = mul nuw i8 %x, %y1415  %d = sdiv i8 %m, %z1416  %r = udiv i8 %d, %x1417  ret i8 %r1418}1419 1420; ((Y * X) / Z) / X --> Y / Z1421 1422define <2 x i8> @sdiv_sdiv_mul_nsw(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {1423; CHECK-LABEL: @sdiv_sdiv_mul_nsw(1424; CHECK-NEXT:    [[R:%.*]] = sdiv <2 x i8> [[Y:%.*]], [[Z:%.*]]1425; CHECK-NEXT:    ret <2 x i8> [[R]]1426;1427  %m = mul nsw <2 x i8> %y, %x1428  %d = sdiv <2 x i8> %m, %z1429  %r = sdiv <2 x i8> %d, %x1430  ret <2 x i8> %r1431}1432 1433; (X * C0) / (X * C1) --> C0 / C11434define i8 @sdiv_mul_nsw_mul_nsw(i8 %x,i8 %y,i8 %z) {1435; CHECK-LABEL: @sdiv_mul_nsw_mul_nsw(1436; CHECK-NEXT:    [[ADD4:%.*]] = mul nsw i8 [[X:%.*]], [[Z:%.*]]1437; CHECK-NEXT:    [[ADD5:%.*]] = mul nsw i8 [[X]], [[Y:%.*]]1438; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[ADD5]], [[ADD4]]1439; CHECK-NEXT:    ret i8 [[DIV]]1440;1441  %add4 = mul nsw i8 %x, %z1442  %add5 = mul nsw i8 %x, %y1443  %div = sdiv i8 %add5, %add41444  ret i8 %div1445}1446 1447define i8 @udiv_mul_nuw_mul_nuw(i8 %x,i8 %y,i8 %z) {1448; CHECK-LABEL: @udiv_mul_nuw_mul_nuw(1449; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[Y:%.*]], [[Z:%.*]]1450; CHECK-NEXT:    ret i8 [[DIV]]1451;1452  %add4 = mul nuw i8 %x, %z1453  %add5 = mul nuw i8 %x, %y1454  %div = udiv i8 %add5, %add41455  ret i8 %div1456}1457 1458define i8 @sdiv_mul_nsw_constant_mul_nsw_constant(i8 %x) {1459; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_nsw_constant(1460; CHECK-NEXT:    ret i8 21461;1462  %add4 = mul nsw i8 %x, 51463  %add5 = mul nsw i8 %x, 101464  %div = sdiv i8 %add5, %add41465  ret i8 %div1466}1467 1468define i4 @sdiv_mul_nsw_constant_mul_constant(i4 %a) {1469; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_constant(1470; CHECK-NEXT:    [[ADD4:%.*]] = mul i4 [[A:%.*]], 31471; CHECK-NEXT:    [[ADD5:%.*]] = mul nsw i4 [[A]], 61472; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]]1473; CHECK-NEXT:    ret i4 [[DIV]]1474;1475  %add4 = mul i4 %a, 31476  %add5 = mul nsw i4 %a, 61477  %div = sdiv i4 %add5, %add41478  ret i4 %div1479}1480define i4 @sdiv_mul_nsw_constant_mul_constant2(i4 %a) {1481; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_constant2(1482; CHECK-NEXT:    [[ADD4:%.*]] = sub i4 0, [[A:%.*]]1483; CHECK-NEXT:    [[ADD5:%.*]] = shl i4 [[A]], 31484; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]]1485; CHECK-NEXT:    ret i4 [[DIV]]1486;1487  %add4 = mul i4 %a, 151488  %add5 = mul nsw i4 %a, 81489  %div = sdiv i4 %add5, %add41490  ret i4 %div1491}1492 1493define i4 @sdiv_mul_nsw_constant_mul_constant3(i4 %a) {1494; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_constant3(1495; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i4 [[A:%.*]], -81496; CHECK-NEXT:    [[DIV:%.*]] = select i1 [[TMP1]], i4 1, i4 -11497; CHECK-NEXT:    ret i4 [[DIV]]1498;1499  %add4 = mul i4 %a, 151500  %add5 = mul nsw i4 %a, 11501  %div = sdiv i4 %add5, %add41502  ret i4 %div1503}1504 1505define i4 @sdiv_mul_nsw_mul(i4 %a) {1506; CHECK-LABEL: @sdiv_mul_nsw_mul(1507; CHECK-NEXT:    [[ADD4:%.*]] = sub i4 0, [[A:%.*]]1508; CHECK-NEXT:    [[ADD5:%.*]] = shl i4 [[A]], 31509; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]]1510; CHECK-NEXT:    ret i4 [[DIV]]1511;1512  %add4 = mul i4 %a, -11513  %add5 = mul nsw i4 %a, -81514  %div = sdiv i4 %add5, %add41515  ret i4 %div1516}1517 1518define i4 @udiv_mul_nuw_constant_mul_constant(i4 %a) {1519; CHECK-LABEL: @udiv_mul_nuw_constant_mul_constant(1520; CHECK-NEXT:    ret i4 21521;1522  %add4 = mul i4 %a, 31523  %add5 = mul nuw i4 %a, 61524  %div = udiv i4 %add5, %add41525  ret i4 %div1526}1527 1528define i4 @udiv_mul_nuw_mul_negative(i4 %a) {1529; CHECK-LABEL: @udiv_mul_nuw_mul_negative(1530; CHECK-NEXT:    [[ADD4:%.*]] = mul i4 [[A:%.*]], -31531; CHECK-NEXT:    [[ADD5:%.*]] = shl nuw i4 [[A]], 21532; CHECK-NEXT:    [[DIV:%.*]] = udiv i4 [[ADD5]], [[ADD4]]1533; CHECK-NEXT:    ret i4 [[DIV]]1534;1535  %add4 = mul i4 %a, 131536  %add5 = mul nuw i4 %a, 41537  %div = udiv i4 %add5, %add41538  ret i4 %div1539}1540 1541define i4 @sdiv_mul_nsw_mul_nsw_allones(i4 %a) {1542; CHECK-LABEL: @sdiv_mul_nsw_mul_nsw_allones(1543; CHECK-NEXT:    [[ADD4:%.*]] = sub nsw i4 0, [[A:%.*]]1544; CHECK-NEXT:    [[ADD5:%.*]] = shl i4 [[A]], 31545; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]]1546; CHECK-NEXT:    ret i4 [[DIV]]1547;1548  %add4 = mul nsw i4 %a, -11549  %add5 = mul nsw i4 %a, -81550  %div = sdiv i4 %add5, %add41551  ret i4 %div1552}1553 1554define i4 @sdiv_mul_nsw_mul_signmask(i4 %a, i4 %c2) {1555; CHECK-LABEL: @sdiv_mul_nsw_mul_signmask(1556; CHECK-NEXT:    [[ADD4:%.*]] = shl i4 [[A:%.*]], 31557; CHECK-NEXT:    [[ADD5:%.*]] = mul nsw i4 [[A]], [[C2:%.*]]1558; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]]1559; CHECK-NEXT:    ret i4 [[DIV]]1560;1561  %add4 = mul nsw i4 %a, -81562  %add5 = mul nsw i4 %a, %c21563  %div = sdiv i4 %add5, %add41564  ret i4 %div1565}1566 1567define i32 @sdiv_sub1(i32 %arg) {1568; CHECK-LABEL: @sdiv_sub1(1569; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[ARG:%.*]], -21474836481570; CHECK-NEXT:    [[DIV:%.*]] = select i1 [[TMP1]], i32 1, i32 -11571; CHECK-NEXT:    ret i32 [[DIV]]1572;1573  %neg = sub i32 0, %arg1574  %div = sdiv i32 %neg, %arg1575  ret i32 %div1576}1577 1578define i32 @sdiv_sub2(i32 %arg) {1579; CHECK-LABEL: @sdiv_sub2(1580; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[ARG:%.*]], -21474836481581; CHECK-NEXT:    [[DIV:%.*]] = select i1 [[TMP1]], i32 1, i32 -11582; CHECK-NEXT:    ret i32 [[DIV]]1583;1584  %neg = sub i32 0, %arg1585  %div = sdiv i32 %arg, %neg1586  ret i32 %div1587}1588 1589define i32 @sub_sdiv_multiuse(i32 %arg) {1590; CHECK-LABEL: @sub_sdiv_multiuse(1591; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[ARG:%.*]]1592; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[ARG]], -21474836481593; CHECK-NEXT:    [[DIV:%.*]] = select i1 [[TMP1]], i32 1, i32 -11594; CHECK-NEXT:    call void @use(i32 [[NEG]])1595; CHECK-NEXT:    ret i32 [[DIV]]1596;1597  %neg = sub i32 0, %arg1598  %div = sdiv i32 %arg, %neg1599  call void @use(i32 %neg)1600  ret i32 %div1601}1602 1603define i32 @sdiv_sub_sub(i32 %x ,i32 %y) {1604; CHECK-LABEL: @sdiv_sub_sub(1605; CHECK-NEXT:    [[S:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]1606; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[S]], -21474836481607; CHECK-NEXT:    [[D:%.*]] = select i1 [[TMP1]], i32 1, i32 -11608; CHECK-NEXT:    ret i32 [[D]]1609;1610  %s = sub i32 %x, %y1611  %u = sub i32 %y, %x1612  %d = sdiv i32 %s, %u1613  ret i32 %d1614}1615 1616define i32 @sdiv_mul_sub(i32 %x, i32 %y) {1617; CHECK-LABEL: @sdiv_mul_sub(1618; CHECK-NEXT:    [[M:%.*]] = mul i32 [[Y:%.*]], [[X:%.*]]1619; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[M]], -21474836481620; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 1, i32 -11621; CHECK-NEXT:    ret i32 [[R]]1622;1623  %m = mul i32 %y, %x1624  %d = sub i32 0, %m1625  %r = sdiv i32 %d, %m1626  ret i32 %r1627}1628 1629define i32 @sdiv_mul_sub_nsw(i32 %x, i32 %y) {1630; CHECK-LABEL: @sdiv_mul_sub_nsw(1631; CHECK-NEXT:    ret i32 -11632;1633  %m = mul i32 %y, %x1634  %n = sub nsw i32 0, %m1635  %d = sdiv i32 %m, %n1636  ret i32 %d1637}1638 1639define i32 @sdiv_mul_nsw_sub_nsw(i32 %x, i32 %y) {1640; CHECK-LABEL: @sdiv_mul_nsw_sub_nsw(1641; CHECK-NEXT:    ret i32 -11642;1643  %m = mul nsw i32 %y, %x1644  %n = sub nsw i32 0, %m1645  %d = sdiv i32 %m, %n1646  ret i32 %d1647}1648 1649; exact propagates1650 1651define i8 @sdiv_sdiv_mul_nsw_exact_exact(i8 %x, i8 %y, i8 %z) {1652; CHECK-LABEL: @sdiv_sdiv_mul_nsw_exact_exact(1653; CHECK-NEXT:    [[R:%.*]] = sdiv exact i8 [[Y:%.*]], [[Z:%.*]]1654; CHECK-NEXT:    ret i8 [[R]]1655;1656  %m = mul nsw i8 %x, %y1657  %d = sdiv exact i8 %m, %z1658  %r = sdiv exact i8 %d, %x1659  ret i8 %r1660}1661 1662; extra uses are ok1663 1664define i32 @sdiv_sdiv_mul_nsw_exact_use(i32 %x, i32 %y, i32 %z) {1665; CHECK-LABEL: @sdiv_sdiv_mul_nsw_exact_use(1666; CHECK-NEXT:    [[M:%.*]] = mul nsw i32 [[X:%.*]], [[Y:%.*]]1667; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[M]], [[Z:%.*]]1668; CHECK-NEXT:    call void @use(i32 [[D]])1669; CHECK-NEXT:    [[R:%.*]] = sdiv i32 [[Y]], [[Z]]1670; CHECK-NEXT:    ret i32 [[R]]1671;1672  %m = mul nsw i32 %x, %y1673  %d = sdiv i32 %m, %z1674  call void @use(i32 %d)1675  %r = sdiv exact i32 %d, %x1676  ret i32 %r1677}1678 1679; negative test - must have nsw1680 1681define i8 @sdiv_sdiv_mul_nuw(i8 %x, i8 %y, i8 %z) {1682; CHECK-LABEL: @sdiv_sdiv_mul_nuw(1683; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]1684; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[M]], [[Z:%.*]]1685; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[D]], [[X]]1686; CHECK-NEXT:    ret i8 [[R]]1687;1688  %m = mul nuw i8 %x, %y1689  %d = sdiv i8 %m, %z1690  %r = sdiv i8 %d, %x1691  ret i8 %r1692}1693 1694; negative test - opcode mismatch1695 1696define i8 @sdiv_udiv_mul_nsw(i8 %x, i8 %y, i8 %z) {1697; CHECK-LABEL: @sdiv_udiv_mul_nsw(1698; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]]1699; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[M]], [[Z:%.*]]1700; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[D]], [[X]]1701; CHECK-NEXT:    ret i8 [[R]]1702;1703  %m = mul nsw i8 %x, %y1704  %d = udiv i8 %m, %z1705  %r = sdiv i8 %d, %x1706  ret i8 %r1707}1708 1709; ((X * C2) + C1) / C2 --> X + C1/C21710 1711define i6 @sdiv_distribute_mul_nsw_add_nsw(i6 %x) {1712; CHECK-LABEL: @sdiv_distribute_mul_nsw_add_nsw(1713; CHECK-NEXT:    [[DIV:%.*]] = add nsw i6 [[X:%.*]], -51714; CHECK-NEXT:    ret i6 [[DIV]]1715;1716  %mul = mul nsw i6 %x, 31717  %add = add nsw i6 %mul, -151718  %div = sdiv i6 %add, 31719  ret i6 %div1720}1721 1722; extra uses are ok1723 1724define i32 @sdiv_distribute_mul_nsw_add_nsw_uses(i32 %x) {1725; CHECK-LABEL: @sdiv_distribute_mul_nsw_add_nsw_uses(1726; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 421727; CHECK-NEXT:    call void @use(i32 [[MUL]])1728; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[MUL]], 1261729; CHECK-NEXT:    call void @use(i32 [[ADD]])1730; CHECK-NEXT:    [[DIV:%.*]] = add nsw i32 [[X]], 31731; CHECK-NEXT:    ret i32 [[DIV]]1732;1733  %mul = mul nsw i32 %x, 421734  call void @use(i32 %mul)1735  %add = add nsw i32 %mul, 1261736  call void @use(i32 %add)1737  %div = sdiv i32 %add, 421738  ret i32 %div1739}1740 1741; vector splats work1742 1743define <2 x i6> @udiv_distribute_mul_nuw_add_nuw(<2 x i6> %x) {1744; CHECK-LABEL: @udiv_distribute_mul_nuw_add_nuw(1745; CHECK-NEXT:    [[DIV:%.*]] = add nuw <2 x i6> [[X:%.*]], splat (i6 5)1746; CHECK-NEXT:    ret <2 x i6> [[DIV]]1747;1748  %mul = mul nuw <2 x i6> %x, <i6 3, i6 3>1749  %add = add nuw <2 x i6> %mul, <i6 15, i6 15>1750  %div = udiv <2 x i6> %add, <i6 3, i6 3>1751  ret <2 x i6> %div1752}1753 1754; negative test - constants must be evenly divisible1755 1756define i6 @sdiv_distribute_mul_nsw_add_nsw_not_multiple_offset(i6 %x) {1757; CHECK-LABEL: @sdiv_distribute_mul_nsw_add_nsw_not_multiple_offset(1758; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i6 [[X:%.*]], 31759; CHECK-NEXT:    [[ADD:%.*]] = add nsw i6 [[MUL]], -161760; CHECK-NEXT:    [[DIV:%.*]] = sdiv i6 [[ADD]], 31761; CHECK-NEXT:    ret i6 [[DIV]]1762;1763  %mul = mul nsw i6 %x, 31764  %add = add nsw i6 %mul, -161765  %div = sdiv i6 %add, 31766  ret i6 %div1767}1768 1769; constants do not have to be evenly divisible with unsigned division1770 1771define i6 @udiv_distribute_mul_nuw_add_nuw_not_multiple_offset(i6 %x) {1772; CHECK-LABEL: @udiv_distribute_mul_nuw_add_nuw_not_multiple_offset(1773; CHECK-NEXT:    [[DIV:%.*]] = add nuw i6 [[X:%.*]], 21774; CHECK-NEXT:    ret i6 [[DIV]]1775;1776  %mul = mul nuw i6 %x, 31777  %add = add nuw i6 %mul, 71778  %div = udiv i6 %add, 31779  ret i6 %div1780}1781 1782; negative test - wrong no-wrap1783 1784define i6 @sdiv_distribute_mul_nuw_add_nsw(i6 %x) {1785; CHECK-LABEL: @sdiv_distribute_mul_nuw_add_nsw(1786; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i6 [[X:%.*]], 31787; CHECK-NEXT:    [[ADD:%.*]] = add nsw i6 [[MUL]], -151788; CHECK-NEXT:    [[DIV:%.*]] = sdiv i6 [[ADD]], 31789; CHECK-NEXT:    ret i6 [[DIV]]1790;1791  %mul = mul nuw i6 %x, 31792  %add = add nsw i6 %mul, -151793  %div = sdiv i6 %add, 31794  ret i6 %div1795}1796 1797; negative test - wrong no-wrap1798 1799define i6 @udiv_distribute_mul_nsw_add_nuw(i6 %x) {1800; CHECK-LABEL: @udiv_distribute_mul_nsw_add_nuw(1801; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i6 [[X:%.*]], 31802; CHECK-NEXT:    [[ADD:%.*]] = add nuw i6 [[MUL]], 91803; CHECK-NEXT:    [[DIV:%.*]] = udiv i6 [[ADD]], 31804; CHECK-NEXT:    ret i6 [[DIV]]1805;1806  %mul = mul nsw i6 %x, 31807  %add = add nuw i6 %mul, 91808  %div = udiv i6 %add, 31809  ret i6 %div1810}1811 1812define i32 @fold_disjoint_or_over_sdiv(i32 %x) {1813; CHECK-LABEL: @fold_disjoint_or_over_sdiv(1814; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[X:%.*]], 91815; CHECK-NEXT:    ret i32 [[R]]1816;1817  %mul = mul nsw i32 %x, 91818  %or = or disjoint i32 %mul, 811819  %r = sdiv i32 %or, 91820  ret i32 %r1821}1822 1823define i32 @fold_disjoint_or_over_udiv(i32 %x) {1824; CHECK-LABEL: @fold_disjoint_or_over_udiv(1825; CHECK-NEXT:    [[R:%.*]] = add nuw i32 [[X:%.*]], 91826; CHECK-NEXT:    ret i32 [[R]]1827;1828  %mul = mul nuw i32 %x, 91829  %or = or disjoint i32 %mul, 811830  %r = udiv i32 %or, 91831  ret i32 %r1832}1833 1834define i8 @udiv_trunc_shl(i32 %x) {1835; CHECK-LABEL: @udiv_trunc_shl(1836; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i81837; CHECK-NEXT:    [[UDIV1:%.*]] = lshr i8 8, [[TMP1]]1838; CHECK-NEXT:    ret i8 [[UDIV1]]1839;1840  %lshr = shl i32 1, %x1841  %trunc = trunc i32 %lshr to i81842  %div = udiv i8 8, %trunc1843  ret i8 %div1844}1845 1846define i32 @zext_udiv_trunc_lshr(i32 %x) {1847; CHECK-LABEL: @zext_udiv_trunc_lshr(1848; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i81849; CHECK-NEXT:    [[TMP2:%.*]] = sub i8 5, [[TMP1]]1850; CHECK-NEXT:    [[UDIV1:%.*]] = lshr i8 8, [[TMP2]]1851; CHECK-NEXT:    [[ZEXT:%.*]] = zext nneg i8 [[UDIV1]] to i321852; CHECK-NEXT:    ret i32 [[ZEXT]]1853;1854  %lshr = lshr i32 32, %x1855  %trunc = trunc i32 %lshr to i81856  %div = udiv i8 8, %trunc1857  %zext = zext i8 %div to i321858  ret i32 %zext1859}1860 1861define i32 @udiv_and_shl(i32 %a, i32 %b, i32 %c) {1862; CHECK-LABEL: @udiv_and_shl(1863; CHECK-NEXT:    [[DIV1:%.*]] = lshr i32 [[C:%.*]], [[A:%.*]]1864; CHECK-NEXT:    ret i32 [[DIV1]]1865;1866  %shl = shl i32 1, %a1867  %and = and i32 %b, %shl1868  %div = udiv i32 %c, %and1869  ret i32 %div1870}1871