399 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; https://bugs.llvm.org/show_bug.cgi?id=376035 6; Pattern:7; x << y >> y8; Should be transformed into:9; x & (-1 >> y)10 11; ============================================================================ ;12; Basic positive tests13; ============================================================================ ;14 15define i32 @positive_samevar(i32 %x, i32 %y) {16; CHECK-LABEL: @positive_samevar(17; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 -1, [[Y:%.*]]18; CHECK-NEXT: [[RET:%.*]] = and i32 [[TMP1]], [[X:%.*]]19; CHECK-NEXT: ret i32 [[RET]]20;21 %t0 = shl i32 %x, %y22 %ret = lshr i32 %t0, %y23 ret i32 %ret24}25 26define i32 @positive_sameconst(i32 %x) {27; CHECK-LABEL: @positive_sameconst(28; CHECK-NEXT: [[T0:%.*]] = and i32 [[X:%.*]], 13421772729; CHECK-NEXT: ret i32 [[T0]]30;31 %t0 = shl i32 %x, 532 %ret = lshr i32 %t0, 533 ret i32 %ret34}35 36define i32 @positive_biggerShl(i32 %x) {37; CHECK-LABEL: @positive_biggerShl(38; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 539; CHECK-NEXT: [[RET:%.*]] = and i32 [[TMP1]], 13421769640; CHECK-NEXT: ret i32 [[RET]]41;42 %t0 = shl i32 %x, 1043 %ret = lshr i32 %t0, 544 ret i32 %ret45}46 47define i32 @positive_biggerLshr(i32 %x) {48; CHECK-LABEL: @positive_biggerLshr(49; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 550; CHECK-NEXT: [[RET:%.*]] = and i32 [[TMP1]], 419430351; CHECK-NEXT: ret i32 [[RET]]52;53 %t0 = shl i32 %x, 554 %ret = lshr i32 %t0, 1055 ret i32 %ret56}57 58define i32 @positive_biggerLshr_lshrexact(i32 %x) {59; CHECK-LABEL: @positive_biggerLshr_lshrexact(60; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 561; CHECK-NEXT: [[RET:%.*]] = and i32 [[TMP1]], 419430362; CHECK-NEXT: ret i32 [[RET]]63;64 %t0 = shl i32 %x, 565 %ret = lshr exact i32 %t0, 1066 ret i32 %ret67}68 69; ============================================================================ ;70; NUW on the first shift71; ============================================================================ ;72 73define i32 @positive_samevar_shlnuw(i32 %x, i32 %y) {74; CHECK-LABEL: @positive_samevar_shlnuw(75; CHECK-NEXT: ret i32 [[X:%.*]]76;77 %t0 = shl nuw i32 %x, %y78 %ret = lshr i32 %t0, %y ; this one is obviously 'exact'.79 ret i32 %ret80}81 82define i32 @positive_sameconst_shlnuw(i32 %x) {83; CHECK-LABEL: @positive_sameconst_shlnuw(84; CHECK-NEXT: ret i32 [[X:%.*]]85;86 %t0 = shl nuw i32 %x, 587 %ret = lshr i32 %t0, 5 ; this one is obviously 'exact'.88 ret i32 %ret89}90 91define i32 @positive_biggerShl_shlnuw(i32 %x) {92; CHECK-LABEL: @positive_biggerShl_shlnuw(93; CHECK-NEXT: [[RET:%.*]] = shl nuw nsw i32 [[X:%.*]], 594; CHECK-NEXT: ret i32 [[RET]]95;96 %t0 = shl nuw i32 %x, 1097 %ret = lshr i32 %t0, 5 ; this one is obviously 'exact'.98 ret i32 %ret99}100 101define i32 @positive_biggerLshr_shlnuw(i32 %x) {102; CHECK-LABEL: @positive_biggerLshr_shlnuw(103; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[X:%.*]], 5104; CHECK-NEXT: ret i32 [[RET]]105;106 %t0 = shl nuw i32 %x, 5107 %ret = lshr i32 %t0, 10108 ret i32 %ret109}110 111define i32 @positive_biggerLshr_shlnuw_lshrexact(i32 %x) {112; CHECK-LABEL: @positive_biggerLshr_shlnuw_lshrexact(113; CHECK-NEXT: [[RET:%.*]] = lshr exact i32 [[X:%.*]], 5114; CHECK-NEXT: ret i32 [[RET]]115;116 %t0 = shl nuw i32 %x, 5117 %ret = lshr exact i32 %t0, 10118 ret i32 %ret119}120 121; ============================================================================ ;122; Vector123; ============================================================================ ;124 125define <2 x i32> @positive_samevar_vec(<2 x i32> %x, <2 x i32> %y) {126; CHECK-LABEL: @positive_samevar_vec(127; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> splat (i32 -1), [[Y:%.*]]128; CHECK-NEXT: [[RET:%.*]] = and <2 x i32> [[TMP1]], [[X:%.*]]129; CHECK-NEXT: ret <2 x i32> [[RET]]130;131 %t0 = shl <2 x i32> %x, %y132 %ret = lshr <2 x i32> %t0, %y133 ret <2 x i32> %ret134}135 136; ============================================================================ ;137; Constant Vectors138; ============================================================================ ;139 140define <2 x i32> @positive_sameconst_vec(<2 x i32> %x) {141; CHECK-LABEL: @positive_sameconst_vec(142; CHECK-NEXT: [[T0:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 134217727)143; CHECK-NEXT: ret <2 x i32> [[T0]]144;145 %t0 = shl <2 x i32> %x, <i32 5, i32 5>146 %ret = lshr <2 x i32> %t0, <i32 5, i32 5>147 ret <2 x i32> %ret148}149 150define <3 x i32> @positive_sameconst_vec_undef0(<3 x i32> %x) {151; CHECK-LABEL: @positive_sameconst_vec_undef0(152; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 undef, i32 5>153; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], splat (i32 5)154; CHECK-NEXT: ret <3 x i32> [[RET]]155;156 %t0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>157 %ret = lshr <3 x i32> %t0, <i32 5, i32 5, i32 5>158 ret <3 x i32> %ret159}160 161define <3 x i32> @positive_sameconst_vec_undef1(<3 x i32> %x) {162; CHECK-LABEL: @positive_sameconst_vec_undef1(163; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], splat (i32 5)164; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 5, i32 undef, i32 5>165; CHECK-NEXT: ret <3 x i32> [[RET]]166;167 %t0 = shl <3 x i32> %x, <i32 5, i32 5, i32 5>168 %ret = lshr <3 x i32> %t0, <i32 5, i32 undef, i32 5>169 ret <3 x i32> %ret170}171 172define <3 x i32> @positive_sameconst_vec_undef2(<3 x i32> %x) {173; CHECK-LABEL: @positive_sameconst_vec_undef2(174; CHECK-NEXT: [[RET:%.*]] = and <3 x i32> [[X:%.*]], <i32 134217727, i32 poison, i32 134217727>175; CHECK-NEXT: ret <3 x i32> [[RET]]176;177 %t0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>178 %ret = lshr <3 x i32> %t0, <i32 5, i32 undef, i32 5>179 ret <3 x i32> %ret180}181 182define <2 x i32> @positive_biggerShl_vec(<2 x i32> %x) {183; CHECK-LABEL: @positive_biggerShl_vec(184; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 5)185; CHECK-NEXT: [[RET:%.*]] = and <2 x i32> [[TMP1]], splat (i32 134217696)186; CHECK-NEXT: ret <2 x i32> [[RET]]187;188 %t0 = shl <2 x i32> %x, <i32 10, i32 10>189 %ret = lshr <2 x i32> %t0, <i32 5, i32 5>190 ret <2 x i32> %ret191}192 193define <3 x i32> @positive_biggerShl_vec_undef0(<3 x i32> %x) {194; CHECK-LABEL: @positive_biggerShl_vec_undef0(195; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 10, i32 undef, i32 10>196; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], splat (i32 5)197; CHECK-NEXT: ret <3 x i32> [[RET]]198;199 %t0 = shl <3 x i32> %x, <i32 10, i32 undef, i32 10>200 %ret = lshr <3 x i32> %t0, <i32 5, i32 5, i32 5>201 ret <3 x i32> %ret202}203 204define <3 x i32> @positive_biggerShl_vec_undef1(<3 x i32> %x) {205; CHECK-LABEL: @positive_biggerShl_vec_undef1(206; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], splat (i32 10)207; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 5, i32 undef, i32 5>208; CHECK-NEXT: ret <3 x i32> [[RET]]209;210 %t0 = shl <3 x i32> %x, <i32 10, i32 10, i32 10>211 %ret = lshr <3 x i32> %t0, <i32 5, i32 undef, i32 5>212 ret <3 x i32> %ret213}214 215define <3 x i32> @positive_biggerShl_vec_undef2(<3 x i32> %x) {216; CHECK-LABEL: @positive_biggerShl_vec_undef2(217; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 10, i32 undef, i32 10>218; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 5, i32 undef, i32 5>219; CHECK-NEXT: ret <3 x i32> [[RET]]220;221 %t0 = shl <3 x i32> %x, <i32 10, i32 undef, i32 10>222 %ret = lshr <3 x i32> %t0, <i32 5, i32 undef, i32 5>223 ret <3 x i32> %ret224}225 226define <2 x i32> @positive_biggerLshr_vec(<2 x i32> %x) {227; CHECK-LABEL: @positive_biggerLshr_vec(228; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 5)229; CHECK-NEXT: [[RET:%.*]] = and <2 x i32> [[TMP1]], splat (i32 4194303)230; CHECK-NEXT: ret <2 x i32> [[RET]]231;232 %t0 = shl <2 x i32> %x, <i32 5, i32 5>233 %ret = lshr <2 x i32> %t0, <i32 10, i32 10>234 ret <2 x i32> %ret235}236 237define <3 x i32> @positive_biggerLshr_vec_undef0(<3 x i32> %x) {238; CHECK-LABEL: @positive_biggerLshr_vec_undef0(239; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 undef, i32 5>240; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], splat (i32 10)241; CHECK-NEXT: ret <3 x i32> [[RET]]242;243 %t0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>244 %ret = lshr <3 x i32> %t0, <i32 10, i32 10, i32 10>245 ret <3 x i32> %ret246}247 248define <3 x i32> @positive_biggerLshr_vec_undef1(<3 x i32> %x) {249; CHECK-LABEL: @positive_biggerLshr_vec_undef1(250; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], splat (i32 5)251; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 10, i32 undef, i32 10>252; CHECK-NEXT: ret <3 x i32> [[RET]]253;254 %t0 = shl <3 x i32> %x, <i32 5, i32 5, i32 5>255 %ret = lshr <3 x i32> %t0, <i32 10, i32 undef, i32 10>256 ret <3 x i32> %ret257}258 259define <3 x i32> @positive_biggerLshr_vec_undef2(<3 x i32> %x) {260; CHECK-LABEL: @positive_biggerLshr_vec_undef2(261; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 undef, i32 5>262; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 10, i32 undef, i32 10>263; CHECK-NEXT: ret <3 x i32> [[RET]]264;265 %t0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>266 %ret = lshr <3 x i32> %t0, <i32 10, i32 undef, i32 10>267 ret <3 x i32> %ret268}269 270; ============================================================================ ;271; Positive multi-use tests with constant272; ============================================================================ ;273 274define i32 @positive_sameconst_multiuse(i32 %x) {275; CHECK-LABEL: @positive_sameconst_multiuse(276; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], 5277; CHECK-NEXT: call void @use32(i32 [[T0]])278; CHECK-NEXT: [[RET:%.*]] = and i32 [[X]], 134217727279; CHECK-NEXT: ret i32 [[RET]]280;281 %t0 = shl i32 %x, 5282 call void @use32(i32 %t0)283 %ret = lshr i32 %t0, 5284 ret i32 %ret285}286 287define i32 @positive_biggerShl_shlnuw_multiuse(i32 %x) {288; CHECK-LABEL: @positive_biggerShl_shlnuw_multiuse(289; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 [[X:%.*]], 10290; CHECK-NEXT: call void @use32(i32 [[T0]])291; CHECK-NEXT: [[RET:%.*]] = shl nuw nsw i32 [[X]], 5292; CHECK-NEXT: ret i32 [[RET]]293;294 %t0 = shl nuw i32 %x, 10295 call void @use32(i32 %t0)296 %ret = lshr i32 %t0, 5297 ret i32 %ret298}299 300define i32 @positive_biggerLshr_shlnuw_multiuse(i32 %x) {301; CHECK-LABEL: @positive_biggerLshr_shlnuw_multiuse(302; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 [[X:%.*]], 5303; CHECK-NEXT: call void @use32(i32 [[T0]])304; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[X]], 5305; CHECK-NEXT: ret i32 [[RET]]306;307 %t0 = shl nuw i32 %x, 5308 call void @use32(i32 %t0)309 %ret = lshr i32 %t0, 10310 ret i32 %ret311}312 313; negative test - don't create extra instructions314 315define i32 @positive_biggerShl_multiuse_extrainstr(i32 %x) {316; CHECK-LABEL: @positive_biggerShl_multiuse_extrainstr(317; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], 10318; CHECK-NEXT: call void @use32(i32 [[T0]])319; CHECK-NEXT: [[RET:%.*]] = lshr exact i32 [[T0]], 5320; CHECK-NEXT: ret i32 [[RET]]321;322 %t0 = shl i32 %x, 10323 call void @use32(i32 %t0)324 %ret = lshr i32 %t0, 5325 ret i32 %ret326}327 328; negative test - don't create extra instructions329 330define i32 @positive_biggerLshr_multiuse_extrainstr(i32 %x) {331; CHECK-LABEL: @positive_biggerLshr_multiuse_extrainstr(332; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], 5333; CHECK-NEXT: call void @use32(i32 [[T0]])334; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[T0]], 10335; CHECK-NEXT: ret i32 [[RET]]336;337 %t0 = shl i32 %x, 5338 call void @use32(i32 %t0)339 %ret = lshr i32 %t0, 10340 ret i32 %ret341}342 343; ============================================================================ ;344; Constant Non-Splat Vectors345; ============================================================================ ;346 347define <2 x i32> @positive_biggerShl_vec_nonsplat(<2 x i32> %x) {348; CHECK-LABEL: @positive_biggerShl_vec_nonsplat(349; CHECK-NEXT: [[T0:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 5)350; CHECK-NEXT: [[RET:%.*]] = lshr <2 x i32> [[T0]], <i32 5, i32 10>351; CHECK-NEXT: ret <2 x i32> [[RET]]352;353 %t0 = shl <2 x i32> %x, <i32 5, i32 5>354 %ret = lshr <2 x i32> %t0, <i32 5, i32 10>355 ret <2 x i32> %ret356}357 358define <2 x i32> @positive_biggerLshl_vec_nonsplat(<2 x i32> %x) {359; CHECK-LABEL: @positive_biggerLshl_vec_nonsplat(360; CHECK-NEXT: [[T0:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 10>361; CHECK-NEXT: [[RET:%.*]] = lshr <2 x i32> [[T0]], splat (i32 5)362; CHECK-NEXT: ret <2 x i32> [[RET]]363;364 %t0 = shl <2 x i32> %x, <i32 5, i32 10>365 %ret = lshr <2 x i32> %t0, <i32 5, i32 5>366 ret <2 x i32> %ret367}368 369; ============================================================================ ;370; Negative tests. Should not be folded.371; ============================================================================ ;372 373define i32 @negative_twovars(i32 %x, i32 %y, i32 %z) {374; CHECK-LABEL: @negative_twovars(375; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]376; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[T0]], [[Z:%.*]]377; CHECK-NEXT: ret i32 [[RET]]378;379 %t0 = shl i32 %x, %y380 %ret = lshr i32 %t0, %z ; $z, not %y381 ret i32 %ret382}383 384declare void @use32(i32)385 386; One use only.387define i32 @negative_oneuse(i32 %x, i32 %y) {388; CHECK-LABEL: @negative_oneuse(389; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]390; CHECK-NEXT: call void @use32(i32 [[T0]])391; CHECK-NEXT: [[RET:%.*]] = lshr exact i32 [[T0]], [[Y]]392; CHECK-NEXT: ret i32 [[RET]]393;394 %t0 = shl i32 %x, %y395 call void @use32(i32 %t0)396 %ret = lshr i32 %t0, %y397 ret i32 %ret398}399