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