brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.1 KiB · 3db87b0 Raw
311 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, we can combine those two shifts into a shift+mask.6 7; There are many variants to this pattern:8;   b)  (trunc ((x & (~(-1 << maskNbits))))) << shiftNbits9; simplify to:10;   ((trunc(x)) << shiftNbits) & (~(-1 << (maskNbits+shiftNbits)))11 12; Simple tests.13 14declare void @use32(i32)15declare void @use64(i64)16 17define i32 @t0_basic(i64 %x, i32 %nbits) {18; CHECK-LABEL: @t0_basic(19; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -120; CHECK-NEXT:    [[T1:%.*]] = zext i32 [[T0]] to i6421; CHECK-NEXT:    [[T2:%.*]] = shl nsw i64 -1, [[T1]]22; CHECK-NEXT:    [[T3:%.*]] = xor i64 [[T2]], -123; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]24; CHECK-NEXT:    call void @use32(i32 [[T0]])25; CHECK-NEXT:    call void @use64(i64 [[T1]])26; CHECK-NEXT:    call void @use64(i64 [[T2]])27; CHECK-NEXT:    call void @use64(i64 [[T3]])28; CHECK-NEXT:    call void @use32(i32 [[T4]])29; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i3230; CHECK-NEXT:    [[TMP2:%.*]] = shl i32 [[TMP1]], [[T4]]31; CHECK-NEXT:    [[T7:%.*]] = and i32 [[TMP2]], 214748364732; CHECK-NEXT:    ret i32 [[T7]]33;34  %t0 = add i32 %nbits, -135  %t1 = zext i32 %t0 to i6436  %t2 = shl i64 -1, %t1 ; shifting by nbits-137  %t3 = xor i64 %t2, -138  %t4 = sub i32 32, %nbits39 40  call void @use32(i32 %t0)41  call void @use64(i64 %t1)42  call void @use64(i64 %t2)43  call void @use64(i64 %t3)44  call void @use32(i32 %t4)45 46  %t5 = and i64 %t3, %x47  %t6 = trunc i64 %t5 to i3248  %t7 = shl i32 %t6, %t449  ret i32 %t750}51 52; Vectors53 54declare void @use8xi32(<8 x i32>)55declare void @use8xi64(<8 x i64>)56 57define <8 x i32> @t1_vec_splat(<8 x i64> %x, <8 x i32> %nbits) {58; CHECK-LABEL: @t1_vec_splat(59; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], splat (i32 -1)60; CHECK-NEXT:    [[T1:%.*]] = zext <8 x i32> [[T0]] to <8 x i64>61; CHECK-NEXT:    [[T2:%.*]] = shl nsw <8 x i64> splat (i64 -1), [[T1]]62; CHECK-NEXT:    [[T3:%.*]] = xor <8 x i64> [[T2]], splat (i64 -1)63; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> splat (i32 32), [[NBITS]]64; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])65; CHECK-NEXT:    call void @use8xi64(<8 x i64> [[T1]])66; CHECK-NEXT:    call void @use8xi64(<8 x i64> [[T2]])67; CHECK-NEXT:    call void @use8xi64(<8 x i64> [[T3]])68; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T4]])69; CHECK-NEXT:    [[TMP1:%.*]] = trunc <8 x i64> [[X:%.*]] to <8 x i32>70; CHECK-NEXT:    [[TMP2:%.*]] = shl <8 x i32> [[TMP1]], [[T4]]71; CHECK-NEXT:    [[T7:%.*]] = and <8 x i32> [[TMP2]], splat (i32 2147483647)72; CHECK-NEXT:    ret <8 x i32> [[T7]]73;74  %t0 = add <8 x i32> %nbits, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>75  %t1 = zext <8 x i32> %t0 to <8 x i64>76  %t2 = shl <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, %t1 ; shifting by nbits-177  %t3 = xor <8 x i64> %t2, <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>78  %t4 = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, %nbits79 80  call void @use8xi32(<8 x i32> %t0)81  call void @use8xi64(<8 x i64> %t1)82  call void @use8xi64(<8 x i64> %t2)83  call void @use8xi64(<8 x i64> %t3)84  call void @use8xi32(<8 x i32> %t4)85 86  %t5 = and <8 x i64> %t3, %x87  %t6 = trunc <8 x i64> %t5 to <8 x i32>88  %t7 = shl <8 x i32> %t6, %t489  ret <8 x i32> %t790}91 92define <8 x i32> @t2_vec_splat_poison(<8 x i64> %x, <8 x i32> %nbits) {93; CHECK-LABEL: @t2_vec_splat_poison(94; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 poison, i32 -1>95; CHECK-NEXT:    [[T1:%.*]] = zext <8 x i32> [[T0]] to <8 x i64>96; CHECK-NEXT:    [[T2:%.*]] = shl nsw <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 poison, i64 -1>, [[T1]]97; CHECK-NEXT:    [[T3:%.*]] = xor <8 x i64> [[T2]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 poison, i64 -1>98; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 poison, i32 32>, [[NBITS]]99; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])100; CHECK-NEXT:    call void @use8xi64(<8 x i64> [[T1]])101; CHECK-NEXT:    call void @use8xi64(<8 x i64> [[T2]])102; CHECK-NEXT:    call void @use8xi64(<8 x i64> [[T3]])103; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T4]])104; CHECK-NEXT:    [[TMP1:%.*]] = trunc <8 x i64> [[X:%.*]] to <8 x i32>105; CHECK-NEXT:    [[TMP2:%.*]] = shl <8 x i32> [[TMP1]], [[T4]]106; CHECK-NEXT:    [[T7:%.*]] = and <8 x i32> [[TMP2]], <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 poison, i32 2147483647>107; CHECK-NEXT:    ret <8 x i32> [[T7]]108;109  %t0 = add <8 x i32> %nbits, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 poison, i32 -1>110  %t1 = zext <8 x i32> %t0 to <8 x i64>111  %t2 = shl <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 poison, i64 -1>, %t1 ; shifting by nbits-1112  %t3 = xor <8 x i64> %t2, <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 poison, i64 -1>113  %t4 = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 poison, i32 32>, %nbits114 115  call void @use8xi32(<8 x i32> %t0)116  call void @use8xi64(<8 x i64> %t1)117  call void @use8xi64(<8 x i64> %t2)118  call void @use8xi64(<8 x i64> %t3)119  call void @use8xi32(<8 x i32> %t4)120 121  %t5 = and <8 x i64> %t3, %x122  %t6 = trunc <8 x i64> %t5 to <8 x i32>123  %t7 = shl <8 x i32> %t6, %t4124  ret <8 x i32> %t7125}126 127define <8 x i32> @t3_vec_nonsplat(<8 x i64> %x, <8 x i32> %nbits) {128; CHECK-LABEL: @t3_vec_nonsplat(129; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -33, i32 -32, i32 -31, i32 -1, i32 0, i32 1, i32 31, i32 32>130; CHECK-NEXT:    [[T1:%.*]] = zext <8 x i32> [[T0]] to <8 x i64>131; CHECK-NEXT:    [[T2:%.*]] = shl nsw <8 x i64> splat (i64 -1), [[T1]]132; CHECK-NEXT:    [[T3:%.*]] = xor <8 x i64> [[T2]], splat (i64 -1)133; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> splat (i32 32), [[NBITS]]134; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])135; CHECK-NEXT:    call void @use8xi64(<8 x i64> [[T1]])136; CHECK-NEXT:    call void @use8xi64(<8 x i64> [[T2]])137; CHECK-NEXT:    call void @use8xi64(<8 x i64> [[T3]])138; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T4]])139; CHECK-NEXT:    [[TMP1:%.*]] = trunc <8 x i64> [[X:%.*]] to <8 x i32>140; CHECK-NEXT:    [[TMP2:%.*]] = shl <8 x i32> [[TMP1]], [[T4]]141; CHECK-NEXT:    [[T7:%.*]] = and <8 x i32> [[TMP2]], <i32 poison, i32 0, i32 1, i32 2147483647, i32 -1, i32 -1, i32 -1, i32 -1>142; CHECK-NEXT:    ret <8 x i32> [[T7]]143;144  %t0 = add <8 x i32> %nbits, <i32 -33, i32 -32, i32 -31, i32 -1, i32 0, i32 1, i32 31, i32 32>145  %t1 = zext <8 x i32> %t0 to <8 x i64>146  %t2 = shl <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, %t1 ; shifting by nbits-1147  %t3 = xor <8 x i64> %t2, <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>148  %t4 = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, %nbits149 150  call void @use8xi32(<8 x i32> %t0)151  call void @use8xi64(<8 x i64> %t1)152  call void @use8xi64(<8 x i64> %t2)153  call void @use8xi64(<8 x i64> %t3)154  call void @use8xi32(<8 x i32> %t4)155 156  %t5 = and <8 x i64> %t3, %x157  %t6 = trunc <8 x i64> %t5 to <8 x i32>158  %t7 = shl <8 x i32> %t6, %t4159  ret <8 x i32> %t7160}161 162; -1 can be truncated.163 164define i32 @t4_allones_trunc(i64 %x, i32 %nbits) {165; CHECK-LABEL: @t4_allones_trunc(166; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1167; CHECK-NEXT:    [[T1:%.*]] = zext i32 [[T0]] to i64168; CHECK-NEXT:    [[T2:%.*]] = shl nsw i64 -1, [[T1]]169; CHECK-NEXT:    [[T3:%.*]] = xor i64 [[T2]], 4294967295170; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]171; CHECK-NEXT:    call void @use32(i32 [[T0]])172; CHECK-NEXT:    call void @use64(i64 [[T1]])173; CHECK-NEXT:    call void @use64(i64 [[T2]])174; CHECK-NEXT:    call void @use64(i64 [[T3]])175; CHECK-NEXT:    call void @use32(i32 [[T4]])176; CHECK-NEXT:    [[T5:%.*]] = and i64 [[T3]], [[X:%.*]]177; CHECK-NEXT:    [[T6:%.*]] = trunc i64 [[T5]] to i32178; CHECK-NEXT:    [[T7:%.*]] = shl i32 [[T6]], [[T4]]179; CHECK-NEXT:    ret i32 [[T7]]180;181  %t0 = add i32 %nbits, -1182  %t1 = zext i32 %t0 to i64183  %t2 = shl i64 -1, %t1 ; shifting by nbits-1184  %t3 = xor i64 %t2, 4294967295 ; we only care about low 32 bits185  %t4 = sub i32 32, %nbits186 187  call void @use32(i32 %t0)188  call void @use64(i64 %t1)189  call void @use64(i64 %t2)190  call void @use64(i64 %t3)191  call void @use32(i32 %t4)192 193  %t5 = and i64 %t3, %x194  %t6 = trunc i64 %t5 to i32195  %t7 = shl i32 %t6, %t4196  ret i32 %t7197}198 199; Extra uses200 201define i32 @n5_extrause0(i64 %x, i32 %nbits) {202; CHECK-LABEL: @n5_extrause0(203; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1204; CHECK-NEXT:    [[T1:%.*]] = zext i32 [[T0]] to i64205; CHECK-NEXT:    [[T2:%.*]] = shl nsw i64 -1, [[T1]]206; CHECK-NEXT:    [[T3:%.*]] = xor i64 [[T2]], -1207; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]208; CHECK-NEXT:    call void @use32(i32 [[T0]])209; CHECK-NEXT:    call void @use64(i64 [[T1]])210; CHECK-NEXT:    call void @use64(i64 [[T2]])211; CHECK-NEXT:    call void @use64(i64 [[T3]])212; CHECK-NEXT:    call void @use32(i32 [[T4]])213; CHECK-NEXT:    [[T5:%.*]] = and i64 [[X:%.*]], [[T3]]214; CHECK-NEXT:    call void @use64(i64 [[T5]])215; CHECK-NEXT:    [[T6:%.*]] = trunc i64 [[T5]] to i32216; CHECK-NEXT:    [[T7:%.*]] = shl i32 [[T6]], [[T4]]217; CHECK-NEXT:    ret i32 [[T7]]218;219  %t0 = add i32 %nbits, -1220  %t1 = zext i32 %t0 to i64221  %t2 = shl i64 -1, %t1 ; shifting by nbits-1222  %t3 = xor i64 %t2, -1223  %t4 = sub i32 32, %nbits224 225  call void @use32(i32 %t0)226  call void @use64(i64 %t1)227  call void @use64(i64 %t2)228  call void @use64(i64 %t3)229  call void @use32(i32 %t4)230 231  %t5 = and i64 %t3, %x232  call void @use64(i64 %t5)233  %t6 = trunc i64 %t5 to i32234  %t7 = shl i32 %t6, %t4235  ret i32 %t7236}237define i32 @n6_extrause1(i64 %x, i32 %nbits) {238; CHECK-LABEL: @n6_extrause1(239; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1240; CHECK-NEXT:    [[T1:%.*]] = zext i32 [[T0]] to i64241; CHECK-NEXT:    [[T2:%.*]] = shl nsw i64 -1, [[T1]]242; CHECK-NEXT:    [[T3:%.*]] = xor i64 [[T2]], -1243; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]244; CHECK-NEXT:    call void @use32(i32 [[T0]])245; CHECK-NEXT:    call void @use64(i64 [[T1]])246; CHECK-NEXT:    call void @use64(i64 [[T2]])247; CHECK-NEXT:    call void @use64(i64 [[T3]])248; CHECK-NEXT:    call void @use32(i32 [[T4]])249; CHECK-NEXT:    [[T5:%.*]] = and i64 [[X:%.*]], [[T3]]250; CHECK-NEXT:    [[T6:%.*]] = trunc i64 [[T5]] to i32251; CHECK-NEXT:    call void @use32(i32 [[T6]])252; CHECK-NEXT:    [[T7:%.*]] = shl i32 [[T6]], [[T4]]253; CHECK-NEXT:    ret i32 [[T7]]254;255  %t0 = add i32 %nbits, -1256  %t1 = zext i32 %t0 to i64257  %t2 = shl i64 -1, %t1 ; shifting by nbits-1258  %t3 = xor i64 %t2, -1259  %t4 = sub i32 32, %nbits260 261  call void @use32(i32 %t0)262  call void @use64(i64 %t1)263  call void @use64(i64 %t2)264  call void @use64(i64 %t3)265  call void @use32(i32 %t4)266 267  %t5 = and i64 %t3, %x268  %t6 = trunc i64 %t5 to i32269  call void @use32(i32 %t6)270  %t7 = shl i32 %t6, %t4271  ret i32 %t7272}273define i32 @n7_extrause2(i64 %x, i32 %nbits) {274; CHECK-LABEL: @n7_extrause2(275; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1276; CHECK-NEXT:    [[T1:%.*]] = zext i32 [[T0]] to i64277; CHECK-NEXT:    [[T2:%.*]] = shl nsw i64 -1, [[T1]]278; CHECK-NEXT:    [[T3:%.*]] = xor i64 [[T2]], -1279; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]280; CHECK-NEXT:    call void @use32(i32 [[T0]])281; CHECK-NEXT:    call void @use64(i64 [[T1]])282; CHECK-NEXT:    call void @use64(i64 [[T2]])283; CHECK-NEXT:    call void @use64(i64 [[T3]])284; CHECK-NEXT:    call void @use32(i32 [[T4]])285; CHECK-NEXT:    [[T5:%.*]] = and i64 [[X:%.*]], [[T3]]286; CHECK-NEXT:    call void @use64(i64 [[T5]])287; CHECK-NEXT:    [[T6:%.*]] = trunc i64 [[T5]] to i32288; CHECK-NEXT:    call void @use32(i32 [[T6]])289; CHECK-NEXT:    [[T7:%.*]] = shl i32 [[T6]], [[T4]]290; CHECK-NEXT:    ret i32 [[T7]]291;292  %t0 = add i32 %nbits, -1293  %t1 = zext i32 %t0 to i64294  %t2 = shl i64 -1, %t1 ; shifting by nbits-1295  %t3 = xor i64 %t2, -1296  %t4 = sub i32 32, %nbits297 298  call void @use32(i32 %t0)299  call void @use64(i64 %t1)300  call void @use64(i64 %t2)301  call void @use64(i64 %t3)302  call void @use32(i32 %t4)303 304  %t5 = and i64 %t3, %x305  call void @use64(i64 %t5)306  %t6 = trunc i64 %t5 to i32307  call void @use32(i32 %t6)308  %t7 = shl i32 %t6, %t4309  ret i32 %t7310}311