2325 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(i64)6declare void @use_i32(i32)7 8declare i32 @llvm.cttz.i32(i32, i1 immarg)9declare <2 x i8> @llvm.cttz.v2i8(<2 x i8>, i1 immarg)10 11define <4 x i32> @lshr_non_splat_vector(<4 x i32> %A) {12; CHECK-LABEL: @lshr_non_splat_vector(13; CHECK-NEXT: [[B:%.*]] = lshr <4 x i32> [[A:%.*]], <i32 32, i32 1, i32 2, i32 3>14; CHECK-NEXT: ret <4 x i32> [[B]]15;16 %B = lshr <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3>17 ret <4 x i32> %B18}19 20define <4 x i32> @shl_non_splat_vector(<4 x i32> %A) {21; CHECK-LABEL: @shl_non_splat_vector(22; CHECK-NEXT: [[B:%.*]] = shl <4 x i32> [[A:%.*]], <i32 32, i32 1, i32 2, i32 3>23; CHECK-NEXT: ret <4 x i32> [[B]]24;25 %B = shl <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3>26 ret <4 x i32> %B27}28 29define i32 @test6(i32 %A) {30; CHECK-LABEL: @test6(31; CHECK-NEXT: [[C:%.*]] = mul i32 [[A:%.*]], 632; CHECK-NEXT: ret i32 [[C]]33;34 %B = shl i32 %A, 1 ;; convert to an mul instruction35 %C = mul i32 %B, 336 ret i32 %C37}38 39define i32 @test6a(i32 %A) {40; CHECK-LABEL: @test6a(41; CHECK-NEXT: [[C:%.*]] = mul i32 [[A:%.*]], 642; CHECK-NEXT: ret i32 [[C]]43;44 %B = mul i32 %A, 345 %C = shl i32 %B, 1 ;; convert to an mul instruction46 ret i32 %C47}48 49;; (A << 5) << 3 === A << 8 == 050define i8 @test8(i8 %A) {51; CHECK-LABEL: @test8(52; CHECK-NEXT: ret i8 053;54 %B = shl i8 %A, 555 %C = shl i8 %B, 356 ret i8 %C57}58 59;; (A << 7) >> 7 === A & 160define i8 @test9(i8 %A) {61; CHECK-LABEL: @test9(62; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 163; CHECK-NEXT: ret i8 [[B]]64;65 %B = shl i8 %A, 766 %C = lshr i8 %B, 767 ret i8 %C68}69 70;; (A >> 7) << 7 === A & 12871 72define i8 @test10(i8 %A) {73; CHECK-LABEL: @test10(74; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], -12875; CHECK-NEXT: ret i8 [[B]]76;77 %B = lshr i8 %A, 778 %C = shl i8 %B, 779 ret i8 %C80}81 82;; Allow the simplification when the lshr shift is exact.83define i8 @test10a(i8 %A) {84; CHECK-LABEL: @test10a(85; CHECK-NEXT: ret i8 [[A:%.*]]86;87 %B = lshr exact i8 %A, 788 %C = shl i8 %B, 789 ret i8 %C90}91 92;; (A >> 3) << 4 === (A & 0x1F) << 193define i8 @test11(i8 %x) {94; CHECK-LABEL: @test11(95; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], 696; CHECK-NEXT: [[C:%.*]] = and i8 [[TMP1]], -1697; CHECK-NEXT: ret i8 [[C]]98;99 %a = mul i8 %x, 3100 %B = lshr i8 %a, 3101 %C = shl i8 %B, 4102 ret i8 %C103}104 105;; Allow the simplification in InstCombine when the lshr shift is exact.106define i8 @test11a(i8 %A) {107; CHECK-LABEL: @test11a(108; CHECK-NEXT: [[C:%.*]] = mul i8 [[A:%.*]], 6109; CHECK-NEXT: ret i8 [[C]]110;111 %a = mul i8 %A, 3112 %B = lshr exact i8 %a, 3113 %C = shl i8 %B, 4114 ret i8 %C115}116 117;; (A >> 8) << 8 === A & -256118define i32 @test12(i32 %A) {119; CHECK-LABEL: @test12(120; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], -256121; CHECK-NEXT: ret i32 [[B]]122;123 %B = ashr i32 %A, 8124 %C = shl i32 %B, 8125 ret i32 %C126}127 128;; ((A >>s 6) << 6 === (A & FFFFFFC0)129define i8 @shishi(i8 %x) {130; CHECK-LABEL: @shishi(131; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 6132; CHECK-NEXT: [[B:%.*]] = and i8 [[X]], -64133; CHECK-NEXT: [[EXTRA_USE_OF_A:%.*]] = mul nsw i8 [[A]], 5134; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[EXTRA_USE_OF_A]], [[B]]135; CHECK-NEXT: ret i8 [[R]]136;137 %a = ashr i8 %x, 6138 %b = shl i8 %a, 6139 %extra_use_of_a = mul i8 %a, 5140 %r = sdiv i8 %extra_use_of_a, %b141 ret i8 %r142}143 144;; (A >> 3) << 4 === (A & -8) * 2145define i8 @test13(i8 %x) {146; CHECK-LABEL: @test13(147; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], 6148; CHECK-NEXT: [[C:%.*]] = and i8 [[TMP1]], -16149; CHECK-NEXT: ret i8 [[C]]150;151 %a = mul i8 %x, 3152 %B = ashr i8 %a, 3153 %C = shl i8 %B, 4154 ret i8 %C155}156 157define i8 @test13a(i8 %A) {158; CHECK-LABEL: @test13a(159; CHECK-NEXT: [[C:%.*]] = mul i8 [[A:%.*]], 6160; CHECK-NEXT: ret i8 [[C]]161;162 %a = mul i8 %A, 3163 %B = ashr exact i8 %a, 3164 %C = shl i8 %B, 4165 ret i8 %C166}167 168;; D = ((B | 1234) << 4) === ((B << 4)|(1234 << 4)169define i32 @test14(i32 %A) {170; CHECK-LABEL: @test14(171; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], -19760172; CHECK-NEXT: [[C:%.*]] = or disjoint i32 [[B]], 19744173; CHECK-NEXT: ret i32 [[C]]174;175 %B = lshr i32 %A, 4176 %C = or i32 %B, 1234177 %D = shl i32 %C, 4178 ret i32 %D179}180 181;; D = ((B | 1234) << 4) === ((B << 4)|(1234 << 4)182define i32 @test14a(i32 %A) {183; CHECK-LABEL: @test14a(184; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], 77185; CHECK-NEXT: ret i32 [[C]]186;187 %B = shl i32 %A, 4188 %C = and i32 %B, 1234189 %D = lshr i32 %C, 4190 ret i32 %D191}192 193define i32 @test15(i1 %C) {194; CHECK-LABEL: @test15(195; CHECK-NEXT: [[A:%.*]] = select i1 [[C:%.*]], i32 12, i32 4196; CHECK-NEXT: ret i32 [[A]]197;198 %A = select i1 %C, i32 3, i32 1199 %V = shl i32 %A, 2200 ret i32 %V201}202 203define i32 @test15a(i1 %C) {204; CHECK-LABEL: @test15a(205; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 512, i32 128206; CHECK-NEXT: ret i32 [[V]]207;208 %A = select i1 %C, i8 3, i8 1209 %shift.upgrd.4 = zext i8 %A to i32210 %V = shl i32 64, %shift.upgrd.4211 ret i32 %V212}213 214define i1 @test16(i32 %X) {215; CHECK-LABEL: @test16(216; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 16217; CHECK-NEXT: [[I_7:%.*]] = icmp ne i32 [[TMP1]], 0218; CHECK-NEXT: ret i1 [[I_7]]219;220 %i.3 = ashr i32 %X, 4221 %i.6 = and i32 %i.3, 1222 %i.7 = icmp ne i32 %i.6, 0223 ret i1 %i.7224}225 226define i1 @test17(i32 %A) {227; CHECK-LABEL: @test17(228; CHECK-NEXT: [[B_MASK:%.*]] = and i32 [[A:%.*]], -8229; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[B_MASK]], 9872230; CHECK-NEXT: ret i1 [[C]]231;232 %B = lshr i32 %A, 3233 %C = icmp eq i32 %B, 1234234 ret i1 %C235}236 237define <2 x i1> @test17vec(<2 x i32> %A) {238; CHECK-LABEL: @test17vec(239; CHECK-NEXT: [[B_MASK:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -8)240; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[B_MASK]], splat (i32 9872)241; CHECK-NEXT: ret <2 x i1> [[C]]242;243 %B = lshr <2 x i32> %A, <i32 3, i32 3>244 %C = icmp eq <2 x i32> %B, <i32 1234, i32 1234>245 ret <2 x i1> %C246}247 248define i1 @test18(i8 %A) {249; CHECK-LABEL: @test18(250; CHECK-NEXT: ret i1 false251;252 %B = lshr i8 %A, 7253 ;; false254 %C = icmp eq i8 %B, 123255 ret i1 %C256}257 258define i1 @test19(i32 %A) {259; CHECK-LABEL: @test19(260; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A:%.*]], 4261; CHECK-NEXT: ret i1 [[C]]262;263 %B = ashr i32 %A, 2264 ;; (X & -4) == 0265 %C = icmp eq i32 %B, 0266 ret i1 %C267}268 269define <2 x i1> @test19vec(<2 x i32> %A) {270; CHECK-LABEL: @test19vec(271; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 4)272; CHECK-NEXT: ret <2 x i1> [[C]]273;274 %B = ashr <2 x i32> %A, <i32 2, i32 2>275 %C = icmp eq <2 x i32> %B, zeroinitializer276 ret <2 x i1> %C277}278 279;; X >u ~4280define i1 @test19a(i32 %A) {281; CHECK-LABEL: @test19a(282; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[A:%.*]], -5283; CHECK-NEXT: ret i1 [[C]]284;285 %B = ashr i32 %A, 2286 %C = icmp eq i32 %B, -1287 ret i1 %C288}289 290define <2 x i1> @test19a_vec(<2 x i32> %A) {291; CHECK-LABEL: @test19a_vec(292; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 -5)293; CHECK-NEXT: ret <2 x i1> [[C]]294;295 %B = ashr <2 x i32> %A, <i32 2, i32 2>296 %C = icmp eq <2 x i32> %B, <i32 -1, i32 -1>297 ret <2 x i1> %C298}299 300define i1 @test20(i8 %A) {301; CHECK-LABEL: @test20(302; CHECK-NEXT: ret i1 false303;304 %B = ashr i8 %A, 7305 ;; false306 %C = icmp eq i8 %B, 123307 ret i1 %C308}309 310define i1 @test21(i8 %A) {311; CHECK-LABEL: @test21(312; CHECK-NEXT: [[B_MASK:%.*]] = and i8 [[A:%.*]], 15313; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B_MASK]], 8314; CHECK-NEXT: ret i1 [[C]]315;316 %B = shl i8 %A, 4317 %C = icmp eq i8 %B, -128318 ret i1 %C319}320 321define i1 @test22(i8 %A) {322; CHECK-LABEL: @test22(323; CHECK-NEXT: [[B_MASK:%.*]] = and i8 [[A:%.*]], 15324; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B_MASK]], 0325; CHECK-NEXT: ret i1 [[C]]326;327 %B = shl i8 %A, 4328 %C = icmp eq i8 %B, 0329 ret i1 %C330}331 332define i8 @test23(i32 %A) {333; CHECK-LABEL: @test23(334; CHECK-NEXT: [[D:%.*]] = trunc i32 [[A:%.*]] to i8335; CHECK-NEXT: ret i8 [[D]]336;337 ;; casts not needed338 %B = shl i32 %A, 24339 %C = ashr i32 %B, 24340 %D = trunc i32 %C to i8341 ret i8 %D342}343 344define i8 @test24(i8 %X) {345; CHECK-LABEL: @test24(346; CHECK-NEXT: [[Z:%.*]] = and i8 [[X:%.*]], 3347; CHECK-NEXT: ret i8 [[Z]]348;349 %Y = and i8 %X, -5350 %Z = shl i8 %Y, 5351 %Q = ashr i8 %Z, 5352 ret i8 %Q353}354 355;; handle casts between shifts.356define i32 @test26(i32 %A) {357; CHECK-LABEL: @test26(358; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], -2359; CHECK-NEXT: ret i32 [[B]]360;361 %B = lshr i32 %A, 1362 %C = bitcast i32 %B to i32363 %D = shl i32 %C, 1364 ret i32 %D365}366 367define i1 @test27(i32 %x) {368; CHECK-LABEL: @test27(369; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 8370; CHECK-NEXT: [[Z:%.*]] = icmp ne i32 [[TMP1]], 0371; CHECK-NEXT: ret i1 [[Z]]372;373 %y = lshr i32 %x, 3374 %z = trunc i32 %y to i1375 ret i1 %z376}377 378define i1 @test28(i8 %x) {379; CHECK-LABEL: @test28(380; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0381; CHECK-NEXT: ret i1 [[CMP]]382;383 %shr = lshr i8 %x, 7384 %cmp = icmp ne i8 %shr, 0385 ret i1 %cmp386}387 388define <2 x i1> @test28vec(<2 x i8> %x) {389; CHECK-LABEL: @test28vec(390; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer391; CHECK-NEXT: ret <2 x i1> [[CMP]]392;393 %shr = lshr <2 x i8> %x, <i8 7, i8 7>394 %cmp = icmp ne <2 x i8> %shr, zeroinitializer395 ret <2 x i1> %cmp396}397 398define i8 @test28a(i8 %x, i8 %y) {399; CHECK-LABEL: @test28a(400; CHECK-NEXT: entry:401; CHECK-NEXT: [[COND1_NOT:%.*]] = icmp sgt i8 [[X:%.*]], -1402; CHECK-NEXT: br i1 [[COND1_NOT]], label [[BB2:%.*]], label [[BB1:%.*]]403; CHECK: bb1:404; CHECK-NEXT: ret i8 1405; CHECK: bb2:406; CHECK-NEXT: ret i8 [[Y:%.*]]407;408entry:409; This shouldn't be transformed.410 %i1 = lshr i8 %x, 7411 %cond1 = icmp ne i8 %i1, 0412 br i1 %cond1, label %bb1, label %bb2413bb1:414 ret i8 %i1415bb2:416 %i2 = add i8 %i1, %y417 ret i8 %i2418}419 420define i32 @test29(i64 %d18) {421; CHECK-LABEL: @test29(422; CHECK-NEXT: entry:423; CHECK-NEXT: [[SUM_SHIFT:%.*]] = lshr i64 [[D18:%.*]], 63424; CHECK-NEXT: [[I101:%.*]] = trunc nuw nsw i64 [[SUM_SHIFT]] to i32425; CHECK-NEXT: ret i32 [[I101]]426;427entry:428 %i916 = lshr i64 %d18, 32429 %i917 = trunc i64 %i916 to i32430 %i10 = lshr i32 %i917, 31431 ret i32 %i10432}433 434define <2 x i32> @test29_uniform(<2 x i64> %d18) {435; CHECK-LABEL: @test29_uniform(436; CHECK-NEXT: entry:437; CHECK-NEXT: [[SUM_SHIFT:%.*]] = lshr <2 x i64> [[D18:%.*]], splat (i64 63)438; CHECK-NEXT: [[I101:%.*]] = trunc nuw nsw <2 x i64> [[SUM_SHIFT]] to <2 x i32>439; CHECK-NEXT: ret <2 x i32> [[I101]]440;441entry:442 %i916 = lshr <2 x i64> %d18, <i64 32, i64 32>443 %i917 = trunc <2 x i64> %i916 to <2 x i32>444 %i10 = lshr <2 x i32> %i917, <i32 31, i32 31>445 ret <2 x i32> %i10446}447 448define <2 x i32> @test29_nonuniform(<2 x i64> %d18) {449; CHECK-LABEL: @test29_nonuniform(450; CHECK-NEXT: entry:451; CHECK-NEXT: [[I916:%.*]] = lshr <2 x i64> [[D18:%.*]], <i64 32, i64 15>452; CHECK-NEXT: [[I917:%.*]] = trunc <2 x i64> [[I916]] to <2 x i32>453; CHECK-NEXT: [[I10:%.*]] = lshr <2 x i32> [[I917]], <i32 31, i32 22>454; CHECK-NEXT: ret <2 x i32> [[I10]]455;456entry:457 %i916 = lshr <2 x i64> %d18, <i64 32, i64 15>458 %i917 = trunc <2 x i64> %i916 to <2 x i32>459 %i10 = lshr <2 x i32> %i917, <i32 31, i32 22>460 ret <2 x i32> %i10461}462 463define <2 x i32> @test29_poison(<2 x i64> %d18) {464; CHECK-LABEL: @test29_poison(465; CHECK-NEXT: entry:466; CHECK-NEXT: [[I916:%.*]] = lshr <2 x i64> [[D18:%.*]], <i64 32, i64 poison>467; CHECK-NEXT: [[I917:%.*]] = trunc nuw <2 x i64> [[I916]] to <2 x i32>468; CHECK-NEXT: [[I10:%.*]] = lshr <2 x i32> [[I917]], <i32 31, i32 poison>469; CHECK-NEXT: ret <2 x i32> [[I10]]470;471entry:472 %i916 = lshr <2 x i64> %d18, <i64 32, i64 poison>473 %i917 = trunc <2 x i64> %i916 to <2 x i32>474 %i10 = lshr <2 x i32> %i917, <i32 31, i32 poison>475 ret <2 x i32> %i10476}477 478define i32 @test30(i32 %A, i32 %B, i32 %C) {479; CHECK-LABEL: @test30(480; CHECK-NEXT: [[X1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]481; CHECK-NEXT: [[Z:%.*]] = shl i32 [[X1]], [[C:%.*]]482; CHECK-NEXT: ret i32 [[Z]]483;484 %X = shl i32 %A, %C485 %Y = shl i32 %B, %C486 %Z = and i32 %X, %Y487 ret i32 %Z488}489 490define i32 @test31(i32 %A, i32 %B, i32 %C) {491; CHECK-LABEL: @test31(492; CHECK-NEXT: [[X1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]493; CHECK-NEXT: [[Z:%.*]] = lshr i32 [[X1]], [[C:%.*]]494; CHECK-NEXT: ret i32 [[Z]]495;496 %X = lshr i32 %A, %C497 %Y = lshr i32 %B, %C498 %Z = or i32 %X, %Y499 ret i32 %Z500}501 502define i32 @test32(i32 %A, i32 %B, i32 %C) {503; CHECK-LABEL: @test32(504; CHECK-NEXT: [[X1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]505; CHECK-NEXT: [[Z:%.*]] = ashr i32 [[X1]], [[C:%.*]]506; CHECK-NEXT: ret i32 [[Z]]507;508 %X = ashr i32 %A, %C509 %Y = ashr i32 %B, %C510 %Z = xor i32 %X, %Y511 ret i32 %Z512}513 514define i1 @test33(i32 %X) {515; CHECK-LABEL: @test33(516; CHECK-NEXT: [[I1_MASK:%.*]] = and i32 [[X:%.*]], 16777216517; CHECK-NEXT: [[I2:%.*]] = icmp ne i32 [[I1_MASK]], 0518; CHECK-NEXT: ret i1 [[I2]]519;520 %i1 = shl i32 %X, 7521 %i2 = icmp slt i32 %i1, 0522 ret i1 %i2523}524 525define <2 x i1> @test33vec(<2 x i32> %X) {526; CHECK-LABEL: @test33vec(527; CHECK-NEXT: [[I1_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 16777216)528; CHECK-NEXT: [[I2:%.*]] = icmp ne <2 x i32> [[I1_MASK]], zeroinitializer529; CHECK-NEXT: ret <2 x i1> [[I2]]530;531 %i1 = shl <2 x i32> %X, <i32 7, i32 7>532 %i2 = icmp slt <2 x i32> %i1, zeroinitializer533 ret <2 x i1> %i2534}535 536define i1 @test34(i32 %X) {537; CHECK-LABEL: @test34(538; CHECK-NEXT: ret i1 false539;540 %i1 = lshr i32 %X, 7541 %i2 = icmp slt i32 %i1, 0542 ret i1 %i2543}544 545define i1 @test35(i32 %X) {546; CHECK-LABEL: @test35(547; CHECK-NEXT: [[I2:%.*]] = icmp slt i32 [[X:%.*]], 0548; CHECK-NEXT: ret i1 [[I2]]549;550 %i1 = ashr i32 %X, 7551 %i2 = icmp slt i32 %i1, 0552 ret i1 %i2553}554 555define <2 x i1> @test35vec(<2 x i32> %X) {556; CHECK-LABEL: @test35vec(557; CHECK-NEXT: [[I2:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer558; CHECK-NEXT: ret <2 x i1> [[I2]]559;560 %i1 = ashr <2 x i32> %X, <i32 7, i32 7>561 %i2 = icmp slt <2 x i32> %i1, zeroinitializer562 ret <2 x i1> %i2563}564 565define i128 @test36(i128 %A, i128 %B) {566; CHECK-LABEL: @test36(567; CHECK-NEXT: [[I231:%.*]] = or i128 [[B:%.*]], [[A:%.*]]568; CHECK-NEXT: [[INS:%.*]] = and i128 [[I231]], 18446744073709551615569; CHECK-NEXT: ret i128 [[INS]]570;571 %i27 = shl i128 %A, 64572 %i23 = shl i128 %B, 64573 %ins = or i128 %i23, %i27574 %i45 = lshr i128 %ins, 64575 ret i128 %i45576}577 578define i64 @test37(i128 %A, i32 %B) {579; CHECK-LABEL: @test37(580; CHECK-NEXT: [[I22:%.*]] = zext i32 [[B:%.*]] to i128581; CHECK-NEXT: [[I23:%.*]] = shl nuw nsw i128 [[I22]], 32582; CHECK-NEXT: [[INS:%.*]] = or i128 [[I23]], [[A:%.*]]583; CHECK-NEXT: [[I46:%.*]] = trunc i128 [[INS]] to i64584; CHECK-NEXT: ret i64 [[I46]]585;586 %i27 = shl i128 %A, 64587 %i22 = zext i32 %B to i128588 %i23 = shl i128 %i22, 96589 %ins = or i128 %i23, %i27590 %i45 = lshr i128 %ins, 64591 %i46 = trunc i128 %i45 to i64592 ret i64 %i46593}594 595define <2 x i32> @shl_nuw_nsw_splat_vec(<2 x i8> %x) {596; CHECK-LABEL: @shl_nuw_nsw_splat_vec(597; CHECK-NEXT: [[T2:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>598; CHECK-NEXT: [[T3:%.*]] = shl nuw nsw <2 x i32> [[T2]], splat (i32 17)599; CHECK-NEXT: ret <2 x i32> [[T3]]600;601 %t2 = zext <2 x i8> %x to <2 x i32>602 %t3 = shl <2 x i32> %t2, <i32 17, i32 17>603 ret <2 x i32> %t3604}605 606define i32 @test38(i32 %x) {607; CHECK-LABEL: @test38(608; CHECK-NEXT: [[REM1:%.*]] = and i32 [[X:%.*]], 31609; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[REM1]]610; CHECK-NEXT: ret i32 [[SHL]]611;612 %rem = srem i32 %x, 32613 %shl = shl i32 1, %rem614 ret i32 %shl615}616 617define <2 x i32> @test38_uniform(<2 x i32> %x) {618; CHECK-LABEL: @test38_uniform(619; CHECK-NEXT: [[REM1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 31)620; CHECK-NEXT: [[SHL:%.*]] = shl nuw <2 x i32> splat (i32 1), [[REM1]]621; CHECK-NEXT: ret <2 x i32> [[SHL]]622;623 %rem = srem <2 x i32> %x, <i32 32, i32 32>624 %shl = shl <2 x i32> <i32 1, i32 1>, %rem625 ret <2 x i32> %shl626}627 628define <3 x i32> @test38_nonuniform(<3 x i32> %x) {629; CHECK-LABEL: @test38_nonuniform(630; CHECK-NEXT: [[REM1:%.*]] = and <3 x i32> [[X:%.*]], <i32 31, i32 15, i32 0>631; CHECK-NEXT: [[SHL:%.*]] = shl nuw <3 x i32> splat (i32 1), [[REM1]]632; CHECK-NEXT: ret <3 x i32> [[SHL]]633;634 %rem = srem <3 x i32> %x, <i32 32, i32 16, i32 1>635 %shl = shl <3 x i32> <i32 1, i32 1, i32 1>, %rem636 ret <3 x i32> %shl637}638 639define <2 x i32> @test38_poison(<2 x i32> %x) {640; CHECK-LABEL: @test38_poison(641; CHECK-NEXT: ret <2 x i32> poison642;643 %rem = srem <2 x i32> %x, <i32 32, i32 poison>644 %shl = shl <2 x i32> <i32 1, i32 1>, %rem645 ret <2 x i32> %shl646}647 648; <rdar://problem/8756731>649define i8 @test39(i32 %a0) {650; CHECK-LABEL: @test39(651; CHECK-NEXT: entry:652; CHECK-NEXT: [[I4:%.*]] = trunc i32 [[A0:%.*]] to i8653; CHECK-NEXT: [[I5:%.*]] = shl i8 [[I4]], 5654; CHECK-NEXT: [[I49:%.*]] = shl i8 [[I4]], 6655; CHECK-NEXT: [[I50:%.*]] = and i8 [[I49]], 64656; CHECK-NEXT: [[I51:%.*]] = xor i8 [[I50]], [[I5]]657; CHECK-NEXT: [[TMP0:%.*]] = lshr exact i8 [[I5]], 3658; CHECK-NEXT: [[I54:%.*]] = and i8 [[TMP0]], 16659; CHECK-NEXT: [[I55:%.*]] = or disjoint i8 [[I54]], [[I51]]660; CHECK-NEXT: ret i8 [[I55]]661;662entry:663 %i4 = trunc i32 %a0 to i8664 %i5 = shl i8 %i4, 5665 %i48 = and i8 %i5, 32666 %i49 = lshr i8 %i48, 5667 %i50 = mul i8 %i49, 64668 %i51 = xor i8 %i50, %i5669 %i52 = and i8 %i51, -128670 %i53 = lshr i8 %i52, 7671 %i54 = mul i8 %i53, 16672 %i55 = xor i8 %i54, %i51673 ret i8 %i55674}675 676define i32 @test42(i32 %a, i32 %b) {677; CHECK-LABEL: @test42(678; CHECK-NEXT: [[TMP1:%.*]] = sub i32 12, [[B:%.*]]679; CHECK-NEXT: [[DIV2:%.*]] = lshr i32 [[A:%.*]], [[TMP1]]680; CHECK-NEXT: ret i32 [[DIV2]]681;682 %div = lshr i32 4096, %b ; must be exact otherwise we'd divide by zero683 %div2 = udiv i32 %a, %div684 ret i32 %div2685}686 687define <2 x i32> @test42vec(<2 x i32> %a, <2 x i32> %b) {688; CHECK-LABEL: @test42vec(689; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i32> splat (i32 12), [[B:%.*]]690; CHECK-NEXT: [[DIV2:%.*]] = lshr <2 x i32> [[A:%.*]], [[TMP1]]691; CHECK-NEXT: ret <2 x i32> [[DIV2]]692;693 %div = lshr <2 x i32> <i32 4096, i32 4096>, %b ; must be exact otherwise we'd divide by zero694 %div2 = udiv <2 x i32> %a, %div695 ret <2 x i32> %div2696}697 698define i32 @test43(i32 %a, i32 %b) {699; CHECK-LABEL: @test43(700; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], 12701; CHECK-NEXT: [[DIV21:%.*]] = lshr i32 [[A:%.*]], [[TMP1]]702; CHECK-NEXT: ret i32 [[DIV21]]703;704 %div = shl i32 4096, %b ; must be exact otherwise we'd divide by zero705 %div2 = udiv i32 %a, %div706 ret i32 %div2707}708 709define i32 @test44(i32 %a) {710; CHECK-LABEL: @test44(711; CHECK-NEXT: [[Y:%.*]] = shl i32 [[A:%.*]], 5712; CHECK-NEXT: ret i32 [[Y]]713;714 %y = shl nuw i32 %a, 1715 %z = shl i32 %y, 4716 ret i32 %z717}718 719define i32 @test44_multiuse(i32 %a) {720; CHECK-LABEL: @test44_multiuse(721; CHECK-NEXT: [[Y:%.*]] = shl nuw i32 [[A:%.*]], 1722; CHECK-NEXT: call void @use_i32(i32 [[Y]])723; CHECK-NEXT: [[Z:%.*]] = shl i32 [[A]], 5724; CHECK-NEXT: ret i32 [[Z]]725;726 %y = shl nuw i32 %a, 1727 call void @use_i32(i32 %y)728 %z = shl i32 %y, 4729 ret i32 %z730}731 732define i32 @test45(i32 %a) {733; CHECK-LABEL: @test45(734; CHECK-NEXT: [[Y:%.*]] = lshr i32 [[A:%.*]], 5735; CHECK-NEXT: ret i32 [[Y]]736;737 %y = lshr exact i32 %a, 1738 %z = lshr i32 %y, 4739 ret i32 %z740}741 742define i32 @test45_multiuse(i32 %a) {743; CHECK-LABEL: @test45_multiuse(744; CHECK-NEXT: [[Y:%.*]] = lshr exact i32 [[A:%.*]], 1745; CHECK-NEXT: call void @use_i32(i32 [[Y]])746; CHECK-NEXT: [[Z:%.*]] = lshr i32 [[A]], 5747; CHECK-NEXT: ret i32 [[Z]]748;749 %y = lshr exact i32 %a, 1750 call void @use_i32(i32 %y)751 %z = lshr i32 %y, 4752 ret i32 %z753}754 755; (X >>?exact C1) << C2 --> X >>?exact (C1-C2)756 757define i32 @test46(i32 %a) {758; CHECK-LABEL: @test46(759; CHECK-NEXT: [[Z:%.*]] = ashr exact i32 [[A:%.*]], 2760; CHECK-NEXT: ret i32 [[Z]]761;762 %y = ashr exact i32 %a, 3763 %z = shl i32 %y, 1764 ret i32 %z765}766 767; (X >>?exact C1) << C2 --> X >>?exact (C1-C2)768 769define <2 x i32> @test46_splat_vec(<2 x i32> %a) {770; CHECK-LABEL: @test46_splat_vec(771; CHECK-NEXT: [[Z:%.*]] = ashr exact <2 x i32> [[A:%.*]], splat (i32 2)772; CHECK-NEXT: ret <2 x i32> [[Z]]773;774 %y = ashr exact <2 x i32> %a, <i32 3, i32 3>775 %z = shl <2 x i32> %y, <i32 1, i32 1>776 ret <2 x i32> %z777}778 779; (X >>?exact C1) << C2 --> X >>?exact (C1-C2)780 781define i8 @test47(i8 %a) {782; CHECK-LABEL: @test47(783; CHECK-NEXT: [[Z:%.*]] = lshr exact i8 [[A:%.*]], 2784; CHECK-NEXT: ret i8 [[Z]]785;786 %y = lshr exact i8 %a, 3787 %z = shl i8 %y, 1788 ret i8 %z789}790 791; (X >>?exact C1) << C2 --> X >>?exact (C1-C2)792 793define <2 x i8> @test47_splat_vec(<2 x i8> %a) {794; CHECK-LABEL: @test47_splat_vec(795; CHECK-NEXT: [[Z:%.*]] = lshr exact <2 x i8> [[A:%.*]], splat (i8 2)796; CHECK-NEXT: ret <2 x i8> [[Z]]797;798 %y = lshr exact <2 x i8> %a, <i8 3, i8 3>799 %z = shl <2 x i8> %y, <i8 1, i8 1>800 ret <2 x i8> %z801}802 803; (X >>u,exact C1) << C2 --> X << (C2-C1) when C2 > C1804 805define i32 @test48(i32 %x) {806; CHECK-LABEL: @test48(807; CHECK-NEXT: [[B:%.*]] = shl i32 [[X:%.*]], 2808; CHECK-NEXT: ret i32 [[B]]809;810 %A = lshr exact i32 %x, 1811 %B = shl i32 %A, 3812 ret i32 %B813}814 815; Verify that wrap flags are preserved from the original 'shl'.816 817define i32 @test48_nuw_nsw(i32 %x) {818; CHECK-LABEL: @test48_nuw_nsw(819; CHECK-NEXT: [[B:%.*]] = shl nuw nsw i32 [[X:%.*]], 2820; CHECK-NEXT: ret i32 [[B]]821;822 %A = lshr exact i32 %x, 1823 %B = shl nuw nsw i32 %A, 3824 ret i32 %B825}826 827; (X >>u,exact C1) << C2 --> X << (C2-C1) when splatted C2 > C1828 829define <2 x i32> @test48_splat_vec(<2 x i32> %x) {830; CHECK-LABEL: @test48_splat_vec(831; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> [[X:%.*]], splat (i32 2)832; CHECK-NEXT: ret <2 x i32> [[B]]833;834 %A = lshr exact <2 x i32> %x, <i32 1, i32 1>835 %B = shl nsw nuw <2 x i32> %A, <i32 3, i32 3>836 ret <2 x i32> %B837}838 839; (X >>s,exact C1) << C2 --> X << (C2-C1) when C2 > C1840 841define i32 @test49(i32 %x) {842; CHECK-LABEL: @test49(843; CHECK-NEXT: [[B:%.*]] = shl i32 [[X:%.*]], 2844; CHECK-NEXT: ret i32 [[B]]845;846 %A = ashr exact i32 %x, 1847 %B = shl i32 %A, 3848 ret i32 %B849}850 851; Verify that wrap flags are preserved from the original 'shl'.852 853define i32 @test49_nuw_nsw(i32 %x) {854; CHECK-LABEL: @test49_nuw_nsw(855; CHECK-NEXT: [[B:%.*]] = shl nuw nsw i32 [[X:%.*]], 2856; CHECK-NEXT: ret i32 [[B]]857;858 %A = ashr exact i32 %x, 1859 %B = shl nuw nsw i32 %A, 3860 ret i32 %B861}862 863; (X >>s,exact C1) << C2 --> X << (C2-C1) when splatted C2 > C1864 865define <2 x i32> @test49_splat_vec(<2 x i32> %x) {866; CHECK-LABEL: @test49_splat_vec(867; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> [[X:%.*]], splat (i32 2)868; CHECK-NEXT: ret <2 x i32> [[B]]869;870 %A = ashr exact <2 x i32> %x, <i32 1, i32 1>871 %B = shl nsw nuw <2 x i32> %A, <i32 3, i32 3>872 ret <2 x i32> %B873}874 875; (X <<nsw C1) >>s C2 --> X >>s (C2-C1)876 877define i32 @test50(i32 %x) {878; CHECK-LABEL: @test50(879; CHECK-NEXT: [[B:%.*]] = ashr i32 [[X:%.*]], 2880; CHECK-NEXT: ret i32 [[B]]881;882 %A = shl nsw i32 %x, 1883 %B = ashr i32 %A, 3884 ret i32 %B885}886 887; (X <<nsw C1) >>s C2 --> X >>s (C2-C1)888; Also, check that exact is propagated.889 890define <2 x i32> @test50_splat_vec(<2 x i32> %x) {891; CHECK-LABEL: @test50_splat_vec(892; CHECK-NEXT: [[B:%.*]] = ashr exact <2 x i32> [[X:%.*]], splat (i32 2)893; CHECK-NEXT: ret <2 x i32> [[B]]894;895 %A = shl nsw <2 x i32> %x, <i32 1, i32 1>896 %B = ashr exact <2 x i32> %A, <i32 3, i32 3>897 ret <2 x i32> %B898}899 900; (X <<nuw C1) >>u C2 --> X >>u (C2-C1)901 902define i32 @test51(i32 %x) {903; CHECK-LABEL: @test51(904; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X:%.*]], 2905; CHECK-NEXT: ret i32 [[B]]906;907 %A = shl nuw i32 %x, 1908 %B = lshr i32 %A, 3909 ret i32 %B910}911 912; (X <<nuw C1) >>u C2 --> X >>u (C2-C1) with splats913; Also, check that exact is propagated.914 915define <2 x i32> @test51_splat_vec(<2 x i32> %x) {916; CHECK-LABEL: @test51_splat_vec(917; CHECK-NEXT: [[B:%.*]] = lshr exact <2 x i32> [[X:%.*]], splat (i32 2)918; CHECK-NEXT: ret <2 x i32> [[B]]919;920 %A = shl nuw <2 x i32> %x, <i32 1, i32 1>921 %B = lshr exact <2 x i32> %A, <i32 3, i32 3>922 ret <2 x i32> %B923}924 925; (X << C1) >>u C2 --> X >>u (C2-C1) & (-1 >> C2)926; Also, check that exact is propagated.927 928define i32 @test51_no_nuw(i32 %x) {929; CHECK-LABEL: @test51_no_nuw(930; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 2931; CHECK-NEXT: [[B:%.*]] = and i32 [[TMP1]], 536870911932; CHECK-NEXT: ret i32 [[B]]933;934 %A = shl i32 %x, 1935 %B = lshr exact i32 %A, 3936 ret i32 %B937}938 939; (X << C1) >>u C2 --> X >>u (C2-C1) & (-1 >> C2)940 941define <2 x i32> @test51_no_nuw_splat_vec(<2 x i32> %x) {942; CHECK-LABEL: @test51_no_nuw_splat_vec(943; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 2)944; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[TMP1]], splat (i32 536870911)945; CHECK-NEXT: ret <2 x i32> [[B]]946;947 %A = shl <2 x i32> %x, <i32 1, i32 1>948 %B = lshr <2 x i32> %A, <i32 3, i32 3>949 ret <2 x i32> %B950}951 952; (X <<nsw C1) >>s C2 --> X <<nsw (C1 - C2)953 954define i32 @test52(i32 %x) {955; CHECK-LABEL: @test52(956; CHECK-NEXT: [[B:%.*]] = shl nsw i32 [[X:%.*]], 2957; CHECK-NEXT: ret i32 [[B]]958;959 %A = shl nsw i32 %x, 3960 %B = ashr i32 %A, 1961 ret i32 %B962}963 964; (X <<nsw C1) >>s C2 --> X <<nsw (C1 - C2)965 966define <2 x i32> @test52_splat_vec(<2 x i32> %x) {967; CHECK-LABEL: @test52_splat_vec(968; CHECK-NEXT: [[B:%.*]] = shl nsw <2 x i32> [[X:%.*]], splat (i32 2)969; CHECK-NEXT: ret <2 x i32> [[B]]970;971 %A = shl nsw <2 x i32> %x, <i32 3, i32 3>972 %B = ashr <2 x i32> %A, <i32 1, i32 1>973 ret <2 x i32> %B974}975 976; (X <<nuw C1) >>u C2 --> X <<nuw/nsw (C1 - C2)977 978define i32 @test53(i32 %x) {979; CHECK-LABEL: @test53(980; CHECK-NEXT: [[B:%.*]] = shl nuw nsw i32 [[X:%.*]], 2981; CHECK-NEXT: ret i32 [[B]]982;983 %A = shl nuw i32 %x, 3984 %B = lshr i32 %A, 1985 ret i32 %B986}987 988; (X <<nuw C1) >>u C2 --> X <<nuw/nsw (C1 - C2)989 990define <2 x i32> @test53_splat_vec(<2 x i32> %x) {991; CHECK-LABEL: @test53_splat_vec(992; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> [[X:%.*]], splat (i32 2)993; CHECK-NEXT: ret <2 x i32> [[B]]994;995 %A = shl nuw <2 x i32> %x, <i32 3, i32 3>996 %B = lshr <2 x i32> %A, <i32 1, i32 1>997 ret <2 x i32> %B998}999 1000; (X << C1) >>u C2 --> X << (C1 - C2) & (-1 >> C2)1001 1002define i8 @test53_no_nuw(i8 %x) {1003; CHECK-LABEL: @test53_no_nuw(1004; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 21005; CHECK-NEXT: [[B:%.*]] = and i8 [[TMP1]], 1241006; CHECK-NEXT: ret i8 [[B]]1007;1008 %A = shl i8 %x, 31009 %B = lshr i8 %A, 11010 ret i8 %B1011}1012 1013; (X << C1) >>u C2 --> X << (C1 - C2) & (-1 >> C2)1014 1015define <2 x i8> @test53_no_nuw_splat_vec(<2 x i8> %x) {1016; CHECK-LABEL: @test53_no_nuw_splat_vec(1017; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 2)1018; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[TMP1]], splat (i8 124)1019; CHECK-NEXT: ret <2 x i8> [[B]]1020;1021 %A = shl <2 x i8> %x, <i8 3, i8 3>1022 %B = lshr <2 x i8> %A, <i8 1, i8 1>1023 ret <2 x i8> %B1024}1025 1026define i32 @test54(i32 %x) {1027; CHECK-LABEL: @test54(1028; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 31029; CHECK-NEXT: [[AND:%.*]] = and i32 [[TMP1]], 161030; CHECK-NEXT: ret i32 [[AND]]1031;1032 %shr2 = lshr i32 %x, 11033 %shl = shl i32 %shr2, 41034 %and = and i32 %shl, 161035 ret i32 %and1036}1037 1038define <2 x i32> @test54_splat_vec(<2 x i32> %x) {1039; CHECK-LABEL: @test54_splat_vec(1040; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 3)1041; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[TMP1]], splat (i32 16)1042; CHECK-NEXT: ret <2 x i32> [[AND]]1043;1044 %shr2 = lshr <2 x i32> %x, <i32 1, i32 1>1045 %shl = shl <2 x i32> %shr2, <i32 4, i32 4>1046 %and = and <2 x i32> %shl, <i32 16, i32 16>1047 ret <2 x i32> %and1048}1049 1050define i32 @test55(i32 %x) {1051; CHECK-LABEL: @test55(1052; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 31053; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], 81054; CHECK-NEXT: ret i32 [[OR]]1055;1056 %shr2 = lshr i32 %x, 11057 %shl = shl i32 %shr2, 41058 %or = or i32 %shl, 81059 ret i32 %or1060}1061 1062define i32 @test56(i32 %x) {1063; CHECK-LABEL: @test56(1064; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 31065; CHECK-NEXT: [[SHL:%.*]] = and i32 [[TMP1]], -161066; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[SHL]], 71067; CHECK-NEXT: ret i32 [[OR]]1068;1069 %shr2 = lshr i32 %x, 11070 %shl = shl i32 %shr2, 41071 %or = or i32 %shl, 71072 ret i32 %or1073}1074 1075define i32 @test57(i32 %x) {1076; CHECK-LABEL: @test57(1077; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 31078; CHECK-NEXT: [[SHL:%.*]] = and i32 [[TMP1]], -161079; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[SHL]], 71080; CHECK-NEXT: ret i32 [[OR]]1081;1082 %shr = ashr i32 %x, 11083 %shl = shl i32 %shr, 41084 %or = or i32 %shl, 71085 ret i32 %or1086}1087 1088define i32 @test58(i32 %x) {1089; CHECK-LABEL: @test58(1090; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 31091; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], 11092; CHECK-NEXT: ret i32 [[OR]]1093;1094 %shr = ashr i32 %x, 41095 %shl = shl i32 %shr, 11096 %or = or i32 %shl, 11097 ret i32 %or1098}1099 1100define <2 x i32> @test58_splat_vec(<2 x i32> %x) {1101; CHECK-LABEL: @test58_splat_vec(1102; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], splat (i32 3)1103; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[TMP1]], splat (i32 1)1104; CHECK-NEXT: ret <2 x i32> [[OR]]1105;1106 %shr = ashr <2 x i32> %x, <i32 4, i32 4>1107 %shl = shl <2 x i32> %shr, <i32 1, i32 1>1108 %or = or <2 x i32> %shl, <i32 1, i32 1>1109 ret <2 x i32> %or1110}1111 1112define i32 @test59(i32 %x) {1113; CHECK-LABEL: @test59(1114; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 31115; CHECK-NEXT: [[SHL:%.*]] = and i32 [[TMP1]], -41116; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[SHL]], 21117; CHECK-NEXT: ret i32 [[OR]]1118;1119 %shr = ashr i32 %x, 41120 %shl = shl i32 %shr, 11121 %or = or i32 %shl, 21122 ret i32 %or1123}1124 1125; propagate "exact" trait1126define i32 @test60(i32 %x) {1127; CHECK-LABEL: @test60(1128; CHECK-NEXT: [[SHL:%.*]] = ashr exact i32 [[X:%.*]], 31129; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], 11130; CHECK-NEXT: ret i32 [[OR]]1131;1132 %shr = ashr exact i32 %x, 41133 %shl = shl i32 %shr, 11134 %or = or i32 %shl, 11135 ret i32 %or1136}1137 1138; PR170261139define void @test61(i128 %arg, i1 %c1, i1 %c2, i1 %c3, i1 %c4) {1140; CHECK-LABEL: @test61(1141; CHECK-NEXT: bb:1142; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB12:%.*]]1143; CHECK: bb1:1144; CHECK-NEXT: br label [[BB2:%.*]]1145; CHECK: bb2:1146; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB7:%.*]]1147; CHECK: bb3:1148; CHECK-NEXT: br label [[BB8:%.*]]1149; CHECK: bb7:1150; CHECK-NEXT: br i1 [[C3:%.*]], label [[BB8]], label [[BB2]]1151; CHECK: bb8:1152; CHECK-NEXT: br i1 poison, label [[BB11:%.*]], label [[BB12]]1153; CHECK: bb11:1154; CHECK-NEXT: br i1 [[C4:%.*]], label [[BB1]], label [[BB12]]1155; CHECK: bb12:1156; CHECK-NEXT: ret void1157;1158bb:1159 br i1 %c1, label %bb1, label %bb121160 1161bb1: ; preds = %bb11, %bb1162 br label %bb21163 1164bb2: ; preds = %bb7, %bb11165 br i1 %c2, label %bb3, label %bb71166 1167bb3: ; preds = %bb21168 %i = lshr i128 %arg, 368934881474191032321169 %i4 = shl i128 %i, 01170 %i5 = or i128 %i4, 01171 %i6 = trunc i128 %i5 to i161172 br label %bb81173 1174bb7: ; preds = %bb21175 br i1 %c3, label %bb8, label %bb21176 1177bb8: ; preds = %bb7, %bb31178 %i9 = phi i16 [ %i6, %bb3 ], [ poison, %bb7 ]1179 %i10 = icmp eq i16 %i9, 01180 br i1 %i10, label %bb11, label %bb121181 1182bb11: ; preds = %bb81183 br i1 %c4, label %bb1, label %bb121184 1185bb12: ; preds = %bb11, %bb8, %bb1186 ret void1187}1188 1189define i32 @test62(i32 %a) {1190; CHECK-LABEL: @test62(1191; CHECK-NEXT: ret i32 poison1192;1193 %b = ashr i32 %a, 32 ; shift all bits out1194 ret i32 %b1195}1196 1197define <4 x i32> @test62_splat_vector(<4 x i32> %a) {1198; CHECK-LABEL: @test62_splat_vector(1199; CHECK-NEXT: ret <4 x i32> poison1200;1201 %b = ashr <4 x i32> %a, <i32 32, i32 32, i32 32, i32 32> ; shift all bits out1202 ret <4 x i32> %b1203}1204 1205define <4 x i32> @test62_non_splat_vector(<4 x i32> %a) {1206; CHECK-LABEL: @test62_non_splat_vector(1207; CHECK-NEXT: [[B:%.*]] = ashr <4 x i32> [[A:%.*]], <i32 32, i32 0, i32 1, i32 2>1208; CHECK-NEXT: ret <4 x i32> [[B]]1209;1210 %b = ashr <4 x i32> %a, <i32 32, i32 0, i32 1, i32 2> ; shift all bits out1211 ret <4 x i32> %b1212}1213 1214define <2 x i65> @test_63(<2 x i64> %t) {1215; CHECK-LABEL: @test_63(1216; CHECK-NEXT: [[A:%.*]] = zext <2 x i64> [[T:%.*]] to <2 x i65>1217; CHECK-NEXT: [[SEXT:%.*]] = shl <2 x i65> [[A]], splat (i65 33)1218; CHECK-NEXT: [[B:%.*]] = ashr exact <2 x i65> [[SEXT]], splat (i65 33)1219; CHECK-NEXT: ret <2 x i65> [[B]]1220;1221 %a = zext <2 x i64> %t to <2 x i65>1222 %sext = shl <2 x i65> %a, <i65 33, i65 33>1223 %b = ashr <2 x i65> %sext, <i65 33, i65 33>1224 ret <2 x i65> %b1225}1226 1227define i32 @test_shl_zext_bool(i1 %t) {1228; CHECK-LABEL: @test_shl_zext_bool(1229; CHECK-NEXT: [[SHL:%.*]] = select i1 [[T:%.*]], i32 4, i32 01230; CHECK-NEXT: ret i32 [[SHL]]1231;1232 %ext = zext i1 %t to i321233 %shl = shl i32 %ext, 21234 ret i32 %shl1235}1236 1237define <2 x i32> @test_shl_zext_bool_splat(<2 x i1> %t) {1238; CHECK-LABEL: @test_shl_zext_bool_splat(1239; CHECK-NEXT: [[SHL:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> splat (i32 8), <2 x i32> zeroinitializer1240; CHECK-NEXT: ret <2 x i32> [[SHL]]1241;1242 %ext = zext <2 x i1> %t to <2 x i32>1243 %shl = shl <2 x i32> %ext, <i32 3, i32 3>1244 ret <2 x i32> %shl1245}1246 1247define <2 x i32> @test_shl_zext_bool_vec(<2 x i1> %t) {1248; CHECK-LABEL: @test_shl_zext_bool_vec(1249; CHECK-NEXT: [[SHL:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer1250; CHECK-NEXT: ret <2 x i32> [[SHL]]1251;1252 %ext = zext <2 x i1> %t to <2 x i32>1253 %shl = shl <2 x i32> %ext, <i32 2, i32 3>1254 ret <2 x i32> %shl1255}1256 1257define i32 @test_shl_zext_bool_not_constant(i1 %cmp, i32 %shamt) {1258; CHECK-LABEL: @test_shl_zext_bool_not_constant(1259; CHECK-NEXT: [[CONV3:%.*]] = zext i1 [[CMP:%.*]] to i321260; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 [[CONV3]], [[SHAMT:%.*]]1261; CHECK-NEXT: ret i32 [[SHL]]1262;1263 %conv3 = zext i1 %cmp to i321264 %shl = shl i32 %conv3, %shamt1265 ret i32 %shl1266}1267 1268define i64 @shl_zext(i32 %t) {1269; CHECK-LABEL: @shl_zext(1270; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[T:%.*]], 81271; CHECK-NEXT: [[SHL:%.*]] = zext i32 [[TMP1]] to i641272; CHECK-NEXT: ret i64 [[SHL]]1273;1274 %and = and i32 %t, 167772151275 %ext = zext i32 %and to i641276 %shl = shl i64 %ext, 81277 ret i64 %shl1278}1279 1280define i64 @shl_zext_extra_use(i32 %t) {1281; CHECK-LABEL: @shl_zext_extra_use(1282; CHECK-NEXT: [[AND:%.*]] = and i32 [[T:%.*]], 167772151283; CHECK-NEXT: [[EXT:%.*]] = zext nneg i32 [[AND]] to i641284; CHECK-NEXT: call void @use(i64 [[EXT]])1285; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i64 [[EXT]], 81286; CHECK-NEXT: ret i64 [[SHL]]1287;1288 %and = and i32 %t, 167772151289 %ext = zext i32 %and to i641290 call void @use(i64 %ext)1291 %shl = shl i64 %ext, 81292 ret i64 %shl1293}1294 1295define <2 x i64> @shl_zext_splat_vec(<2 x i32> %t) {1296; CHECK-LABEL: @shl_zext_splat_vec(1297; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[T:%.*]], splat (i32 8)1298; CHECK-NEXT: [[SHL:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>1299; CHECK-NEXT: ret <2 x i64> [[SHL]]1300;1301 %and = and <2 x i32> %t, <i32 16777215, i32 16777215>1302 %ext = zext <2 x i32> %and to <2 x i64>1303 %shl = shl <2 x i64> %ext, <i64 8, i64 8>1304 ret <2 x i64> %shl1305}1306 1307define i64 @shl_zext_mul(i32 %t) {1308; CHECK-LABEL: @shl_zext_mul(1309; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[T:%.*]], 167772151310; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[MUL]] to i641311; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[EXT]], 321312; CHECK-NEXT: ret i64 [[SHL]]1313;1314 %mul = mul i32 %t, 167772151315 %ext = zext i32 %mul to i641316 %shl = shl i64 %ext, 321317 ret i64 %shl1318}1319 1320define <3 x i17> @shl_zext_mul_splat(<3 x i5> %t) {1321; CHECK-LABEL: @shl_zext_mul_splat(1322; CHECK-NEXT: [[MUL:%.*]] = mul <3 x i5> [[T:%.*]], splat (i5 13)1323; CHECK-NEXT: [[EXT:%.*]] = zext <3 x i5> [[MUL]] to <3 x i17>1324; CHECK-NEXT: [[SHL:%.*]] = shl nuw <3 x i17> [[EXT]], splat (i17 12)1325; CHECK-NEXT: ret <3 x i17> [[SHL]]1326;1327 %mul = mul <3 x i5> %t, <i5 13, i5 13, i5 13>1328 %ext = zext <3 x i5> %mul to <3 x i17>1329 %shl = shl <3 x i17> %ext, <i17 12, i17 12, i17 12>1330 ret <3 x i17> %shl1331}1332 1333define i64 @shl_zext_mul_low_shift_amount(i32 %t) {1334; CHECK-LABEL: @shl_zext_mul_low_shift_amount(1335; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[T:%.*]], 167772151336; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[MUL]] to i641337; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i64 [[EXT]], 311338; CHECK-NEXT: ret i64 [[SHL]]1339;1340 %mul = mul i32 %t, 167772151341 %ext = zext i32 %mul to i641342 %shl = shl i64 %ext, 311343 ret i64 %shl1344}1345 1346define i64 @shl_zext_mul_extra_use1(i32 %t) {1347; CHECK-LABEL: @shl_zext_mul_extra_use1(1348; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[T:%.*]], 167772151349; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[MUL]] to i641350; CHECK-NEXT: call void @use(i64 [[EXT]])1351; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[EXT]], 321352; CHECK-NEXT: ret i64 [[SHL]]1353;1354 %mul = mul i32 %t, 167772151355 %ext = zext i32 %mul to i641356 call void @use(i64 %ext)1357 %shl = shl i64 %ext, 321358 ret i64 %shl1359}1360 1361define i64 @shl_zext_mul_extra_use2(i32 %t) {1362; CHECK-LABEL: @shl_zext_mul_extra_use2(1363; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[T:%.*]], 167772151364; CHECK-NEXT: call void @use_i32(i32 [[MUL]])1365; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[MUL]] to i641366; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[EXT]], 321367; CHECK-NEXT: ret i64 [[SHL]]1368;1369 %mul = mul i32 %t, 167772151370 call void @use_i32(i32 %mul)1371 %ext = zext i32 %mul to i641372 %shl = shl i64 %ext, 321373 ret i64 %shl1374}1375 1376define <2 x i8> @ashr_demanded_bits_splat(<2 x i8> %x) {1377; CHECK-LABEL: @ashr_demanded_bits_splat(1378; CHECK-NEXT: [[SHR:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 7)1379; CHECK-NEXT: ret <2 x i8> [[SHR]]1380;1381 %and = and <2 x i8> %x, <i8 128, i8 128>1382 %shr = ashr <2 x i8> %and, <i8 7, i8 7>1383 ret <2 x i8> %shr1384}1385 1386define <vscale x 8 x i8> @ashr_demanded_bits_splat2(<vscale x 8 x i8> %x) {1387; CHECK-LABEL: @ashr_demanded_bits_splat2(1388; CHECK-NEXT: [[SHR:%.*]] = ashr <vscale x 8 x i8> [[X:%.*]], splat (i8 7)1389; CHECK-NEXT: ret <vscale x 8 x i8> [[SHR]]1390;1391 %and = and <vscale x 8 x i8> %x, splat (i8 128)1392 %shr = ashr <vscale x 8 x i8> %and, splat (i8 7)1393 ret <vscale x 8 x i8> %shr1394}1395 1396define <2 x i8> @lshr_demanded_bits_splat(<2 x i8> %x) {1397; CHECK-LABEL: @lshr_demanded_bits_splat(1398; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i8> [[X:%.*]], splat (i8 7)1399; CHECK-NEXT: ret <2 x i8> [[SHR]]1400;1401 %and = and <2 x i8> %x, <i8 128, i8 128>1402 %shr = lshr <2 x i8> %and, <i8 7, i8 7>1403 ret <2 x i8> %shr1404}1405 1406define <vscale x 8 x i8> @lshr_demanded_bits_splat2(<vscale x 8 x i8> %x) {1407; CHECK-LABEL: @lshr_demanded_bits_splat2(1408; CHECK-NEXT: [[SHR:%.*]] = lshr <vscale x 8 x i8> [[X:%.*]], splat (i8 7)1409; CHECK-NEXT: ret <vscale x 8 x i8> [[SHR]]1410;1411 %and = and <vscale x 8 x i8> %x, splat (i8 128)1412 %shr = lshr <vscale x 8 x i8> %and, splat (i8 7)1413 ret <vscale x 8 x i8> %shr1414}1415 1416; Make sure known bits works correctly with non power of 2 bit widths.1417define i7 @test65(i7 %a, i7 %b) {1418; CHECK-LABEL: @test65(1419; CHECK-NEXT: ret i7 01420;1421 %shiftamt = and i7 %b, 6 ; this ensures the shift amount is even and less than the bit width.1422 %x = lshr i7 42, %shiftamt ; 42 has a zero in every even numbered bit and a one in every odd bit.1423 %y = and i7 %x, 1 ; this extracts the lsb which should be 0 because we shifted an even number of bits and all even bits of the shift input are 0.1424 ret i7 %y1425}1426 1427define i32 @shl_select_add_true(i32 %x, i1 %cond) {1428; CHECK-LABEL: @shl_select_add_true(1429; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 11430; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 141431; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]1432; CHECK-NEXT: ret i32 [[TMP3]]1433;1434 %1 = add i32 %x, 71435 %2 = select i1 %cond, i32 %1, i32 %x1436 %3 = shl i32 %2, 11437 ret i32 %31438}1439 1440define i32 @shl_select_add_false(i32 %x, i1 %cond) {1441; CHECK-LABEL: @shl_select_add_false(1442; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 11443; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 141444; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]1445; CHECK-NEXT: ret i32 [[TMP3]]1446;1447 %1 = add i32 %x, 71448 %2 = select i1 %cond, i32 %x, i32 %11449 %3 = shl i32 %2, 11450 ret i32 %31451}1452 1453define i32 @shl_select_and_true(i32 %x, i1 %cond) {1454; CHECK-LABEL: @shl_select_and_true(1455; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 11456; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 141457; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]1458; CHECK-NEXT: ret i32 [[TMP3]]1459;1460 %1 = and i32 %x, 71461 %2 = select i1 %cond, i32 %1, i32 %x1462 %3 = shl i32 %2, 11463 ret i32 %31464}1465 1466define i32 @shl_select_and_false(i32 %x, i1 %cond) {1467; CHECK-LABEL: @shl_select_and_false(1468; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 11469; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 141470; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]1471; CHECK-NEXT: ret i32 [[TMP3]]1472;1473 %1 = and i32 %x, 71474 %2 = select i1 %cond, i32 %x, i32 %11475 %3 = shl i32 %2, 11476 ret i32 %31477}1478 1479define i32 @lshr_select_and_true(i32 %x, i1 %cond) {1480; CHECK-LABEL: @lshr_select_and_true(1481; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 11482; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 31483; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]1484; CHECK-NEXT: ret i32 [[TMP3]]1485;1486 %1 = and i32 %x, 71487 %2 = select i1 %cond, i32 %1, i32 %x1488 %3 = lshr i32 %2, 11489 ret i32 %31490}1491 1492define i32 @lshr_select_and_false(i32 %x, i1 %cond) {1493; CHECK-LABEL: @lshr_select_and_false(1494; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 11495; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 31496; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]1497; CHECK-NEXT: ret i32 [[TMP3]]1498;1499 %1 = and i32 %x, 71500 %2 = select i1 %cond, i32 %x, i32 %11501 %3 = lshr i32 %2, 11502 ret i32 %31503}1504 1505define i32 @ashr_select_and_true(i32 %x, i1 %cond) {1506; CHECK-LABEL: @ashr_select_and_true(1507; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 11508; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -10737418211509; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]1510; CHECK-NEXT: ret i32 [[TMP3]]1511;1512 %1 = and i32 %x, 21474836551513 %2 = select i1 %cond, i32 %1, i32 %x1514 %3 = ashr i32 %2, 11515 ret i32 %31516}1517 1518define i32 @ashr_select_and_false(i32 %x, i1 %cond) {1519; CHECK-LABEL: @ashr_select_and_false(1520; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 11521; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -10737418211522; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]1523; CHECK-NEXT: ret i32 [[TMP3]]1524;1525 %1 = and i32 %x, 21474836551526 %2 = select i1 %cond, i32 %x, i32 %11527 %3 = ashr i32 %2, 11528 ret i32 %31529}1530 1531define i32 @shl_select_or_true(i32 %x, i1 %cond) {1532; CHECK-LABEL: @shl_select_or_true(1533; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 11534; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 141535; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]1536; CHECK-NEXT: ret i32 [[TMP3]]1537;1538 %1 = or i32 %x, 71539 %2 = select i1 %cond, i32 %1, i32 %x1540 %3 = shl i32 %2, 11541 ret i32 %31542}1543 1544define i32 @shl_select_or_false(i32 %x, i1 %cond) {1545; CHECK-LABEL: @shl_select_or_false(1546; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 11547; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 141548; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]1549; CHECK-NEXT: ret i32 [[TMP3]]1550;1551 %1 = or i32 %x, 71552 %2 = select i1 %cond, i32 %x, i32 %11553 %3 = shl i32 %2, 11554 ret i32 %31555}1556 1557define i32 @lshr_select_or_true(i32 %x, i1 %cond) {1558; CHECK-LABEL: @lshr_select_or_true(1559; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 11560; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 31561; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]1562; CHECK-NEXT: ret i32 [[TMP3]]1563;1564 %1 = or i32 %x, 71565 %2 = select i1 %cond, i32 %1, i32 %x1566 %3 = lshr i32 %2, 11567 ret i32 %31568}1569 1570define i32 @lshr_select_or_false(i32 %x, i1 %cond) {1571; CHECK-LABEL: @lshr_select_or_false(1572; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 11573; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 31574; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]1575; CHECK-NEXT: ret i32 [[TMP3]]1576;1577 %1 = or i32 %x, 71578 %2 = select i1 %cond, i32 %x, i32 %11579 %3 = lshr i32 %2, 11580 ret i32 %31581}1582 1583define i32 @ashr_select_or_true(i32 %x, i1 %cond) {1584; CHECK-LABEL: @ashr_select_or_true(1585; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 11586; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 31587; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]1588; CHECK-NEXT: ret i32 [[TMP3]]1589;1590 %1 = or i32 %x, 71591 %2 = select i1 %cond, i32 %1, i32 %x1592 %3 = ashr i32 %2, 11593 ret i32 %31594}1595 1596define i32 @ashr_select_or_false(i32 %x, i1 %cond) {1597; CHECK-LABEL: @ashr_select_or_false(1598; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 11599; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 31600; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]1601; CHECK-NEXT: ret i32 [[TMP3]]1602;1603 %1 = or i32 %x, 71604 %2 = select i1 %cond, i32 %x, i32 %11605 %3 = ashr i32 %2, 11606 ret i32 %31607}1608 1609define i32 @shl_select_xor_true(i32 %x, i1 %cond) {1610; CHECK-LABEL: @shl_select_xor_true(1611; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 11612; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 141613; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]1614; CHECK-NEXT: ret i32 [[TMP3]]1615;1616 %1 = xor i32 %x, 71617 %2 = select i1 %cond, i32 %1, i32 %x1618 %3 = shl i32 %2, 11619 ret i32 %31620}1621 1622define i32 @shl_select_xor_false(i32 %x, i1 %cond) {1623; CHECK-LABEL: @shl_select_xor_false(1624; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 11625; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 141626; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]1627; CHECK-NEXT: ret i32 [[TMP3]]1628;1629 %1 = xor i32 %x, 71630 %2 = select i1 %cond, i32 %x, i32 %11631 %3 = shl i32 %2, 11632 ret i32 %31633}1634 1635define i32 @lshr_select_xor_true(i32 %x, i1 %cond) {1636; CHECK-LABEL: @lshr_select_xor_true(1637; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 11638; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 31639; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]1640; CHECK-NEXT: ret i32 [[TMP3]]1641;1642 %1 = xor i32 %x, 71643 %2 = select i1 %cond, i32 %1, i32 %x1644 %3 = lshr i32 %2, 11645 ret i32 %31646}1647 1648define i32 @lshr_select_xor_false(i32 %x, i1 %cond) {1649; CHECK-LABEL: @lshr_select_xor_false(1650; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 11651; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 31652; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]1653; CHECK-NEXT: ret i32 [[TMP3]]1654;1655 %1 = xor i32 %x, 71656 %2 = select i1 %cond, i32 %x, i32 %11657 %3 = lshr i32 %2, 11658 ret i32 %31659}1660 1661define i32 @ashr_select_xor_true(i32 %x, i1 %cond) {1662; CHECK-LABEL: @ashr_select_xor_true(1663; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 11664; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 31665; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]]1666; CHECK-NEXT: ret i32 [[TMP3]]1667;1668 %1 = xor i32 %x, 71669 %2 = select i1 %cond, i32 %1, i32 %x1670 %3 = ashr i32 %2, 11671 ret i32 %31672}1673 1674define i32 @ashr_select_xor_false(i32 %x, i1 %cond) {1675; CHECK-LABEL: @ashr_select_xor_false(1676; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 11677; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 31678; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]]1679; CHECK-NEXT: ret i32 [[TMP3]]1680;1681 %1 = xor i32 %x, 71682 %2 = select i1 %cond, i32 %x, i32 %11683 %3 = ashr i32 %2, 11684 ret i32 %31685}1686 1687; OSS Fuzz #48711688; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=48711689define i177 @lshr_out_of_range(i177 %Y, ptr %A2, ptr %ptr) {1690; CHECK-LABEL: @lshr_out_of_range(1691; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i177 [[Y:%.*]], -11692; CHECK-NEXT: [[B4:%.*]] = sext i1 [[TMP1]] to i1771693; CHECK-NEXT: [[C8:%.*]] = icmp ugt i177 [[Y]], [[B4]]1694; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[C8]] to i641695; CHECK-NEXT: [[G18:%.*]] = getelementptr ptr, ptr [[A2:%.*]], i64 [[TMP2]]1696; CHECK-NEXT: store ptr [[G18]], ptr [[PTR:%.*]], align 81697; CHECK-NEXT: ret i177 01698;1699 %B5 = udiv i177 %Y, -11700 %B4 = add i177 %B5, -11701 %B2 = add i177 %B4, -11702 %B6 = mul i177 %B5, %B21703 %B3 = add i177 %B2, %B21704 %B10 = sub i177 %B5, %B31705 %B12 = lshr i177 %Y, %B61706 %C8 = icmp ugt i177 %B12, %B41707 %G18 = getelementptr ptr, ptr %A2, i1 %C81708 store ptr %G18, ptr %ptr1709 %B1 = udiv i177 %B10, %B61710 ret i177 %B11711}1712 1713; OSS Fuzz #267161714; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=267161715define i177 @lshr_out_of_range2(i177 %Y, ptr %A2, ptr %ptr) {1716; CHECK-LABEL: @lshr_out_of_range2(1717; CHECK-NEXT: [[C8:%.*]] = icmp ne i177 [[Y:%.*]], 01718; CHECK-NEXT: [[TMP1:%.*]] = sext i1 [[C8]] to i641719; CHECK-NEXT: [[G18:%.*]] = getelementptr ptr, ptr [[A2:%.*]], i64 [[TMP1]]1720; CHECK-NEXT: store ptr [[G18]], ptr [[PTR:%.*]], align 81721; CHECK-NEXT: ret i177 01722;1723 %B5 = udiv i177 %Y, -11724 %B = sdiv i177 %B5, -11725 %B4 = add i177 %B5, %B1726 %B2 = add i177 %B4, -11727 %B6 = mul i177 %B5, %B21728 %B12 = lshr i177 %Y, %B61729 %C8 = icmp ugt i177 %B12, %B41730 %G18 = getelementptr ptr, ptr %A2, i1 %C81731 store ptr %G18, ptr %ptr, align 81732 %B1 = udiv i177 %B5, %B61733 ret i177 %B11734}1735 1736; The fuzzer-generated @ashr_out_of_range test case does not reach a fixpoint,1737; because a logical and it not relaxed to a bitwise and in one iteration.1738 1739; OSS Fuzz #50321740; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=50321741define void @ashr_out_of_range(ptr %A) "instcombine-no-verify-fixpoint" {1742; CHECK-LABEL: @ashr_out_of_range(1743; CHECK-NEXT: [[L:%.*]] = load i177, ptr [[A:%.*]], align 41744; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L]], -11745; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i64 -1, i64 -21746; CHECK-NEXT: [[G11:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP2]]1747; CHECK-NEXT: [[L7:%.*]] = load i177, ptr [[G11]], align 41748; CHECK-NEXT: [[L7_FROZEN:%.*]] = freeze i177 [[L7]]1749; CHECK-NEXT: [[C171:%.*]] = icmp slt i177 [[L7_FROZEN]], 01750; CHECK-NEXT: [[C17:%.*]] = select i1 [[TMP1]], i1 [[C171]], i1 false1751; CHECK-NEXT: [[TMP3:%.*]] = sext i1 [[C17]] to i641752; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP3]]1753; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i177 [[L7_FROZEN]], -11754; CHECK-NEXT: [[B28:%.*]] = select i1 [[TMP4]], i177 0, i177 [[L7_FROZEN]]1755; CHECK-NEXT: store i177 [[B28]], ptr [[G62]], align 41756; CHECK-NEXT: ret void1757;1758 %L = load i177, ptr %A1759 %B5 = udiv i177 %L, -11760 %B4 = add i177 %B5, -11761 %B2 = add i177 %B4, -11762 %G11 = getelementptr i177, ptr %A, i177 %B21763 %L7 = load i177, ptr %G111764 %B6 = mul i177 %B5, %B21765 %B24 = ashr i177 %L7, %B61766 %B36 = and i177 %L7, %B41767 %C17 = icmp sgt i177 %B36, %B241768 %G62 = getelementptr i177, ptr %G11, i1 %C171769 %B28 = urem i177 %B24, %B61770 store i177 %B28, ptr %G621771 ret void1772}1773 1774; OSS Fuzz #261351775; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=261351776define void @ashr_out_of_range_1(ptr %A) {1777; CHECK-LABEL: @ashr_out_of_range_1(1778; CHECK-NEXT: [[L:%.*]] = load i177, ptr [[A:%.*]], align 41779; CHECK-NEXT: [[L_FROZEN:%.*]] = freeze i177 [[L]]1780; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L_FROZEN]], -11781; CHECK-NEXT: [[TMP2:%.*]] = trunc i177 [[L_FROZEN]] to i641782; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]1783; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP3]]1784; CHECK-NEXT: [[G11:%.*]] = getelementptr i8, ptr [[TMP4]], i64 -241785; CHECK-NEXT: [[TMP5:%.*]] = sext i1 [[TMP1]] to i641786; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP5]]1787; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i177 [[L_FROZEN]], -11788; CHECK-NEXT: [[B28:%.*]] = select i1 [[TMP6]], i177 0, i177 [[L_FROZEN]]1789; CHECK-NEXT: store i177 [[B28]], ptr [[G62]], align 41790; CHECK-NEXT: ret void1791;1792 %L = load i177, ptr %A, align 41793 %B5 = udiv i177 %L, -11794 %B4 = add i177 %B5, -11795 %B = and i177 %B4, %L1796 %B2 = add i177 %B, -11797 %G11 = getelementptr i177, ptr %A, i177 %B21798 %B6 = mul i177 %B5, %B21799 %B24 = ashr i177 %L, %B61800 %C17 = icmp sgt i177 %B, %B241801 %G62 = getelementptr i177, ptr %G11, i1 %C171802 %B28 = urem i177 %B24, %B61803 store i177 %B28, ptr %G62, align 41804 ret void1805}1806 1807; OSS Fuzz #380781808; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=380781809define void @ossfuzz_38078(i32 %arg, i32 %arg1, ptr %ptr, ptr %ptr2, ptr %ptr3, ptr %ptr4, ptr %ptr5, ptr %ptr6, ptr %ptr7) {1810; CHECK-LABEL: @ossfuzz_38078(1811; CHECK-NEXT: bb:1812; CHECK-NEXT: [[G1:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 -41813; CHECK-NEXT: [[I2:%.*]] = sub i32 0, [[ARG1:%.*]]1814; CHECK-NEXT: [[I5:%.*]] = icmp eq i32 [[ARG:%.*]], [[I2]]1815; CHECK-NEXT: call void @llvm.assume(i1 [[I5]])1816; CHECK-NEXT: store volatile i32 2147483647, ptr [[G1]], align 41817; CHECK-NEXT: br label [[BB:%.*]]1818; CHECK: BB:1819; CHECK-NEXT: unreachable1820;1821bb:1822 %i = or i32 0, -11823 %B24 = urem i32 %i, -21474836481824 %B21 = or i32 %i, %i1825 %i2 = add nsw i32 %arg, %arg11826 %B7 = or i32 %i, %i21827 %B8 = and i32 %i, %i21828 %B12 = sdiv i32 %i2, %B71829 %B3 = add i32 %i2, %B241830 %B5 = and i32 %i, %B31831 %B18 = and i32 %i, %B81832 %i3 = xor i32 %i2, %B31833 %C1 = icmp ne i32 %B8, %B51834 %i4 = lshr i32 %B5, %i31835 %B29 = shl nuw i32 %B8, %i31836 %B2 = lshr i32 %B12, %i21837 %B16 = add i32 %B2, %i31838 %B = sdiv i32 %B29, %B51839 %B15 = sub i32 %i2, %B51840 %B22 = or i32 %B21, %B291841 %B23 = mul i32 %B15, %B1842 %C2 = icmp sge i1 %C1, false1843 %C7 = icmp sle i32 %i3, %B161844 %B20 = xor i32 %B21, %B221845 %G1 = getelementptr i32, ptr %ptr, i32 %B221846 %B1 = sub i32 %B, 01847 %B26 = ashr i32 %B29, 01848 %B4 = add i32 0, %B51849 %B27 = srem i32 %B12, %B211850 %i5 = icmp eq i32 %B20, %B181851 %C11 = icmp ugt i32 %i4, %B41852 call void @llvm.assume(i1 %i5)1853 store volatile i32 %B4, ptr %G1, align 41854 %B11 = or i32 0, %B231855 br label %BB1856 1857BB:1858 store i1 %C7, ptr %ptr2, align 11859 store i32 %B11, ptr %ptr3, align 41860 store i1 %C11, ptr %ptr4, align 11861 store i32 %B1, ptr %ptr5, align 41862 store i32 %B27, ptr %ptr6, align 41863 %C = icmp ne i32 %B26, 01864 %B17 = or i1 %C, %C21865 store i1 %B17, ptr %ptr7, align 11866 unreachable1867}1868declare void @llvm.assume(i1 noundef)1869 1870define i8 @lshr_mask_demand(i8 %x) {1871; CHECK-LABEL: @lshr_mask_demand(1872; CHECK-NEXT: [[S:%.*]] = lshr i8 63, [[X:%.*]]1873; CHECK-NEXT: [[R:%.*]] = and i8 [[S]], 321874; CHECK-NEXT: ret i8 [[R]]1875;1876 %s = lshr i8 63, %x ; 0b001111111877 %r = and i8 %s, 224 ; 0b111000001878 ret i8 %r1879}1880 1881define i8 @shl_mask_demand(i8 %x) {1882; CHECK-LABEL: @shl_mask_demand(1883; CHECK-NEXT: [[S:%.*]] = shl i8 12, [[X:%.*]]1884; CHECK-NEXT: [[R:%.*]] = and i8 [[S]], 41885; CHECK-NEXT: ret i8 [[R]]1886;1887 %s = shl i8 12, %x ; 0b000011001888 %r = and i8 %s, 7 ; 0b000001111889 ret i8 %r1890}1891 1892define i64 @lshr_mul_negpow2(i64 %x) {1893; CHECK-LABEL: @lshr_mul_negpow2(1894; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[X:%.*]]1895; CHECK-NEXT: [[A:%.*]] = and i64 [[TMP1]], 42949672951896; CHECK-NEXT: ret i64 [[A]]1897;1898 %a = mul i64 %x, -42949672961899 %b = lshr i64 %a, 321900 ret i64 %b1901}1902 1903define i64 @lshr_mul_negpow2_2(i64 %x) {1904; CHECK-LABEL: @lshr_mul_negpow2_2(1905; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[X:%.*]]1906; CHECK-NEXT: [[A:%.*]] = and i64 [[TMP1]], 2814749767106551907; CHECK-NEXT: ret i64 [[A]]1908;1909 %a = mul i64 %x, -655361910 %b = lshr i64 %a, 161911 ret i64 %b1912}1913 1914define <2 x i32> @lshr_mul_negpow2_3(<2 x i32> %x) {1915; CHECK-LABEL: @lshr_mul_negpow2_3(1916; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]]1917; CHECK-NEXT: [[A:%.*]] = and <2 x i32> [[TMP1]], splat (i32 255)1918; CHECK-NEXT: ret <2 x i32> [[A]]1919;1920 %a = mul <2 x i32> %x, <i32 -16777216, i32 -16777216>1921 %b = lshr <2 x i32> %a, <i32 24, i32 24>1922 ret <2 x i32> %b1923}1924 1925define i32 @lshr_mul_negpow2_4(i32 %x) {1926; CHECK-LABEL: @lshr_mul_negpow2_4(1927; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[X:%.*]]1928; CHECK-NEXT: [[A:%.*]] = and i32 [[TMP1]], 655351929; CHECK-NEXT: [[B:%.*]] = xor i32 [[A]], 11930; CHECK-NEXT: ret i32 [[B]]1931;1932 %a = mul i32 %x, -655361933 %b = xor i32 %a, 655361934 %c = lshr i32 %b, 161935 ret i32 %c1936}1937 1938define <2 x i32> @lshr_mul_negpow2_5(<2 x i32> %x) {1939; CHECK-LABEL: @lshr_mul_negpow2_5(1940; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]]1941; CHECK-NEXT: [[A:%.*]] = and <2 x i32> [[TMP1]], splat (i32 65527)1942; CHECK-NEXT: [[B:%.*]] = or disjoint <2 x i32> [[A]], splat (i32 8)1943; CHECK-NEXT: ret <2 x i32> [[B]]1944;1945 %a = mul <2 x i32> %x, <i32 -65536, i32 -65536>1946 %b = or <2 x i32> %a, <i32 524288, i32 524288>1947 %c = lshr <2 x i32> %b, <i32 16, i32 16>1948 ret <2 x i32> %c1949}1950 1951define i64 @lshr_mul_negpow2_extra_use(i64 %x) {1952; CHECK-LABEL: @lshr_mul_negpow2_extra_use(1953; CHECK-NEXT: [[A:%.*]] = mul i64 [[X:%.*]], -42949672961954; CHECK-NEXT: [[B:%.*]] = lshr exact i64 [[A]], 321955; CHECK-NEXT: call void @use(i64 [[A]])1956; CHECK-NEXT: ret i64 [[B]]1957;1958 %a = mul i64 %x, -42949672961959 %b = lshr i64 %a, 321960 call void @use(i64 %a)1961 ret i64 %b1962}1963 1964define i8 @ashr_sdiv_pos(i8 %x) {1965; CHECK-LABEL: @ashr_sdiv_pos(1966; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], -411967; CHECK-NEXT: [[R:%.*]] = sext i1 [[TMP1]] to i81968; CHECK-NEXT: ret i8 [[R]]1969;1970 %d = sdiv i8 %x, 421971 %r = ashr i8 %d, 71972 ret i8 %r1973}1974 1975define <2 x i8> @ashr_sdiv_neg_splat_vec(<2 x i8> %x) {1976; CHECK-LABEL: @ashr_sdiv_neg_splat_vec(1977; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 41)1978; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>1979; CHECK-NEXT: ret <2 x i8> [[R]]1980;1981 %d = sdiv <2 x i8> %x, <i8 -42, i8 -42>1982 %r = ashr <2 x i8> %d, <i8 7, i8 7>1983 ret <2 x i8> %r1984}1985 1986define <2 x i8> @ashr_sdiv_neg_splat_vec_poison(<2 x i8> %x) {1987; CHECK-LABEL: @ashr_sdiv_neg_splat_vec_poison(1988; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 127)1989; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>1990; CHECK-NEXT: ret <2 x i8> [[R]]1991;1992 %d = sdiv <2 x i8> %x, <i8 -127, i8 -127>1993 %r = ashr <2 x i8> %d, <i8 7, i8 poison>1994 ret <2 x i8> %r1995}1996 1997define i8 @lshr_sdiv_pos(i8 %x) {1998; CHECK-LABEL: @lshr_sdiv_pos(1999; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], -112000; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i82001; CHECK-NEXT: ret i8 [[R]]2002;2003 %d = sdiv i8 %x, 122004 %r = lshr i8 %d, 72005 ret i8 %r2006}2007 2008define i18 @lshr_sdiv_neg(i18 %x) {2009; CHECK-LABEL: @lshr_sdiv_neg(2010; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i18 [[X:%.*]], 112011; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i182012; CHECK-NEXT: ret i18 [[R]]2013;2014 %d = sdiv i18 %x, -122015 %r = lshr i18 %d, 172016 ret i18 %r2017}2018 2019; negative test2020 2021define i8 @ashr_sdiv_not_full_shift(i8 %x) {2022; CHECK-LABEL: @ashr_sdiv_not_full_shift(2023; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], 422024; CHECK-NEXT: [[R:%.*]] = ashr i8 [[D]], 62025; CHECK-NEXT: ret i8 [[R]]2026;2027 %d = sdiv i8 %x, 422028 %r = ashr i8 %d, 62029 ret i8 %r2030}2031 2032; negative test2033 2034define i32 @ashr_sdiv_extra_use(i32 %x) {2035; CHECK-LABEL: @ashr_sdiv_extra_use(2036; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 422037; CHECK-NEXT: call void @use_i32(i32 [[D]])2038; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], -412039; CHECK-NEXT: [[R:%.*]] = sext i1 [[TMP1]] to i322040; CHECK-NEXT: ret i32 [[R]]2041;2042 %d = sdiv i32 %x, 422043 call void @use_i32(i32 %d)2044 %r = ashr i32 %d, 312045 ret i32 %r2046}2047 2048define i32 @shl1_cttz(i32 %x) {2049; CHECK-LABEL: @shl1_cttz(2050; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]]2051; CHECK-NEXT: [[SHL:%.*]] = and i32 [[X]], [[NEG]]2052; CHECK-NEXT: ret i32 [[SHL]]2053;2054 %tz = call i32 @llvm.cttz.i32(i32 %x, i1 true)2055 %shl = shl i32 1, %tz2056 ret i32 %shl2057}2058 2059define <2 x i8> @shl1_cttz_vec(<2 x i8> %x) {2060; CHECK-LABEL: @shl1_cttz_vec(2061; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]]2062; CHECK-NEXT: [[SHL:%.*]] = and <2 x i8> [[X]], [[NEG]]2063; CHECK-NEXT: ret <2 x i8> [[SHL]]2064;2065 %tz = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %x, i1 false)2066 %shl = shl <2 x i8> <i8 1, i8 1>, %tz2067 ret <2 x i8> %shl2068}2069 2070define <2 x i8> @shl1_cttz_vec_poison(<2 x i8> %x) {2071; CHECK-LABEL: @shl1_cttz_vec_poison(2072; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]]2073; CHECK-NEXT: [[SHL:%.*]] = and <2 x i8> [[X]], [[NEG]]2074; CHECK-NEXT: ret <2 x i8> [[SHL]]2075;2076 %tz = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %x, i1 false)2077 %shl = shl <2 x i8> <i8 1, i8 poison>, %tz2078 ret <2 x i8> %shl2079}2080 2081; negative test - extra use2082 2083define i32 @shl1_cttz_extra_use(i32 %x) {2084; CHECK-LABEL: @shl1_cttz_extra_use(2085; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)2086; CHECK-NEXT: call void @use_i32(i32 [[TZ]])2087; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[TZ]]2088; CHECK-NEXT: ret i32 [[SHL]]2089;2090 %tz = call i32 @llvm.cttz.i32(i32 %x, i1 false)2091 call void @use_i32(i32 %tz)2092 %shl = shl i32 1, %tz2093 ret i32 %shl2094}2095 2096; negative test - must be shift-left of 12097 2098define i32 @shl2_cttz(i32 %x) {2099; CHECK-LABEL: @shl2_cttz(2100; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)2101; CHECK-NEXT: [[SHL:%.*]] = shl i32 2, [[TZ]]2102; CHECK-NEXT: ret i32 [[SHL]]2103;2104 %tz = call i32 @llvm.cttz.i32(i32 %x, i1 true)2105 %shl = shl i32 2, %tz2106 ret i32 %shl2107}2108 2109; shift (X, amt | bitwidth - 1) -> shift (X, bitwidth - 1)2110define i6 @shl_or7_eq_shl7(i6 %x, i6 %c) {2111; CHECK-LABEL: @shl_or7_eq_shl7(2112; CHECK-NEXT: [[Y:%.*]] = shl nsw i6 [[X:%.*]], 52113; CHECK-NEXT: ret i6 [[Y]]2114;2115 %amt = or i6 %c, 52116 ;; nsw not needed for transform, just check that we propagate.2117 %y = shl nsw i6 %x, %amt2118 ret i6 %y2119}2120 2121define <2 x i8> @lshr_vec_or7_eq_shl7(<2 x i8> %x, <2 x i8> %c) {2122; CHECK-LABEL: @lshr_vec_or7_eq_shl7(2123; CHECK-NEXT: [[Y:%.*]] = lshr exact <2 x i8> [[X:%.*]], splat (i8 7)2124; CHECK-NEXT: ret <2 x i8> [[Y]]2125;2126 %amt = or <2 x i8> %c, <i8 7, i8 7>2127 ;; exact not needed for transform, just check that we propagate.2128 %y = lshr exact <2 x i8> %x, %amt2129 ret <2 x i8> %y2130}2131 2132define <2 x i8> @ashr_vec_or7_eq_ashr7(<2 x i8> %x, <2 x i8> %c) {2133; CHECK-LABEL: @ashr_vec_or7_eq_ashr7(2134; CHECK-NEXT: [[Y:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 7)2135; CHECK-NEXT: ret <2 x i8> [[Y]]2136;2137 %amt = or <2 x i8> %c, <i8 7, i8 7>2138 %y = ashr <2 x i8> %x, %amt2139 ret <2 x i8> %y2140}2141 2142; Negative test not bitwidth - 12143define <2 x i8> @ashr_vec_or6_fail(<2 x i8> %x, <2 x i8> %c) {2144; CHECK-LABEL: @ashr_vec_or6_fail(2145; CHECK-NEXT: [[AMT:%.*]] = or <2 x i8> [[C:%.*]], splat (i8 6)2146; CHECK-NEXT: [[Y:%.*]] = ashr <2 x i8> [[X:%.*]], [[AMT]]2147; CHECK-NEXT: ret <2 x i8> [[Y]]2148;2149 %amt = or <2 x i8> %c, <i8 6, i8 6>2150 %y = ashr <2 x i8> %x, %amt2151 ret <2 x i8> %y2152}2153 2154define i16 @lshr_and_not_demanded(i8 %x) {2155; CHECK-LABEL: @lshr_and_not_demanded(2156; CHECK-NEXT: [[Y_EXT:%.*]] = sext i8 [[X:%.*]] to i162157; CHECK-NEXT: [[SHR:%.*]] = lshr i16 [[Y_EXT]], 12158; CHECK-NEXT: ret i16 [[SHR]]2159;2160 %y = and i8 %x, -22161 %y.ext = sext i8 %y to i162162 %shr = lshr i16 %y.ext, 12163 ret i16 %shr2164}2165 2166define i16 @lshr_exact_and_not_demanded(i8 %x) {2167; CHECK-LABEL: @lshr_exact_and_not_demanded(2168; CHECK-NEXT: [[Y_EXT:%.*]] = sext i8 [[X:%.*]] to i162169; CHECK-NEXT: [[SHR:%.*]] = lshr i16 [[Y_EXT]], 12170; CHECK-NEXT: ret i16 [[SHR]]2171;2172 %y = and i8 %x, -22173 %y.ext = sext i8 %y to i162174 %shr = lshr exact i16 %y.ext, 12175 ret i16 %shr2176}2177 2178define i16 @lshr_and_demanded(i8 %x) {2179; CHECK-LABEL: @lshr_and_demanded(2180; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -42181; CHECK-NEXT: [[Y_EXT:%.*]] = sext i8 [[Y]] to i162182; CHECK-NEXT: [[SHR:%.*]] = lshr exact i16 [[Y_EXT]], 12183; CHECK-NEXT: ret i16 [[SHR]]2184;2185 %y = and i8 %x, -42186 %y.ext = sext i8 %y to i162187 %shr = lshr i16 %y.ext, 12188 ret i16 %shr2189}2190 2191define i16 @ashr_umax_not_demanded(i16 %x) {2192; CHECK-LABEL: @ashr_umax_not_demanded(2193; CHECK-NEXT: [[SHR:%.*]] = ashr i16 [[X:%.*]], 12194; CHECK-NEXT: ret i16 [[SHR]]2195;2196 %y = call i16 @llvm.umax.i16(i16 %x, i16 1)2197 %shr = ashr i16 %y, 12198 ret i16 %shr2199}2200 2201define i16 @ashr_exact_umax_not_demanded(i16 %x) {2202; CHECK-LABEL: @ashr_exact_umax_not_demanded(2203; CHECK-NEXT: [[SHR:%.*]] = ashr i16 [[X:%.*]], 12204; CHECK-NEXT: ret i16 [[SHR]]2205;2206 %y = call i16 @llvm.umax.i16(i16 %x, i16 1)2207 %shr = ashr exact i16 %y, 12208 ret i16 %shr2209}2210 2211define i16 @ashr_umax_demanded(i16 %x) {2212; CHECK-LABEL: @ashr_umax_demanded(2213; CHECK-NEXT: [[Y:%.*]] = call i16 @llvm.umax.i16(i16 [[X:%.*]], i16 2)2214; CHECK-NEXT: [[SHR:%.*]] = ashr i16 [[Y]], 12215; CHECK-NEXT: ret i16 [[SHR]]2216;2217 %y = call i16 @llvm.umax.i16(i16 %x, i16 2)2218 %shr = ashr i16 %y, 12219 ret i16 %shr2220}2221 2222define i128 @shift_zext_nneg(i8 %arg) {2223; CHECK-LABEL: @shift_zext_nneg(2224; CHECK-NEXT: [[EXT:%.*]] = zext nneg i8 [[ARG:%.*]] to i1282225; CHECK-NEXT: [[SHL:%.*]] = shl nuw i128 1, [[EXT]]2226; CHECK-NEXT: ret i128 [[SHL]]2227;2228 %ext = zext i8 %arg to i1282229 %shl = shl i128 1, %ext2230 ret i128 %shl2231}2232 2233define i129 @shift_zext_not_nneg(i8 %arg) {2234; CHECK-LABEL: @shift_zext_not_nneg(2235; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[ARG:%.*]] to i1292236; CHECK-NEXT: [[SHL:%.*]] = shl nuw i129 1, [[EXT]]2237; CHECK-NEXT: ret i129 [[SHL]]2238;2239 %ext = zext i8 %arg to i1292240 %shl = shl i129 1, %ext2241 ret i129 %shl2242}2243 2244define i8 @src_shl_nsw(i8 %x) {2245; CHECK-LABEL: @src_shl_nsw(2246; CHECK-NEXT: [[R:%.*]] = shl nsw i8 32, [[X:%.*]]2247; CHECK-NEXT: ret i8 [[R]]2248;2249 %sh = shl nsw i8 1, %x2250 %r = shl nsw i8 %sh, 52251 ret i8 %r2252}2253 2254define i8 @src_shl_nsw_fail(i8 %x) {2255; CHECK-LABEL: @src_shl_nsw_fail(2256; CHECK-NEXT: [[R:%.*]] = shl i8 32, [[X:%.*]]2257; CHECK-NEXT: ret i8 [[R]]2258;2259 %sh = shl nsw i8 1, %x2260 %r = shl i8 %sh, 52261 ret i8 %r2262}2263 2264define i8 @src_shl_nuw(i8 %x) {2265; CHECK-LABEL: @src_shl_nuw(2266; CHECK-NEXT: [[R:%.*]] = shl nuw i8 12, [[X:%.*]]2267; CHECK-NEXT: ret i8 [[R]]2268;2269 %sh = shl nuw i8 3, %x2270 %r = shl nuw i8 %sh, 22271 ret i8 %r2272}2273 2274define i8 @src_shl_nuw_fail(i8 %x) {2275; CHECK-LABEL: @src_shl_nuw_fail(2276; CHECK-NEXT: [[R:%.*]] = shl i8 12, [[X:%.*]]2277; CHECK-NEXT: ret i8 [[R]]2278;2279 %sh = shl i8 3, %x2280 %r = shl nuw i8 %sh, 22281 ret i8 %r2282}2283 2284define i8 @src_lshr_exact(i8 %x) {2285; CHECK-LABEL: @src_lshr_exact(2286; CHECK-NEXT: [[R:%.*]] = lshr exact i8 48, [[X:%.*]]2287; CHECK-NEXT: ret i8 [[R]]2288;2289 %sh = lshr exact i8 96, %x2290 %r = lshr exact i8 %sh, 12291 ret i8 %r2292}2293 2294define i8 @src_lshr_exact_fail(i8 %x) {2295; CHECK-LABEL: @src_lshr_exact_fail(2296; CHECK-NEXT: [[R:%.*]] = lshr i8 48, [[X:%.*]]2297; CHECK-NEXT: ret i8 [[R]]2298;2299 %sh = lshr exact i8 96, %x2300 %r = lshr i8 %sh, 12301 ret i8 %r2302}2303 2304define i8 @src_ashr_exact(i8 %x) {2305; CHECK-LABEL: @src_ashr_exact(2306; CHECK-NEXT: [[R:%.*]] = ashr exact i8 -8, [[X:%.*]]2307; CHECK-NEXT: ret i8 [[R]]2308;2309 %sh = ashr exact i8 -32, %x2310 %r = ashr exact i8 %sh, 22311 ret i8 %r2312}2313 2314define i8 @src_ashr_exact_fail(i8 %x) {2315; CHECK-LABEL: @src_ashr_exact_fail(2316; CHECK-NEXT: [[R:%.*]] = ashr i8 -8, [[X:%.*]]2317; CHECK-NEXT: ret i8 [[R]]2318;2319 %sh = ashr i8 -32, %x2320 %r = ashr exact i8 %sh, 22321 ret i8 %r2322}2323 2324declare i16 @llvm.umax.i16(i16, i16)2325