410 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; If we have some pattern that leaves only some low bits set, and then performs5; left-shift of those bits, if none of the bits that are left after the final6; shift are modified by the mask, we can omit the mask.7 8; There are many variants to this pattern:9; a) (x & ((1 << maskNbits) - 1)) << shiftNbits10; simplify to:11; x << shiftNbits12; iff (maskNbits+shiftNbits) u>= bitwidth(x)13 14; Simple tests. We don't care about extra uses.15 16declare void @use32(i32)17 18define i32 @t0_basic(i32 %x, i32 %nbits) {19; CHECK-LABEL: @t0_basic(20; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]21; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -122; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]23; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]24; CHECK-NEXT: call void @use32(i32 [[T0]])25; CHECK-NEXT: call void @use32(i32 [[T1]])26; CHECK-NEXT: call void @use32(i32 [[T2]])27; CHECK-NEXT: call void @use32(i32 [[T3]])28; CHECK-NEXT: [[T4:%.*]] = shl i32 [[X]], [[T3]]29; CHECK-NEXT: ret i32 [[T4]]30;31 %t0 = shl i32 1, %nbits32 %t1 = add nsw i32 %t0, -133 %t2 = and i32 %t1, %x34 %t3 = sub i32 32, %nbits35 call void @use32(i32 %t0)36 call void @use32(i32 %t1)37 call void @use32(i32 %t2)38 call void @use32(i32 %t3)39 %t4 = shl i32 %t2, %t340 ret i32 %t441}42 43define i32 @t1_bigger_shift(i32 %x, i32 %nbits) {44; CHECK-LABEL: @t1_bigger_shift(45; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]46; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -147; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]48; CHECK-NEXT: [[T3:%.*]] = sub i32 33, [[NBITS]]49; CHECK-NEXT: call void @use32(i32 [[T0]])50; CHECK-NEXT: call void @use32(i32 [[T1]])51; CHECK-NEXT: call void @use32(i32 [[T2]])52; CHECK-NEXT: call void @use32(i32 [[T3]])53; CHECK-NEXT: [[T4:%.*]] = shl i32 [[X]], [[T3]]54; CHECK-NEXT: ret i32 [[T4]]55;56 %t0 = shl i32 1, %nbits57 %t1 = add nsw i32 %t0, -158 %t2 = and i32 %t1, %x59 %t3 = sub i32 33, %nbits ; subtracting from bitwidth+160 call void @use32(i32 %t0)61 call void @use32(i32 %t1)62 call void @use32(i32 %t2)63 call void @use32(i32 %t3)64 %t4 = shl i32 %t2, %t365 ret i32 %t466}67 68define i32 @t2_bigger_mask(i32 %x, i32 %nbits) {69; CHECK-LABEL: @t2_bigger_mask(70; CHECK-NEXT: [[T0:%.*]] = add i32 [[NBITS:%.*]], 171; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 1, [[T0]]72; CHECK-NEXT: [[T2:%.*]] = add nsw i32 [[T1]], -173; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], [[X:%.*]]74; CHECK-NEXT: [[T4:%.*]] = sub i32 32, [[NBITS]]75; CHECK-NEXT: call void @use32(i32 [[T0]])76; CHECK-NEXT: call void @use32(i32 [[T1]])77; CHECK-NEXT: call void @use32(i32 [[T2]])78; CHECK-NEXT: call void @use32(i32 [[T3]])79; CHECK-NEXT: call void @use32(i32 [[T4]])80; CHECK-NEXT: [[T5:%.*]] = shl i32 [[X]], [[T4]]81; CHECK-NEXT: ret i32 [[T5]]82;83 %t0 = add i32 %nbits, 184 %t1 = shl i32 1, %t0 ; shifting by nbits+185 %t2 = add nsw i32 %t1, -186 %t3 = and i32 %t2, %x87 %t4 = sub i32 32, %nbits88 call void @use32(i32 %t0)89 call void @use32(i32 %t1)90 call void @use32(i32 %t2)91 call void @use32(i32 %t3)92 call void @use32(i32 %t4)93 %t5 = shl i32 %t3, %t494 ret i32 %t595}96 97; Vectors98 99declare void @use3xi32(<3 x i32>)100 101define <3 x i32> @t3_vec_splat(<3 x i32> %x, <3 x i32> %nbits) {102; CHECK-LABEL: @t3_vec_splat(103; CHECK-NEXT: [[T1:%.*]] = shl nuw <3 x i32> splat (i32 1), [[NBITS:%.*]]104; CHECK-NEXT: [[T2:%.*]] = add nsw <3 x i32> [[T1]], splat (i32 -1)105; CHECK-NEXT: [[T3:%.*]] = and <3 x i32> [[T2]], [[X:%.*]]106; CHECK-NEXT: [[T4:%.*]] = sub <3 x i32> splat (i32 32), [[NBITS]]107; CHECK-NEXT: call void @use3xi32(<3 x i32> [[NBITS]])108; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T1]])109; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T2]])110; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T3]])111; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T4]])112; CHECK-NEXT: [[T5:%.*]] = shl <3 x i32> [[X]], [[T4]]113; CHECK-NEXT: ret <3 x i32> [[T5]]114;115 %t0 = add <3 x i32> %nbits, <i32 0, i32 0, i32 0>116 %t1 = shl <3 x i32> <i32 1, i32 1, i32 1>, %t0117 %t2 = add nsw <3 x i32> %t1, <i32 -1, i32 -1, i32 -1>118 %t3 = and <3 x i32> %t2, %x119 %t4 = sub <3 x i32> <i32 32, i32 32, i32 32>, %nbits120 call void @use3xi32(<3 x i32> %t0)121 call void @use3xi32(<3 x i32> %t1)122 call void @use3xi32(<3 x i32> %t2)123 call void @use3xi32(<3 x i32> %t3)124 call void @use3xi32(<3 x i32> %t4)125 %t5 = shl <3 x i32> %t3, %t4126 ret <3 x i32> %t5127}128 129define <3 x i32> @t4_vec_nonsplat(<3 x i32> %x, <3 x i32> %nbits) {130; CHECK-LABEL: @t4_vec_nonsplat(131; CHECK-NEXT: [[T0:%.*]] = add <3 x i32> [[NBITS:%.*]], <i32 -1, i32 0, i32 1>132; CHECK-NEXT: [[T1:%.*]] = shl nuw <3 x i32> splat (i32 1), [[T0]]133; CHECK-NEXT: [[T2:%.*]] = add nsw <3 x i32> [[T1]], splat (i32 -1)134; CHECK-NEXT: [[T3:%.*]] = and <3 x i32> [[T2]], [[X:%.*]]135; CHECK-NEXT: [[T4:%.*]] = sub <3 x i32> <i32 33, i32 32, i32 32>, [[NBITS]]136; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T0]])137; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T1]])138; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T2]])139; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T3]])140; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T4]])141; CHECK-NEXT: [[T5:%.*]] = shl <3 x i32> [[X]], [[T4]]142; CHECK-NEXT: ret <3 x i32> [[T5]]143;144 %t0 = add <3 x i32> %nbits, <i32 -1, i32 0, i32 1>145 %t1 = shl <3 x i32> <i32 1, i32 1, i32 1>, %t0146 %t2 = add nsw <3 x i32> %t1, <i32 -1, i32 -1, i32 -1>147 %t3 = and <3 x i32> %t2, %x148 %t4 = sub <3 x i32> <i32 33, i32 32, i32 32>, %nbits149 call void @use3xi32(<3 x i32> %t0)150 call void @use3xi32(<3 x i32> %t1)151 call void @use3xi32(<3 x i32> %t2)152 call void @use3xi32(<3 x i32> %t3)153 call void @use3xi32(<3 x i32> %t4)154 %t5 = shl <3 x i32> %t3, %t4155 ret <3 x i32> %t5156}157 158define <3 x i32> @t5_vec_poison(<3 x i32> %x, <3 x i32> %nbits) {159; CHECK-LABEL: @t5_vec_poison(160; CHECK-NEXT: [[T1:%.*]] = shl nuw <3 x i32> <i32 1, i32 poison, i32 1>, [[NBITS:%.*]]161; CHECK-NEXT: [[T2:%.*]] = add nsw <3 x i32> [[T1]], <i32 -1, i32 poison, i32 -1>162; CHECK-NEXT: [[T3:%.*]] = and <3 x i32> [[T2]], [[X:%.*]]163; CHECK-NEXT: [[T4:%.*]] = sub <3 x i32> <i32 32, i32 poison, i32 32>, [[NBITS]]164; CHECK-NEXT: call void @use3xi32(<3 x i32> [[NBITS]])165; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T1]])166; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T2]])167; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T3]])168; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T4]])169; CHECK-NEXT: [[T5:%.*]] = shl <3 x i32> [[X]], [[T4]]170; CHECK-NEXT: ret <3 x i32> [[T5]]171;172 %t0 = add <3 x i32> %nbits, <i32 0, i32 poison, i32 0>173 %t1 = shl <3 x i32> <i32 1, i32 poison, i32 1>, %t0174 %t2 = add nsw <3 x i32> %t1, <i32 -1, i32 poison, i32 -1>175 %t3 = and <3 x i32> %t2, %x176 %t4 = sub <3 x i32> <i32 32, i32 poison, i32 32>, %nbits177 call void @use3xi32(<3 x i32> %t0)178 call void @use3xi32(<3 x i32> %t1)179 call void @use3xi32(<3 x i32> %t2)180 call void @use3xi32(<3 x i32> %t3)181 call void @use3xi32(<3 x i32> %t4)182 %t5 = shl <3 x i32> %t3, %t4183 ret <3 x i32> %t5184}185 186; Commutativity187 188declare i32 @gen32()189 190define i32 @t6_commutativity0(i32 %nbits) {191; CHECK-LABEL: @t6_commutativity0(192; CHECK-NEXT: [[X:%.*]] = call i32 @gen32()193; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]194; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1195; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], [[T1]]196; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]197; CHECK-NEXT: call void @use32(i32 [[T0]])198; CHECK-NEXT: call void @use32(i32 [[T1]])199; CHECK-NEXT: call void @use32(i32 [[T2]])200; CHECK-NEXT: call void @use32(i32 [[T3]])201; CHECK-NEXT: [[T4:%.*]] = shl i32 [[X]], [[T3]]202; CHECK-NEXT: ret i32 [[T4]]203;204 %x = call i32 @gen32()205 %t0 = shl i32 1, %nbits206 %t1 = add nsw i32 %t0, -1207 %t2 = and i32 %x, %t1 ; swapped208 %t3 = sub i32 32, %nbits209 call void @use32(i32 %t0)210 call void @use32(i32 %t1)211 call void @use32(i32 %t2)212 call void @use32(i32 %t3)213 %t4 = shl i32 %t2, %t3214 ret i32 %t4215}216 217define i32 @t7_commutativity1(i32 %nbits0, i32 %nbits1) {218; CHECK-LABEL: @t7_commutativity1(219; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS0:%.*]]220; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1221; CHECK-NEXT: [[T2:%.*]] = shl nuw i32 1, [[NBITS1:%.*]]222; CHECK-NEXT: [[T3:%.*]] = add nsw i32 [[T2]], -1223; CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], [[T1]]224; CHECK-NEXT: [[T5:%.*]] = sub i32 32, [[NBITS0]]225; CHECK-NEXT: call void @use32(i32 [[T0]])226; CHECK-NEXT: call void @use32(i32 [[T1]])227; CHECK-NEXT: call void @use32(i32 [[T2]])228; CHECK-NEXT: call void @use32(i32 [[T3]])229; CHECK-NEXT: call void @use32(i32 [[T4]])230; CHECK-NEXT: call void @use32(i32 [[T5]])231; CHECK-NEXT: [[T6:%.*]] = shl i32 [[T4]], [[T5]]232; CHECK-NEXT: ret i32 [[T6]]233;234 %t0 = shl i32 1, %nbits0235 %t1 = add nsw i32 %t0, -1236 %t2 = shl i32 1, %nbits1237 %t3 = add nsw i32 %t2, -1238 %t4 = and i32 %t3, %t1 ; both hands of 'and' could be mask..239 %t5 = sub i32 32, %nbits0240 call void @use32(i32 %t0)241 call void @use32(i32 %t1)242 call void @use32(i32 %t2)243 call void @use32(i32 %t3)244 call void @use32(i32 %t4)245 call void @use32(i32 %t5)246 %t6 = shl i32 %t4, %t5247 ret i32 %t6248}249define i32 @t8_commutativity2(i32 %nbits0, i32 %nbits1) {250; CHECK-LABEL: @t8_commutativity2(251; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS0:%.*]]252; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1253; CHECK-NEXT: [[T2:%.*]] = shl nuw i32 1, [[NBITS1:%.*]]254; CHECK-NEXT: [[T3:%.*]] = add nsw i32 [[T2]], -1255; CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], [[T1]]256; CHECK-NEXT: [[T5:%.*]] = sub i32 32, [[NBITS1]]257; CHECK-NEXT: call void @use32(i32 [[T0]])258; CHECK-NEXT: call void @use32(i32 [[T1]])259; CHECK-NEXT: call void @use32(i32 [[T2]])260; CHECK-NEXT: call void @use32(i32 [[T3]])261; CHECK-NEXT: call void @use32(i32 [[T4]])262; CHECK-NEXT: call void @use32(i32 [[T5]])263; CHECK-NEXT: [[T6:%.*]] = shl i32 [[T1]], [[T5]]264; CHECK-NEXT: ret i32 [[T6]]265;266 %t0 = shl i32 1, %nbits0267 %t1 = add nsw i32 %t0, -1268 %t2 = shl i32 1, %nbits1269 %t3 = add nsw i32 %t2, -1270 %t4 = and i32 %t3, %t1 ; both hands of 'and' could be mask..271 %t5 = sub i32 32, %nbits1272 call void @use32(i32 %t0)273 call void @use32(i32 %t1)274 call void @use32(i32 %t2)275 call void @use32(i32 %t3)276 call void @use32(i32 %t4)277 call void @use32(i32 %t5)278 %t6 = shl i32 %t4, %t5279 ret i32 %t6280}281 282; Fast-math flags. We must not preserve them!283 284define i32 @t9_nuw(i32 %x, i32 %nbits) {285; CHECK-LABEL: @t9_nuw(286; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]287; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1288; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]289; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]290; CHECK-NEXT: call void @use32(i32 [[T0]])291; CHECK-NEXT: call void @use32(i32 [[T1]])292; CHECK-NEXT: call void @use32(i32 [[T2]])293; CHECK-NEXT: call void @use32(i32 [[T3]])294; CHECK-NEXT: [[T4:%.*]] = shl i32 [[X]], [[T3]]295; CHECK-NEXT: ret i32 [[T4]]296;297 %t0 = shl i32 1, %nbits298 %t1 = add nsw i32 %t0, -1299 %t2 = and i32 %t1, %x300 %t3 = sub i32 32, %nbits301 call void @use32(i32 %t0)302 call void @use32(i32 %t1)303 call void @use32(i32 %t2)304 call void @use32(i32 %t3)305 %t4 = shl nuw i32 %t2, %t3306 ret i32 %t4307}308 309define i32 @t10_nsw(i32 %x, i32 %nbits) {310; CHECK-LABEL: @t10_nsw(311; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]312; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1313; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]314; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]315; CHECK-NEXT: call void @use32(i32 [[T0]])316; CHECK-NEXT: call void @use32(i32 [[T1]])317; CHECK-NEXT: call void @use32(i32 [[T2]])318; CHECK-NEXT: call void @use32(i32 [[T3]])319; CHECK-NEXT: [[T4:%.*]] = shl i32 [[X]], [[T3]]320; CHECK-NEXT: ret i32 [[T4]]321;322 %t0 = shl i32 1, %nbits323 %t1 = add nsw i32 %t0, -1324 %t2 = and i32 %t1, %x325 %t3 = sub i32 32, %nbits326 call void @use32(i32 %t0)327 call void @use32(i32 %t1)328 call void @use32(i32 %t2)329 call void @use32(i32 %t3)330 %t4 = shl nsw i32 %t2, %t3331 ret i32 %t4332}333 334define i32 @t11_nuw_nsw(i32 %x, i32 %nbits) {335; CHECK-LABEL: @t11_nuw_nsw(336; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]337; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1338; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]339; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]340; CHECK-NEXT: call void @use32(i32 [[T0]])341; CHECK-NEXT: call void @use32(i32 [[T1]])342; CHECK-NEXT: call void @use32(i32 [[T2]])343; CHECK-NEXT: call void @use32(i32 [[T3]])344; CHECK-NEXT: [[T4:%.*]] = shl i32 [[X]], [[T3]]345; CHECK-NEXT: ret i32 [[T4]]346;347 %t0 = shl i32 1, %nbits348 %t1 = add nsw i32 %t0, -1349 %t2 = and i32 %t1, %x350 %t3 = sub i32 32, %nbits351 call void @use32(i32 %t0)352 call void @use32(i32 %t1)353 call void @use32(i32 %t2)354 call void @use32(i32 %t3)355 %t4 = shl nuw nsw i32 %t2, %t3356 ret i32 %t4357}358 359; Negative tests360 361define i32 @n12_not_minus_one(i32 %x, i32 %nbits) {362; CHECK-LABEL: @n12_not_minus_one(363; CHECK-NEXT: [[T0:%.*]] = shl i32 2, [[NBITS:%.*]]364; CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], -1365; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]366; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]367; CHECK-NEXT: call void @use32(i32 [[T0]])368; CHECK-NEXT: call void @use32(i32 [[T1]])369; CHECK-NEXT: call void @use32(i32 [[T2]])370; CHECK-NEXT: call void @use32(i32 [[T3]])371; CHECK-NEXT: [[T4:%.*]] = shl i32 [[T2]], [[T3]]372; CHECK-NEXT: ret i32 [[T4]]373;374 %t0 = shl i32 2, %nbits ; shifting not '-1'375 %t1 = add nsw i32 %t0, -1376 %t2 = and i32 %t1, %x377 %t3 = sub i32 32, %nbits378 call void @use32(i32 %t0)379 call void @use32(i32 %t1)380 call void @use32(i32 %t2)381 call void @use32(i32 %t3)382 %t4 = shl i32 %t2, %t3383 ret i32 %t4384}385 386define i32 @n13_not_minus_one(i32 %x, i32 %nbits) {387; CHECK-LABEL: @n13_not_minus_one(388; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 1, [[NBITS:%.*]]389; CHECK-NEXT: [[T1:%.*]] = add nuw nsw i32 [[T0]], 2147483647390; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]391; CHECK-NEXT: [[T3:%.*]] = sub i32 32, [[NBITS]]392; CHECK-NEXT: call void @use32(i32 [[T0]])393; CHECK-NEXT: call void @use32(i32 [[T1]])394; CHECK-NEXT: call void @use32(i32 [[T2]])395; CHECK-NEXT: call void @use32(i32 [[T3]])396; CHECK-NEXT: [[T4:%.*]] = shl i32 [[T2]], [[T3]]397; CHECK-NEXT: ret i32 [[T4]]398;399 %t0 = shl i32 1, %nbits400 %t1 = add nsw i32 %t0, 2147483647 ; adding not '-1'401 %t2 = and i32 %t1, %x402 %t3 = sub i32 32, %nbits403 call void @use32(i32 %t0)404 call void @use32(i32 %t1)405 call void @use32(i32 %t2)406 call void @use32(i32 %t3)407 %t4 = shl i32 %t2, %t3408 ret i32 %t4409}410