brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.9 KiB · a6c3f33 Raw
158 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)  (x & (~(-1 << maskNbits))) << shiftNbits9; simplify to:10;   (x << shiftNbits) & (~(-1 << (maskNbits+shiftNbits)))11 12; Simple tests.13 14declare void @use32(i32)15 16define i32 @t0_basic(i32 %x, i32 %nbits) {17; CHECK-LABEL: @t0_basic(18; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -119; CHECK-NEXT:    [[T1:%.*]] = shl nsw i32 -1, [[T0]]20; CHECK-NEXT:    [[T2:%.*]] = xor i32 [[T1]], -121; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]22; CHECK-NEXT:    call void @use32(i32 [[T0]])23; CHECK-NEXT:    call void @use32(i32 [[T1]])24; CHECK-NEXT:    call void @use32(i32 [[T2]])25; CHECK-NEXT:    call void @use32(i32 [[T4]])26; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], [[T4]]27; CHECK-NEXT:    [[T5:%.*]] = and i32 [[TMP1]], 214748364728; CHECK-NEXT:    ret i32 [[T5]]29;30  %t0 = add i32 %nbits, -131  %t1 = shl i32 -1, %t0 ; shifting by nbits-132  %t2 = xor i32 %t1, -133  %t3 = and i32 %t2, %x34  %t4 = 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 %t4)39  %t5 = shl i32 %t3, %t440  ret i32 %t541}42 43; Vectors44 45declare void @use8xi32(<8 x i32>)46 47define <8 x i32> @t1_vec_splat(<8 x i32> %x, <8 x i32> %nbits) {48; CHECK-LABEL: @t1_vec_splat(49; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], splat (i32 -1)50; CHECK-NEXT:    [[T1:%.*]] = shl nsw <8 x i32> splat (i32 -1), [[T0]]51; CHECK-NEXT:    [[T2:%.*]] = xor <8 x i32> [[T1]], splat (i32 -1)52; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> splat (i32 32), [[NBITS]]53; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])54; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T1]])55; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T2]])56; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T4]])57; CHECK-NEXT:    [[TMP1:%.*]] = shl <8 x i32> [[X:%.*]], [[T4]]58; CHECK-NEXT:    [[T5:%.*]] = and <8 x i32> [[TMP1]], splat (i32 2147483647)59; CHECK-NEXT:    ret <8 x i32> [[T5]]60;61  %t0 = add <8 x i32> %nbits, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>62  %t1 = shl <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>, %t063  %t2 = xor <8 x i32> %t1, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>64  %t3 = and <8 x i32> %t2, %x65  %t4 = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, %nbits66  call void @use8xi32(<8 x i32> %t0)67  call void @use8xi32(<8 x i32> %t1)68  call void @use8xi32(<8 x i32> %t2)69  call void @use8xi32(<8 x i32> %t4)70  %t5 = shl <8 x i32> %t3, %t471  ret <8 x i32> %t572}73 74define <8 x i32> @t1_vec_splat_poison(<8 x i32> %x, <8 x i32> %nbits) {75; CHECK-LABEL: @t1_vec_splat_poison(76; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 poison, i32 -1>77; CHECK-NEXT:    [[T1:%.*]] = shl nsw <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 poison, i32 -1>, [[T0]]78; CHECK-NEXT:    [[T2:%.*]] = xor <8 x i32> [[T1]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 poison, i32 -1>79; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 poison, i32 32>, [[NBITS]]80; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])81; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T1]])82; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T2]])83; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T4]])84; CHECK-NEXT:    [[TMP1:%.*]] = shl <8 x i32> [[X:%.*]], [[T4]]85; CHECK-NEXT:    [[T5:%.*]] = and <8 x i32> [[TMP1]], <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 poison, i32 2147483647>86; CHECK-NEXT:    ret <8 x i32> [[T5]]87;88  %t0 = add <8 x i32> %nbits, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 poison, i32 -1>89  %t1 = shl <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 poison, i32 -1>, %t090  %t2 = xor <8 x i32> %t1, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 poison, i32 -1>91  %t3 = and <8 x i32> %t2, %x92  %t4 = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 poison, i32 32>, %nbits93  call void @use8xi32(<8 x i32> %t0)94  call void @use8xi32(<8 x i32> %t1)95  call void @use8xi32(<8 x i32> %t2)96  call void @use8xi32(<8 x i32> %t4)97  %t5 = shl <8 x i32> %t3, %t498  ret <8 x i32> %t599}100 101define <8 x i32> @t2_vec_nonsplat(<8 x i32> %x, <8 x i32> %nbits) {102; CHECK-LABEL: @t2_vec_nonsplat(103; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -33, i32 -32, i32 -31, i32 -1, i32 0, i32 1, i32 31, i32 32>104; CHECK-NEXT:    [[T1:%.*]] = shl nsw <8 x i32> splat (i32 -1), [[T0]]105; CHECK-NEXT:    [[T2:%.*]] = xor <8 x i32> [[T1]], splat (i32 -1)106; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> splat (i32 32), [[NBITS]]107; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])108; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T1]])109; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T2]])110; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T4]])111; CHECK-NEXT:    [[TMP1:%.*]] = shl <8 x i32> [[X:%.*]], [[T4]]112; CHECK-NEXT:    [[T5:%.*]] = and <8 x i32> [[TMP1]], <i32 poison, i32 0, i32 1, i32 2147483647, i32 -1, i32 -1, i32 -1, i32 poison>113; CHECK-NEXT:    ret <8 x i32> [[T5]]114;115  %t0 = add <8 x i32> %nbits, <i32 -33, i32 -32, i32 -31, i32 -1, i32 0, i32 1, i32 31, i32 32>116  %t1 = shl <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>, %t0117  %t2 = xor <8 x i32> %t1, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>118  %t3 = and <8 x i32> %t2, %x119  %t4 = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, %nbits120  call void @use8xi32(<8 x i32> %t0)121  call void @use8xi32(<8 x i32> %t1)122  call void @use8xi32(<8 x i32> %t2)123  call void @use8xi32(<8 x i32> %t4)124  %t5 = shl <8 x i32> %t3, %t4125  ret <8 x i32> %t5126}127 128; Extra uses.129 130define i32 @n3_extrause(i32 %x, i32 %nbits) {131; CHECK-LABEL: @n3_extrause(132; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1133; CHECK-NEXT:    [[T1:%.*]] = shl nsw i32 -1, [[T0]]134; CHECK-NEXT:    [[T2:%.*]] = xor i32 [[T1]], -1135; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], [[T2]]136; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]137; CHECK-NEXT:    call void @use32(i32 [[T0]])138; CHECK-NEXT:    call void @use32(i32 [[T1]])139; CHECK-NEXT:    call void @use32(i32 [[T2]])140; CHECK-NEXT:    call void @use32(i32 [[T3]])141; CHECK-NEXT:    call void @use32(i32 [[T4]])142; CHECK-NEXT:    [[T5:%.*]] = shl i32 [[T3]], [[T4]]143; CHECK-NEXT:    ret i32 [[T5]]144;145  %t0 = add i32 %nbits, -1146  %t1 = shl i32 -1, %t0 ; shifting by nbits-1147  %t2 = xor i32 %t1, -1148  %t3 = and i32 %t2, %x ; this mask must be one-use.149  %t4 = sub i32 32, %nbits150  call void @use32(i32 %t0)151  call void @use32(i32 %t1)152  call void @use32(i32 %t2)153  call void @use32(i32 %t3) ; BAD154  call void @use32(i32 %t4)155  %t5 = shl i32 %t3, %t4156  ret i32 %t5157}158