brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.5 KiB · db0ecbf Raw
1225 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define i32 @ashr_lshr_exact_ashr_only(i32 %x, i32 %y) {5; CHECK-LABEL: @ashr_lshr_exact_ashr_only(6; CHECK-NEXT:    [[CMP12:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]7; CHECK-NEXT:    ret i32 [[CMP12]]8;9  %cmp = icmp sgt i32 %x, -110  %l = lshr i32 %x, %y11  %r = ashr exact i32 %x, %y12  %ret = select i1 %cmp, i32 %l, i32 %r13  ret i32 %ret14}15 16define i32 @ashr_lshr_no_exact(i32 %x, i32 %y) {17; CHECK-LABEL: @ashr_lshr_no_exact(18; CHECK-NEXT:    [[CMP12:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]19; CHECK-NEXT:    ret i32 [[CMP12]]20;21  %cmp = icmp sgt i32 %x, -122  %l = lshr i32 %x, %y23  %r = ashr i32 %x, %y24  %ret = select i1 %cmp, i32 %l, i32 %r25  ret i32 %ret26}27 28define i32 @ashr_lshr_exact_both(i32 %x, i32 %y) {29; CHECK-LABEL: @ashr_lshr_exact_both(30; CHECK-NEXT:    [[CMP12:%.*]] = ashr exact i32 [[X:%.*]], [[Y:%.*]]31; CHECK-NEXT:    ret i32 [[CMP12]]32;33  %cmp = icmp sgt i32 %x, -134  %l = lshr exact i32 %x, %y35  %r = ashr exact i32 %x, %y36  %ret = select i1 %cmp, i32 %l, i32 %r37  ret i32 %ret38}39 40define i32 @ashr_lshr_exact_lshr_only(i32 %x, i32 %y) {41; CHECK-LABEL: @ashr_lshr_exact_lshr_only(42; CHECK-NEXT:    [[CMP12:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]43; CHECK-NEXT:    ret i32 [[CMP12]]44;45  %cmp = icmp sgt i32 %x, -146  %l = lshr exact i32 %x, %y47  %r = ashr i32 %x, %y48  %ret = select i1 %cmp, i32 %l, i32 %r49  ret i32 %ret50}51 52define i32 @ashr_lshr2(i32 %x, i32 %y) {53; CHECK-LABEL: @ashr_lshr2(54; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]55; CHECK-NEXT:    ret i32 [[CMP1]]56;57  %cmp = icmp sgt i32 %x, 558  %l = lshr i32 %x, %y59  %r = ashr exact i32 %x, %y60  %ret = select i1 %cmp, i32 %l, i32 %r61  ret i32 %ret62}63 64define i128 @ashr_lshr2_i128(i128 %x, i128 %y) {65; CHECK-LABEL: @ashr_lshr2_i128(66; CHECK-NEXT:    [[CMP1:%.*]] = ashr i128 [[X:%.*]], [[Y:%.*]]67; CHECK-NEXT:    ret i128 [[CMP1]]68;69  %cmp = icmp sgt i128 %x, 570  %l = lshr i128 %x, %y71  %r = ashr exact i128 %x, %y72  %ret = select i1 %cmp, i128 %l, i128 %r73  ret i128 %ret74}75 76define <2 x i32> @ashr_lshr_splat_vec(<2 x i32> %x, <2 x i32> %y) {77; CHECK-LABEL: @ashr_lshr_splat_vec(78; CHECK-NEXT:    [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]79; CHECK-NEXT:    ret <2 x i32> [[CMP12]]80;81  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>82  %l = lshr <2 x i32> %x, %y83  %r = ashr <2 x i32> %x, %y84  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r85  ret <2 x i32> %ret86}87 88define <2 x i32> @ashr_lshr_splat_vec2(<2 x i32> %x, <2 x i32> %y) {89; CHECK-LABEL: @ashr_lshr_splat_vec2(90; CHECK-NEXT:    [[CMP12:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]]91; CHECK-NEXT:    ret <2 x i32> [[CMP12]]92;93  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>94  %l = lshr exact <2 x i32> %x, %y95  %r = ashr exact <2 x i32> %x, %y96  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r97  ret <2 x i32> %ret98}99 100define <2 x i32> @ashr_lshr_splat_vec3(<2 x i32> %x, <2 x i32> %y) {101; CHECK-LABEL: @ashr_lshr_splat_vec3(102; CHECK-NEXT:    [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]103; CHECK-NEXT:    ret <2 x i32> [[CMP12]]104;105  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>106  %l = lshr exact <2 x i32> %x, %y107  %r = ashr <2 x i32> %x, %y108  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r109  ret <2 x i32> %ret110}111 112define <2 x i32> @ashr_lshr_splat_vec4(<2 x i32> %x, <2 x i32> %y) {113; CHECK-LABEL: @ashr_lshr_splat_vec4(114; CHECK-NEXT:    [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]115; CHECK-NEXT:    ret <2 x i32> [[CMP12]]116;117  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>118  %l = lshr <2 x i32> %x, %y119  %r = ashr exact <2 x i32> %x, %y120  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r121  ret <2 x i32> %ret122}123 124define <2 x i32> @ashr_lshr_nonsplat_vec(<2 x i32> %x, <2 x i32> %y) {125; CHECK-LABEL: @ashr_lshr_nonsplat_vec(126; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]127; CHECK-NEXT:    ret <2 x i32> [[CMP1]]128;129  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 1>130  %l = lshr <2 x i32> %x, %y131  %r = ashr <2 x i32> %x, %y132  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r133  ret <2 x i32> %ret134}135 136define <2 x i32> @ashr_lshr_nonsplat_vec2(<2 x i32> %x, <2 x i32> %y) {137; CHECK-LABEL: @ashr_lshr_nonsplat_vec2(138; CHECK-NEXT:    [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]]139; CHECK-NEXT:    ret <2 x i32> [[CMP1]]140;141  %cmp = icmp sgt <2 x i32> %x, <i32 2, i32 4>142  %l = lshr exact <2 x i32> %x, %y143  %r = ashr exact <2 x i32> %x, %y144  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r145  ret <2 x i32> %ret146}147 148define <2 x i32> @ashr_lshr_nonsplat_vec3(<2 x i32> %x, <2 x i32> %y) {149; CHECK-LABEL: @ashr_lshr_nonsplat_vec3(150; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]151; CHECK-NEXT:    ret <2 x i32> [[CMP1]]152;153  %cmp = icmp sgt <2 x i32> %x, <i32 5, i32 6>154  %l = lshr exact <2 x i32> %x, %y155  %r = ashr <2 x i32> %x, %y156  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r157  ret <2 x i32> %ret158}159 160define <2 x i32> @ashr_lshr_nonsplat_vec4(<2 x i32> %x, <2 x i32> %y) {161; CHECK-LABEL: @ashr_lshr_nonsplat_vec4(162; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]163; CHECK-NEXT:    ret <2 x i32> [[CMP1]]164;165  %cmp = icmp sgt <2 x i32> %x, <i32 8, i32 7>166  %l = lshr <2 x i32> %x, %y167  %r = ashr exact <2 x i32> %x, %y168  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r169  ret <2 x i32> %ret170}171 172define i32 @ashr_lshr_cst(i32 %x, i32 %y) {173; CHECK-LABEL: @ashr_lshr_cst(174; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], 8175; CHECK-NEXT:    ret i32 [[CMP1]]176;177  %cmp = icmp slt i32 %x, 1178  %l = lshr i32 %x, 8179  %r = ashr exact i32 %x, 8180  %ret = select i1 %cmp, i32 %r, i32 %l181  ret i32 %ret182}183 184define i32 @ashr_lshr_cst2(i32 %x, i32 %y) {185; CHECK-LABEL: @ashr_lshr_cst2(186; CHECK-NEXT:    [[CMP12:%.*]] = ashr i32 [[X:%.*]], 8187; CHECK-NEXT:    ret i32 [[CMP12]]188;189  %cmp = icmp sgt i32 %x, -1190  %l = lshr i32 %x, 8191  %r = ashr exact i32 %x, 8192  %ret = select i1 %cmp, i32 %l, i32 %r193  ret i32 %ret194}195 196define i32 @ashr_lshr_inv(i32 %x, i32 %y) {197; CHECK-LABEL: @ashr_lshr_inv(198; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]199; CHECK-NEXT:    ret i32 [[CMP1]]200;201  %cmp = icmp slt i32 %x, 1202  %l = lshr i32 %x, %y203  %r = ashr exact i32 %x, %y204  %ret = select i1 %cmp, i32 %r, i32 %l205  ret i32 %ret206}207 208define i32 @ashr_lshr_inv2(i32 %x, i32 %y) {209; CHECK-LABEL: @ashr_lshr_inv2(210; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]211; CHECK-NEXT:    ret i32 [[CMP1]]212;213  %cmp = icmp slt i32 %x, 7214  %l = lshr i32 %x, %y215  %r = ashr exact i32 %x, %y216  %ret = select i1 %cmp, i32 %r, i32 %l217  ret i32 %ret218}219 220define <2 x i32> @ashr_lshr_inv_splat_vec(<2 x i32> %x, <2 x i32> %y) {221; CHECK-LABEL: @ashr_lshr_inv_splat_vec(222; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]223; CHECK-NEXT:    ret <2 x i32> [[CMP1]]224;225  %cmp = icmp slt <2 x i32> %x, <i32 1, i32 1>226  %l = lshr <2 x i32> %x, %y227  %r = ashr exact <2 x i32> %x, %y228  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l229  ret <2 x i32> %ret230}231 232define <2 x i32> @ashr_lshr_inv_nonsplat_vec(<2 x i32> %x, <2 x i32> %y) {233; CHECK-LABEL: @ashr_lshr_inv_nonsplat_vec(234; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]235; CHECK-NEXT:    ret <2 x i32> [[CMP1]]236;237  %cmp = icmp slt <2 x i32> %x, <i32 4, i32 5>238  %l = lshr <2 x i32> %x, %y239  %r = ashr exact <2 x i32> %x, %y240  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l241  ret <2 x i32> %ret242}243 244define <2 x i32> @ashr_lshr_vec_poison(<2 x i32> %x, <2 x i32> %y) {245; CHECK-LABEL: @ashr_lshr_vec_poison(246; CHECK-NEXT:    [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]247; CHECK-NEXT:    ret <2 x i32> [[CMP12]]248;249  %cmp = icmp sgt <2 x i32> %x, <i32 poison, i32 -1>250  %l = lshr <2 x i32> %x, %y251  %r = ashr exact <2 x i32> %x, %y252  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r253  ret <2 x i32> %ret254}255 256define <2 x i32> @ashr_lshr_vec_poison2(<2 x i32> %x, <2 x i32> %y) {257; CHECK-LABEL: @ashr_lshr_vec_poison2(258; CHECK-NEXT:    [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]]259; CHECK-NEXT:    ret <2 x i32> [[CMP1]]260;261  %cmp = icmp slt <2 x i32> %x, <i32 1, i32 poison>262  %l = lshr exact <2 x i32> %x, %y263  %r = ashr exact <2 x i32> %x, %y264  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l265  ret <2 x i32> %ret266}267 268; Negative tests269 270define i32 @ashr_lshr_wrong_cst(i32 %x, i32 %y) {271; CHECK-LABEL: @ashr_lshr_wrong_cst(272; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -2273; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]274; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[X]], [[Y]]275; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]276; CHECK-NEXT:    ret i32 [[RET]]277;278  %cmp = icmp sgt i32 %x, -2279  %l = lshr i32 %x, %y280  %r = ashr exact i32 %x, %y281  %ret = select i1 %cmp, i32 %l, i32 %r282  ret i32 %ret283}284 285define i32 @ashr_lshr_wrong_cst2(i32 %x, i32 %y) {286; CHECK-LABEL: @ashr_lshr_wrong_cst2(287; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], -1288; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]289; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[X]], [[Y]]290; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[R]], i32 [[L]]291; CHECK-NEXT:    ret i32 [[RET]]292;293  %cmp = icmp slt i32 %x, -1294  %l = lshr i32 %x, %y295  %r = ashr exact i32 %x, %y296  %ret = select i1 %cmp, i32 %r, i32 %l297  ret i32 %ret298}299 300define i32 @ashr_lshr_wrong_cond(i32 %x, i32 %y) {301; CHECK-LABEL: @ashr_lshr_wrong_cond(302; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -2303; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]304; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]305; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]306; CHECK-NEXT:    ret i32 [[RET]]307;308  %cmp = icmp sge i32 %x, -1309  %l = lshr i32 %x, %y310  %r = ashr i32 %x, %y311  %ret = select i1 %cmp, i32 %l, i32 %r312  ret i32 %ret313}314 315define i32 @ashr_lshr_shift_wrong_pred(i32 %x, i32 %y, i32 %z) {316; CHECK-LABEL: @ashr_lshr_shift_wrong_pred(317; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1318; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]319; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]320; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]321; CHECK-NEXT:    ret i32 [[RET]]322;323  %cmp = icmp sle i32 %x, 0324  %l = lshr i32 %x, %y325  %r = ashr i32 %x, %y326  %ret = select i1 %cmp, i32 %l, i32 %r327  ret i32 %ret328}329 330define i32 @ashr_lshr_shift_wrong_pred2(i32 %x, i32 %y, i32 %z) {331; CHECK-LABEL: @ashr_lshr_shift_wrong_pred2(332; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]333; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]334; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[Z:%.*]], 0335; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]]336; CHECK-NEXT:    ret i32 [[RET]]337;338  %cmp = icmp sge i32 %z, 0339  %l = lshr i32 %x, %y340  %r = ashr i32 %x, %y341  %ret = select i1 %cmp, i32 %l, i32 %r342  ret i32 %ret343}344 345define i32 @ashr_lshr_wrong_operands(i32 %x, i32 %y) {346; CHECK-LABEL: @ashr_lshr_wrong_operands(347; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]348; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]349; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 0350; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[L]], i32 [[R]]351; CHECK-NEXT:    ret i32 [[RET]]352;353  %cmp = icmp sge i32 %x, 0354  %l = lshr i32 %x, %y355  %r = ashr i32 %x, %y356  %ret = select i1 %cmp, i32 %r, i32 %l357  ret i32 %ret358}359 360define i32 @ashr_lshr_no_ashr(i32 %x, i32 %y) {361; CHECK-LABEL: @ashr_lshr_no_ashr(362; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]363; CHECK-NEXT:    [[R:%.*]] = xor i32 [[X]], [[Y]]364; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 0365; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]]366; CHECK-NEXT:    ret i32 [[RET]]367;368  %cmp = icmp sge i32 %x, 0369  %l = lshr i32 %x, %y370  %r = xor i32 %x, %y371  %ret = select i1 %cmp, i32 %l, i32 %r372  ret i32 %ret373}374 375define i32 @ashr_lshr_shift_amt_mismatch(i32 %x, i32 %y, i32 %z) {376; CHECK-LABEL: @ashr_lshr_shift_amt_mismatch(377; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]378; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Z:%.*]]379; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 0380; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]]381; CHECK-NEXT:    ret i32 [[RET]]382;383  %cmp = icmp sge i32 %x, 0384  %l = lshr i32 %x, %y385  %r = ashr i32 %x, %z386  %ret = select i1 %cmp, i32 %l, i32 %r387  ret i32 %ret388}389 390define i32 @ashr_lshr_shift_base_mismatch(i32 %x, i32 %y, i32 %z) {391; CHECK-LABEL: @ashr_lshr_shift_base_mismatch(392; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]393; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[Z:%.*]], [[Y]]394; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 0395; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]]396; CHECK-NEXT:    ret i32 [[RET]]397;398  %cmp = icmp sge i32 %x, 0399  %l = lshr i32 %x, %y400  %r = ashr i32 %z, %y401  %ret = select i1 %cmp, i32 %l, i32 %r402  ret i32 %ret403}404 405define i32 @ashr_lshr_no_lshr(i32 %x, i32 %y) {406; CHECK-LABEL: @ashr_lshr_no_lshr(407; CHECK-NEXT:    [[L:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]408; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]409; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 0410; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]]411; CHECK-NEXT:    ret i32 [[RET]]412;413  %cmp = icmp sge i32 %x, 0414  %l = add i32 %x, %y415  %r = ashr i32 %x, %y416  %ret = select i1 %cmp, i32 %l, i32 %r417  ret i32 %ret418}419 420define <2 x i32> @ashr_lshr_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) {421; CHECK-LABEL: @ashr_lshr_vec_wrong_pred(422; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], splat (i32 1)423; CHECK-NEXT:    [[L:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]424; CHECK-NEXT:    [[R:%.*]] = ashr <2 x i32> [[X]], [[Y]]425; CHECK-NEXT:    [[RET:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[L]], <2 x i32> [[R]]426; CHECK-NEXT:    ret <2 x i32> [[RET]]427;428  %cmp = icmp sle <2 x i32> %x, zeroinitializer429  %l = lshr <2 x i32> %x, %y430  %r = ashr <2 x i32> %x, %y431  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r432  ret <2 x i32> %ret433}434 435define <2 x i32> @ashr_lshr_inv_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) {436; CHECK-LABEL: @ashr_lshr_inv_vec_wrong_pred(437; CHECK-NEXT:    [[L:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]]438; CHECK-NEXT:    [[R:%.*]] = ashr <2 x i32> [[X]], [[Y]]439; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer440; CHECK-NEXT:    [[RET:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> [[L]], <2 x i32> [[R]]441; CHECK-NEXT:    ret <2 x i32> [[RET]]442;443  %cmp = icmp sge <2 x i32> %x, zeroinitializer444  %l = lshr <2 x i32> %x, %y445  %r = ashr <2 x i32> %x, %y446  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l447  ret <2 x i32> %ret448}449 450define i32 @lshr_sub_nsw(i32 %x, i32 %y) {451; CHECK-LABEL: @lshr_sub_nsw(452; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]453; CHECK-NEXT:    [[SHR:%.*]] = zext i1 [[TMP1]] to i32454; CHECK-NEXT:    ret i32 [[SHR]]455;456  %sub = sub nsw i32 %x, %y457  %shr = lshr i32 %sub, 31458  ret i32 %shr459}460 461; negative test - must shift sign-bit462 463define i32 @lshr_sub_wrong_amount(i32 %x, i32 %y) {464; CHECK-LABEL: @lshr_sub_wrong_amount(465; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]466; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[SUB]], 30467; CHECK-NEXT:    ret i32 [[SHR]]468;469  %sub = sub nsw i32 %x, %y470  %shr = lshr i32 %sub, 30471  ret i32 %shr472}473 474; negative test - must have nsw475 476define i32 @lshr_sub(i32 %x, i32 %y) {477; CHECK-LABEL: @lshr_sub(478; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]479; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[SUB]], 31480; CHECK-NEXT:    ret i32 [[SHR]]481;482  %sub = sub i32 %x, %y483  %shr = lshr i32 %sub, 31484  ret i32 %shr485}486 487; negative test - one-use488 489define i32 @lshr_sub_nsw_extra_use(i32 %x, i32 %y, ptr %p) {490; CHECK-LABEL: @lshr_sub_nsw_extra_use(491; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]492; CHECK-NEXT:    store i32 [[SUB]], ptr [[P:%.*]], align 4493; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[SUB]], 31494; CHECK-NEXT:    ret i32 [[SHR]]495;496  %sub = sub nsw i32 %x, %y497  store i32 %sub, ptr %p498  %shr = lshr i32 %sub, 31499  ret i32 %shr500}501 502define <3 x i42> @lshr_sub_nsw_splat(<3 x i42> %x, <3 x i42> %y) {503; CHECK-LABEL: @lshr_sub_nsw_splat(504; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <3 x i42> [[X:%.*]], [[Y:%.*]]505; CHECK-NEXT:    [[SHR:%.*]] = zext <3 x i1> [[TMP1]] to <3 x i42>506; CHECK-NEXT:    ret <3 x i42> [[SHR]]507;508  %sub = sub nsw <3 x i42> %x, %y509  %shr = lshr <3 x i42> %sub, <i42 41, i42 41, i42 41>510  ret <3 x i42> %shr511}512 513define <3 x i42> @lshr_sub_nsw_splat_poison(<3 x i42> %x, <3 x i42> %y) {514; CHECK-LABEL: @lshr_sub_nsw_splat_poison(515; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <3 x i42> [[X:%.*]], [[Y:%.*]]516; CHECK-NEXT:    [[SHR:%.*]] = lshr <3 x i42> [[SUB]], <i42 41, i42 poison, i42 41>517; CHECK-NEXT:    ret <3 x i42> [[SHR]]518;519  %sub = sub nsw <3 x i42> %x, %y520  %shr = lshr <3 x i42> %sub, <i42 41, i42 poison, i42 41>521  ret <3 x i42> %shr522}523 524define i17 @ashr_sub_nsw(i17 %x, i17 %y) {525; CHECK-LABEL: @ashr_sub_nsw(526; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i17 [[X:%.*]], [[Y:%.*]]527; CHECK-NEXT:    [[SHR:%.*]] = sext i1 [[TMP1]] to i17528; CHECK-NEXT:    ret i17 [[SHR]]529;530  %sub = sub nsw i17 %x, %y531  %shr = ashr i17 %sub, 16532  ret i17 %shr533}534 535; negative test - must shift sign-bit536 537define i17 @ashr_sub_wrong_amount(i17 %x, i17 %y) {538; CHECK-LABEL: @ashr_sub_wrong_amount(539; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i17 [[X:%.*]], [[Y:%.*]]540; CHECK-NEXT:    [[SHR:%.*]] = ashr i17 [[SUB]], 15541; CHECK-NEXT:    ret i17 [[SHR]]542;543  %sub = sub nsw i17 %x, %y544  %shr = ashr i17 %sub, 15545  ret i17 %shr546}547 548; negative test - must have nsw549 550define i32 @ashr_sub(i32 %x, i32 %y) {551; CHECK-LABEL: @ashr_sub(552; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]553; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[SUB]], 31554; CHECK-NEXT:    ret i32 [[SHR]]555;556  %sub = sub i32 %x, %y557  %shr = ashr i32 %sub, 31558  ret i32 %shr559}560 561; negative test - one-use562 563define i32 @ashr_sub_nsw_extra_use(i32 %x, i32 %y, ptr %p) {564; CHECK-LABEL: @ashr_sub_nsw_extra_use(565; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]566; CHECK-NEXT:    store i32 [[SUB]], ptr [[P:%.*]], align 4567; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[SUB]], 31568; CHECK-NEXT:    ret i32 [[SHR]]569;570  %sub = sub nsw i32 %x, %y571  store i32 %sub, ptr %p572  %shr = ashr i32 %sub, 31573  ret i32 %shr574}575 576define <3 x i43> @ashr_sub_nsw_splat(<3 x i43> %x, <3 x i43> %y) {577; CHECK-LABEL: @ashr_sub_nsw_splat(578; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <3 x i43> [[X:%.*]], [[Y:%.*]]579; CHECK-NEXT:    [[SHR:%.*]] = sext <3 x i1> [[TMP1]] to <3 x i43>580; CHECK-NEXT:    ret <3 x i43> [[SHR]]581;582  %sub = sub nsw <3 x i43> %x, %y583  %shr = ashr <3 x i43> %sub, <i43 42, i43 42, i43 42>584  ret <3 x i43> %shr585}586 587define <3 x i43> @ashr_sub_nsw_splat_poison(<3 x i43> %x, <3 x i43> %y) {588; CHECK-LABEL: @ashr_sub_nsw_splat_poison(589; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <3 x i43> [[X:%.*]], [[Y:%.*]]590; CHECK-NEXT:    [[SHR:%.*]] = ashr <3 x i43> [[SUB]], <i43 42, i43 poison, i43 42>591; CHECK-NEXT:    ret <3 x i43> [[SHR]]592;593  %sub = sub nsw <3 x i43> %x, %y594  %shr = ashr <3 x i43> %sub, <i43 42, i43 poison, i43 42>595  ret <3 x i43> %shr596}597 598define i8 @ashr_known_pos_exact(i8 %x, i8 %y) {599; CHECK-LABEL: @ashr_known_pos_exact(600; CHECK-NEXT:    [[P:%.*]] = and i8 [[X:%.*]], 127601; CHECK-NEXT:    [[R:%.*]] = lshr exact i8 [[P]], [[Y:%.*]]602; CHECK-NEXT:    ret i8 [[R]]603;604  %p = and i8 %x, 127605  %r = ashr exact i8 %p, %y606  ret i8 %r607}608 609define <2 x i8> @ashr_known_pos_exact_vec(<2 x i8> %x, <2 x i8> %y) {610; CHECK-LABEL: @ashr_known_pos_exact_vec(611; CHECK-NEXT:    [[P:%.*]] = mul nsw <2 x i8> [[X:%.*]], [[X]]612; CHECK-NEXT:    [[R:%.*]] = lshr exact <2 x i8> [[P]], [[Y:%.*]]613; CHECK-NEXT:    ret <2 x i8> [[R]]614;615  %p = mul nsw <2 x i8> %x, %x616  %r = ashr exact <2 x i8> %p, %y617  ret <2 x i8> %r618}619 620define i32 @lshr_mul_times_3_div_2(i32 %0) {621; CHECK-LABEL: @lshr_mul_times_3_div_2(622; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 1623; CHECK-NEXT:    [[LSHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]]624; CHECK-NEXT:    ret i32 [[LSHR]]625;626  %mul = mul nsw nuw i32 %0, 3627  %lshr = lshr i32 %mul, 1628  ret i32 %lshr629}630 631define i32 @lshr_mul_times_3_div_2_exact(i32 %x) {632; CHECK-LABEL: @lshr_mul_times_3_div_2_exact(633; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 1634; CHECK-NEXT:    [[LSHR:%.*]] = add nsw i32 [[X]], [[TMP1]]635; CHECK-NEXT:    ret i32 [[LSHR]]636;637  %mul = mul nsw i32 %x, 3638  %lshr = lshr exact i32 %mul, 1639  ret i32 %lshr640}641 642; Negative test643 644define i32 @lshr_mul_times_3_div_2_no_flags(i32 %0) {645; CHECK-LABEL: @lshr_mul_times_3_div_2_no_flags(646; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 3647; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 [[MUL]], 1648; CHECK-NEXT:    ret i32 [[LSHR]]649;650  %mul = mul i32 %0, 3651  %lshr = lshr i32 %mul, 1652  ret i32 %lshr653}654 655; Negative test656 657define i32 @mul_times_3_div_2_multiuse_lshr(i32 %x) {658; CHECK-LABEL: @mul_times_3_div_2_multiuse_lshr(659; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 3660; CHECK-NEXT:    [[RES:%.*]] = lshr i32 [[MUL]], 1661; CHECK-NEXT:    call void @use(i32 [[MUL]])662; CHECK-NEXT:    ret i32 [[RES]]663;664  %mul = mul nuw i32 %x, 3665  %res = lshr i32 %mul, 1666  call void @use(i32 %mul)667  ret i32 %res668}669 670define i32 @lshr_mul_times_3_div_2_exact_2(i32 %x) {671; CHECK-LABEL: @lshr_mul_times_3_div_2_exact_2(672; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 1673; CHECK-NEXT:    [[LSHR:%.*]] = add nuw i32 [[X]], [[TMP1]]674; CHECK-NEXT:    ret i32 [[LSHR]]675;676  %mul = mul nuw i32 %x, 3677  %lshr = lshr exact i32 %mul, 1678  ret i32 %lshr679}680 681define i32 @lshr_mul_times_5_div_4(i32 %0) {682; CHECK-LABEL: @lshr_mul_times_5_div_4(683; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 2684; CHECK-NEXT:    [[LSHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]]685; CHECK-NEXT:    ret i32 [[LSHR]]686;687  %mul = mul nsw nuw i32 %0, 5688  %lshr = lshr i32 %mul, 2689  ret i32 %lshr690}691 692define i32 @lshr_mul_times_5_div_4_exact(i32 %x) {693; CHECK-LABEL: @lshr_mul_times_5_div_4_exact(694; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 2695; CHECK-NEXT:    [[LSHR:%.*]] = add nsw i32 [[X]], [[TMP1]]696; CHECK-NEXT:    ret i32 [[LSHR]]697;698  %mul = mul nsw i32 %x, 5699  %lshr = lshr exact i32 %mul, 2700  ret i32 %lshr701}702 703; Negative test704 705define i32 @lshr_mul_times_5_div_4_no_flags(i32 %0) {706; CHECK-LABEL: @lshr_mul_times_5_div_4_no_flags(707; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 5708; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 [[MUL]], 2709; CHECK-NEXT:    ret i32 [[LSHR]]710;711  %mul = mul i32 %0, 5712  %lshr = lshr i32 %mul, 2713  ret i32 %lshr714}715 716; Negative test717 718define i32 @mul_times_5_div_4_multiuse_lshr(i32 %x) {719; CHECK-LABEL: @mul_times_5_div_4_multiuse_lshr(720; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 5721; CHECK-NEXT:    [[RES:%.*]] = lshr i32 [[MUL]], 2722; CHECK-NEXT:    call void @use(i32 [[MUL]])723; CHECK-NEXT:    ret i32 [[RES]]724;725  %mul = mul nuw i32 %x, 5726  %res = lshr i32 %mul, 2727  call void @use(i32 %mul)728  ret i32 %res729}730 731define i32 @lshr_mul_times_5_div_4_exact_2(i32 %x) {732; CHECK-LABEL: @lshr_mul_times_5_div_4_exact_2(733; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 2734; CHECK-NEXT:    [[LSHR:%.*]] = add nuw i32 [[X]], [[TMP1]]735; CHECK-NEXT:    ret i32 [[LSHR]]736;737  %mul = mul nuw i32 %x, 5738  %lshr = lshr exact i32 %mul, 2739  ret i32 %lshr740}741 742define i32 @ashr_mul_times_3_div_2(i32 %0) {743; CHECK-LABEL: @ashr_mul_times_3_div_2(744; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 1745; CHECK-NEXT:    [[ASHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]]746; CHECK-NEXT:    ret i32 [[ASHR]]747;748  %mul = mul nuw nsw i32 %0, 3749  %ashr = ashr i32 %mul, 1750  ret i32 %ashr751}752 753define i32 @ashr_mul_times_3_div_2_exact(i32 %x) {754; CHECK-LABEL: @ashr_mul_times_3_div_2_exact(755; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 1756; CHECK-NEXT:    [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]]757; CHECK-NEXT:    ret i32 [[ASHR]]758;759  %mul = mul nsw i32 %x, 3760  %ashr = ashr exact i32 %mul, 1761  ret i32 %ashr762}763 764; Negative test765 766define i32 @ashr_mul_times_3_div_2_no_flags(i32 %0) {767; CHECK-LABEL: @ashr_mul_times_3_div_2_no_flags(768; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 3769; CHECK-NEXT:    [[ASHR:%.*]] = ashr i32 [[MUL]], 1770; CHECK-NEXT:    ret i32 [[ASHR]]771;772  %mul = mul i32 %0, 3773  %ashr = ashr i32 %mul, 1774  ret i32 %ashr775}776 777; Negative test778 779define i32 @ashr_mul_times_3_div_2_no_nsw(i32 %0) {780; CHECK-LABEL: @ashr_mul_times_3_div_2_no_nsw(781; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[TMP0:%.*]], 3782; CHECK-NEXT:    [[ASHR:%.*]] = ashr i32 [[MUL]], 1783; CHECK-NEXT:    ret i32 [[ASHR]]784;785  %mul = mul nuw i32 %0, 3786  %ashr = ashr i32 %mul, 1787  ret i32 %ashr788}789 790; Negative test791 792define i32 @mul_times_3_div_2_multiuse_ashr(i32 %x) {793; CHECK-LABEL: @mul_times_3_div_2_multiuse_ashr(794; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 3795; CHECK-NEXT:    [[RES:%.*]] = ashr i32 [[MUL]], 1796; CHECK-NEXT:    call void @use(i32 [[MUL]])797; CHECK-NEXT:    ret i32 [[RES]]798;799  %mul = mul nsw i32 %x, 3800  %res = ashr i32 %mul, 1801  call void @use(i32 %mul)802  ret i32 %res803}804 805define i32 @ashr_mul_times_3_div_2_exact_2(i32 %x) {806; CHECK-LABEL: @ashr_mul_times_3_div_2_exact_2(807; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 1808; CHECK-NEXT:    [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]]809; CHECK-NEXT:    ret i32 [[ASHR]]810;811  %mul = mul nsw i32 %x, 3812  %ashr = ashr exact i32 %mul, 1813  ret i32 %ashr814}815 816define i32 @ashr_mul_times_5_div_4(i32 %0) {817; CHECK-LABEL: @ashr_mul_times_5_div_4(818; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 2819; CHECK-NEXT:    [[ASHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]]820; CHECK-NEXT:    ret i32 [[ASHR]]821;822  %mul = mul nuw nsw i32 %0, 5823  %ashr = ashr i32 %mul, 2824  ret i32 %ashr825}826 827define i32 @ashr_mul_times_5_div_4_exact(i32 %x) {828; CHECK-LABEL: @ashr_mul_times_5_div_4_exact(829; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 2830; CHECK-NEXT:    [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]]831; CHECK-NEXT:    ret i32 [[ASHR]]832;833  %mul = mul nsw i32 %x, 5834  %ashr = ashr exact i32 %mul, 2835  ret i32 %ashr836}837 838; Negative test839 840define i32 @ashr_mul_times_5_div_4_no_flags(i32 %0) {841; CHECK-LABEL: @ashr_mul_times_5_div_4_no_flags(842; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 5843; CHECK-NEXT:    [[ASHR:%.*]] = ashr i32 [[MUL]], 2844; CHECK-NEXT:    ret i32 [[ASHR]]845;846  %mul = mul i32 %0, 5847  %ashr = ashr i32 %mul, 2848  ret i32 %ashr849}850 851; Negative test852 853define i32 @mul_times_5_div_4_multiuse_ashr(i32 %x) {854; CHECK-LABEL: @mul_times_5_div_4_multiuse_ashr(855; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 5856; CHECK-NEXT:    [[RES:%.*]] = ashr i32 [[MUL]], 2857; CHECK-NEXT:    call void @use(i32 [[MUL]])858; CHECK-NEXT:    ret i32 [[RES]]859;860  %mul = mul nsw i32 %x, 5861  %res = ashr i32 %mul, 2862  call void @use(i32 %mul)863  ret i32 %res864}865 866define i32 @ashr_mul_times_5_div_4_exact_2(i32 %x) {867; CHECK-LABEL: @ashr_mul_times_5_div_4_exact_2(868; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 2869; CHECK-NEXT:    [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]]870; CHECK-NEXT:    ret i32 [[ASHR]]871;872  %mul = mul nsw i32 %x, 5873  %ashr = ashr exact i32 %mul, 2874  ret i32 %ashr875}876 877 878define i32 @lsb_mask_sign_zext(i32 %x) {879; CHECK-LABEL: @lsb_mask_sign_zext(880; CHECK-NEXT:  entry:881; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0882; CHECK-NEXT:    [[SHR:%.*]] = zext i1 [[TMP0]] to i32883; CHECK-NEXT:    ret i32 [[SHR]]884;885entry:886  %sub = add i32 %x, -1887  %not = xor i32 %x, -1888  %and = and i32 %sub, %not889  %shr = lshr i32 %and, 31890  ret i32 %shr891}892 893define i32 @lsb_mask_sign_zext_commuted(i32 %x) {894; CHECK-LABEL: @lsb_mask_sign_zext_commuted(895; CHECK-NEXT:  entry:896; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0897; CHECK-NEXT:    [[SHR:%.*]] = zext i1 [[TMP0]] to i32898; CHECK-NEXT:    ret i32 [[SHR]]899;900entry:901  %sub = add i32 %x, -1902  %not = xor i32 %x, -1903  %and = and i32 %not, %sub904  %shr = lshr i32 %and, 31905  ret i32 %shr906}907 908; Negative tests909 910define i32 @lsb_mask_sign_zext_wrong_cst1(i32 %x) {911; CHECK-LABEL: @lsb_mask_sign_zext_wrong_cst1(912; CHECK-NEXT:  entry:913; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -2914; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -1915; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]916; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[AND]], 31917; CHECK-NEXT:    ret i32 [[SHR]]918;919entry:920  %sub = add i32 %x, -2921  %not = xor i32 %x, -1922  %and = and i32 %sub, %not923  %shr = lshr i32 %and, 31924  ret i32 %shr925}926 927define i32 @lsb_mask_sign_zext_wrong_cst2(i32 %x) {928; CHECK-LABEL: @lsb_mask_sign_zext_wrong_cst2(929; CHECK-NEXT:  entry:930; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -1931; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[X]]932; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[AND]], 31933; CHECK-NEXT:    ret i32 [[SHR]]934;935entry:936  %sub = add i32 %x, -1937  %not = xor i32 %x, 2938  %and = and i32 %sub, %not939  %shr = lshr i32 %and, 31940  ret i32 %shr941}942 943define i32 @lsb_mask_sign_zext_wrong_cst3(i32 %x) {944; CHECK-LABEL: @lsb_mask_sign_zext_wrong_cst3(945; CHECK-NEXT:  entry:946; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -1947; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -1948; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]949; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[AND]], 30950; CHECK-NEXT:    ret i32 [[SHR]]951;952entry:953  %sub = add i32 %x, -1954  %not = xor i32 %x, -1955  %and = and i32 %sub, %not956  %shr = lshr i32 %and, 30957  ret i32 %shr958}959 960define i32 @lsb_mask_sign_zext_multiuse(i32 %x) {961; CHECK-LABEL: @lsb_mask_sign_zext_multiuse(962; CHECK-NEXT:  entry:963; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -1964; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -1965; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]966; CHECK-NEXT:    call void @use(i32 [[AND]])967; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[AND]], 31968; CHECK-NEXT:    ret i32 [[SHR]]969;970entry:971  %sub = add i32 %x, -1972  %not = xor i32 %x, -1973  %and = and i32 %sub, %not974  call void @use(i32 %and)975  %shr = lshr i32 %and, 31976  ret i32 %shr977}978 979define i32 @lsb_mask_sign_sext(i32 %x) {980; CHECK-LABEL: @lsb_mask_sign_sext(981; CHECK-NEXT:  entry:982; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0983; CHECK-NEXT:    [[SHR:%.*]] = sext i1 [[TMP0]] to i32984; CHECK-NEXT:    ret i32 [[SHR]]985;986entry:987  %sub = add i32 %x, -1988  %not = xor i32 %x, -1989  %and = and i32 %sub, %not990  %shr = ashr i32 %and, 31991  ret i32 %shr992}993 994define i32 @lsb_mask_sign_sext_commuted(i32 %x) {995; CHECK-LABEL: @lsb_mask_sign_sext_commuted(996; CHECK-NEXT:  entry:997; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0998; CHECK-NEXT:    [[SHR:%.*]] = sext i1 [[TMP0]] to i32999; CHECK-NEXT:    ret i32 [[SHR]]1000;1001entry:1002  %sub = add i32 %x, -11003  %not = xor i32 %x, -11004  %and = and i32 %not, %sub1005  %shr = ashr i32 %and, 311006  ret i32 %shr1007}1008 1009; Negative tests1010 1011define i32 @lsb_mask_sign_sext_wrong_cst1(i32 %x) {1012; CHECK-LABEL: @lsb_mask_sign_sext_wrong_cst1(1013; CHECK-NEXT:  entry:1014; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -21015; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -11016; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]1017; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[AND]], 311018; CHECK-NEXT:    ret i32 [[SHR]]1019;1020entry:1021  %sub = add i32 %x, -21022  %not = xor i32 %x, -11023  %and = and i32 %sub, %not1024  %shr = ashr i32 %and, 311025  ret i32 %shr1026}1027 1028define i32 @lsb_mask_sign_sext_wrong_cst2(i32 %x) {1029; CHECK-LABEL: @lsb_mask_sign_sext_wrong_cst2(1030; CHECK-NEXT:  entry:1031; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -11032; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[X]]1033; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[AND]], 311034; CHECK-NEXT:    ret i32 [[SHR]]1035;1036entry:1037  %sub = add i32 %x, -11038  %not = xor i32 %x, 21039  %and = and i32 %sub, %not1040  %shr = ashr i32 %and, 311041  ret i32 %shr1042}1043 1044define i32 @lsb_mask_sign_sext_wrong_cst3(i32 %x) {1045; CHECK-LABEL: @lsb_mask_sign_sext_wrong_cst3(1046; CHECK-NEXT:  entry:1047; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -11048; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -11049; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]1050; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[AND]], 301051; CHECK-NEXT:    ret i32 [[SHR]]1052;1053entry:1054  %sub = add i32 %x, -11055  %not = xor i32 %x, -11056  %and = and i32 %sub, %not1057  %shr = ashr i32 %and, 301058  ret i32 %shr1059}1060 1061define i32 @lsb_mask_sign_sext_multiuse(i32 %x) {1062; CHECK-LABEL: @lsb_mask_sign_sext_multiuse(1063; CHECK-NEXT:  entry:1064; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -11065; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -11066; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]1067; CHECK-NEXT:    call void @use(i32 [[AND]])1068; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[AND]], 311069; CHECK-NEXT:    ret i32 [[SHR]]1070;1071entry:1072  %sub = add i32 %x, -11073  %not = xor i32 %x, -11074  %and = and i32 %sub, %not1075  call void @use(i32 %and)1076  %shr = ashr i32 %and, 311077  ret i32 %shr1078}1079 1080define i32 @ashr_shift_mul(i32 %x) {1081; CHECK-LABEL: @ashr_shift_mul(1082; CHECK-NEXT:    [[A:%.*]] = ashr exact i32 [[X:%.*]], 31083; CHECK-NEXT:    [[RES:%.*]] = add i32 [[X]], [[A]]1084; CHECK-NEXT:    ret i32 [[RES]]1085;1086  %a = ashr exact i32 %x, 31087  %res = mul i32 %a, 91088  ret i32 %res1089}1090 1091define i32 @ashr_shift_mul_nuw(i32 %x) {1092; CHECK-LABEL: @ashr_shift_mul_nuw(1093; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 31094; CHECK-NEXT:    [[RES:%.*]] = add nuw i32 [[X]], [[TMP1]]1095; CHECK-NEXT:    ret i32 [[RES]]1096;1097  %a = ashr exact i32 %x, 31098  %res = mul nuw i32 %a, 91099  ret i32 %res1100}1101 1102define i32 @ashr_shift_mul_nsw(i32 %x) {1103; CHECK-LABEL: @ashr_shift_mul_nsw(1104; CHECK-NEXT:    [[A:%.*]] = ashr exact i32 [[X:%.*]], 31105; CHECK-NEXT:    [[RES:%.*]] = add nsw i32 [[X]], [[A]]1106; CHECK-NEXT:    ret i32 [[RES]]1107;1108  %a = ashr exact i32 %x, 31109  %res = mul nsw i32 %a, 91110  ret i32 %res1111}1112 1113define i32 @lshr_shift_mul_nuw(i32 %x) {1114; CHECK-LABEL: @lshr_shift_mul_nuw(1115; CHECK-NEXT:    [[A:%.*]] = lshr exact i32 [[X:%.*]], 31116; CHECK-NEXT:    [[RES:%.*]] = add nuw i32 [[X]], [[A]]1117; CHECK-NEXT:    ret i32 [[RES]]1118;1119  %a = lshr exact i32 %x, 31120  %res = mul nuw i32 %a, 91121  ret i32 %res1122}1123 1124define i32 @lshr_shift_mul(i32 %x) {1125; CHECK-LABEL: @lshr_shift_mul(1126; CHECK-NEXT:    [[A:%.*]] = lshr exact i32 [[X:%.*]], 31127; CHECK-NEXT:    [[RES:%.*]] = add i32 [[X]], [[A]]1128; CHECK-NEXT:    ret i32 [[RES]]1129;1130  %a = lshr exact i32 %x, 31131  %res = mul i32 %a, 91132  ret i32 %res1133}1134 1135define i32 @lshr_shift_mul_nsw(i32 %x) {1136; CHECK-LABEL: @lshr_shift_mul_nsw(1137; CHECK-NEXT:    [[A:%.*]] = lshr exact i32 [[X:%.*]], 31138; CHECK-NEXT:    [[RES:%.*]] = add nsw i32 [[X]], [[A]]1139; CHECK-NEXT:    ret i32 [[RES]]1140;1141  %a = lshr exact i32 %x, 31142  %res = mul nsw i32 %a, 91143  ret i32 %res1144}1145 1146; Negative test1147 1148define i32 @lshr_no_exact(i32 %x) {1149; CHECK-LABEL: @lshr_no_exact(1150; CHECK-NEXT:    [[A:%.*]] = lshr i32 [[X:%.*]], 31151; CHECK-NEXT:    [[RES:%.*]] = mul nuw nsw i32 [[A]], 91152; CHECK-NEXT:    ret i32 [[RES]]1153;1154  %a = lshr i32 %x, 31155  %res = mul nsw i32 %a, 91156  ret i32 %res1157}1158 1159; Negative test1160 1161define i32 @ashr_no_exact(i32 %x) {1162; CHECK-LABEL: @ashr_no_exact(1163; CHECK-NEXT:    [[A:%.*]] = ashr i32 [[X:%.*]], 31164; CHECK-NEXT:    [[RES:%.*]] = mul nsw i32 [[A]], 91165; CHECK-NEXT:    ret i32 [[RES]]1166;1167  %a = ashr i32 %x, 31168  %res = mul nsw i32 %a, 91169  ret i32 %res1170}1171 1172define i32 @lshr_multiuse(i32 %x) {1173; CHECK-LABEL: @lshr_multiuse(1174; CHECK-NEXT:    [[A:%.*]] = lshr exact i32 [[X:%.*]], 31175; CHECK-NEXT:    call void @use(i32 [[A]])1176; CHECK-NEXT:    [[RES:%.*]] = add nsw i32 [[X]], [[A]]1177; CHECK-NEXT:    ret i32 [[RES]]1178;1179  %a = lshr exact i32 %x, 31180  call void @use(i32 %a)1181  %res = mul nsw i32 %a, 91182  ret i32 %res1183}1184 1185define i32 @lshr_multiuse_no_flags(i32 %x) {1186; CHECK-LABEL: @lshr_multiuse_no_flags(1187; CHECK-NEXT:    [[A:%.*]] = lshr exact i32 [[X:%.*]], 31188; CHECK-NEXT:    call void @use(i32 [[A]])1189; CHECK-NEXT:    [[RES:%.*]] = add i32 [[X]], [[A]]1190; CHECK-NEXT:    ret i32 [[RES]]1191;1192  %a = lshr exact i32 %x, 31193  call void @use(i32 %a)1194  %res = mul i32 %a, 91195  ret i32 %res1196}1197 1198define i32 @ashr_multiuse_no_flags(i32 %x) {1199; CHECK-LABEL: @ashr_multiuse_no_flags(1200; CHECK-NEXT:    [[A:%.*]] = ashr exact i32 [[X:%.*]], 31201; CHECK-NEXT:    call void @use(i32 [[A]])1202; CHECK-NEXT:    [[RES:%.*]] = add i32 [[X]], [[A]]1203; CHECK-NEXT:    ret i32 [[RES]]1204;1205  %a = ashr exact i32 %x, 31206  call void @use(i32 %a)1207  %res = mul i32 %a, 91208  ret i32 %res1209}1210 1211define i32 @ashr_multiuse(i32 %x) {1212; CHECK-LABEL: @ashr_multiuse(1213; CHECK-NEXT:    [[A:%.*]] = ashr exact i32 [[X:%.*]], 31214; CHECK-NEXT:    call void @use(i32 [[A]])1215; CHECK-NEXT:    [[RES:%.*]] = add nsw i32 [[X]], [[A]]1216; CHECK-NEXT:    ret i32 [[RES]]1217;1218  %a = ashr exact i32 %x, 31219  call void @use(i32 %a)1220  %res = mul nsw i32 %a, 91221  ret i32 %res1222}1223 1224declare void @use(i32)1225