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