brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.2 KiB · 03188c0 Raw
270 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Iff trunc only chops off zero bits that were just shifted-in by the lshr,5; but no other bits, then we can instead do signed shift, and signext it.6; Note that we can replace trunc with trunc of new signed shift.7 8declare void @use32(i32)9declare void @use8(i8)10declare void @use4(i4)11declare void @usevec8(<2 x i8>)12declare void @usevec4(<2 x i4>)13 14define i16 @t0(i8 %x) {15; CHECK-LABEL: @t0(16; CHECK-NEXT:    [[TMP1:%.*]] = ashr i8 [[X:%.*]], 417; CHECK-NEXT:    [[C:%.*]] = sext i8 [[TMP1]] to i1618; CHECK-NEXT:    ret i16 [[C]]19;20  %a = lshr i8 %x, 421  %b = trunc i8 %a to i422  %c = sext i4 %b to i1623  ret i16 %c24}25 26define i16 @t1(i8 %x) {27; CHECK-LABEL: @t1(28; CHECK-NEXT:    [[TMP1:%.*]] = ashr i8 [[X:%.*]], 529; CHECK-NEXT:    [[C:%.*]] = sext i8 [[TMP1]] to i1630; CHECK-NEXT:    ret i16 [[C]]31;32  %a = lshr i8 %x, 533  %b = trunc i8 %a to i334  %c = sext i3 %b to i1635  ret i16 %c36}37 38define i16 @t2(i7 %x) {39; CHECK-LABEL: @t2(40; CHECK-NEXT:    [[TMP1:%.*]] = ashr i7 [[X:%.*]], 341; CHECK-NEXT:    [[C:%.*]] = sext i7 [[TMP1]] to i1642; CHECK-NEXT:    ret i16 [[C]]43;44  %a = lshr i7 %x, 345  %b = trunc i7 %a to i446  %c = sext i4 %b to i1647  ret i16 %c48}49 50; negative test - shift amount doesn't match trunc amount51 52define i16 @n3(i8 %x) {53; CHECK-LABEL: @n3(54; CHECK-NEXT:    [[A:%.*]] = lshr i8 [[X:%.*]], 355; CHECK-NEXT:    [[B:%.*]] = trunc i8 [[A]] to i456; CHECK-NEXT:    [[C:%.*]] = sext i4 [[B]] to i1657; CHECK-NEXT:    ret i16 [[C]]58;59  %a = lshr i8 %x, 360  %b = trunc i8 %a to i461  %c = sext i4 %b to i1662  ret i16 %c63}64 65define <2 x i16> @t4_vec_splat(<2 x i8> %x) {66; CHECK-LABEL: @t4_vec_splat(67; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 4)68; CHECK-NEXT:    [[C:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i16>69; CHECK-NEXT:    ret <2 x i16> [[C]]70;71  %a = lshr <2 x i8> %x, <i8 4, i8 4>72  %b = trunc <2 x i8> %a to <2 x i4>73  %c = sext <2 x i4> %b to <2 x i16>74  ret <2 x i16> %c75}76 77define <2 x i16> @t5_vec_poison(<2 x i8> %x) {78; CHECK-LABEL: @t5_vec_poison(79; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 4)80; CHECK-NEXT:    [[C:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i16>81; CHECK-NEXT:    ret <2 x i16> [[C]]82;83  %a = lshr <2 x i8> %x, <i8 4, i8 poison>84  %b = trunc <2 x i8> %a to <2 x i4>85  %c = sext <2 x i4> %b to <2 x i16>86  ret <2 x i16> %c87}88 89; TODO: We could convert %a to ashr and eliminate 2nd use of %b.90 91define i16 @t6_extrause0(i8 %x) {92; CHECK-LABEL: @t6_extrause0(93; CHECK-NEXT:    [[A:%.*]] = lshr i8 [[X:%.*]], 494; CHECK-NEXT:    [[B:%.*]] = trunc nuw i8 [[A]] to i495; CHECK-NEXT:    call void @use4(i4 [[B]])96; CHECK-NEXT:    [[C:%.*]] = sext i4 [[B]] to i1697; CHECK-NEXT:    ret i16 [[C]]98;99  %a = lshr i8 %x, 4100  %b = trunc i8 %a to i4 ; has extra use, but we can deal with that101  call void @use4(i4 %b)102  %c = sext i4 %b to i16103  ret i16 %c104}105 106; TODO: We could convert %a to ashr and eliminate 2nd use of %b.107 108define <2 x i16> @t7_extrause0_vec_poison(<2 x i8> %x) {109; CHECK-LABEL: @t7_extrause0_vec_poison(110; CHECK-NEXT:    [[A:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 4, i8 poison>111; CHECK-NEXT:    [[B:%.*]] = trunc nuw <2 x i8> [[A]] to <2 x i4>112; CHECK-NEXT:    call void @usevec4(<2 x i4> [[B]])113; CHECK-NEXT:    [[C:%.*]] = sext <2 x i4> [[B]] to <2 x i16>114; CHECK-NEXT:    ret <2 x i16> [[C]]115;116  %a = lshr <2 x i8> %x, <i8 4, i8 poison>117  %b = trunc <2 x i8> %a to <2 x i4>118  call void @usevec4(<2 x i4> %b)119  %c = sext <2 x i4> %b to <2 x i16>120  ret <2 x i16> %c121}122 123; TODO: We could convert %a to ashr + mask (and) and eliminate %b.124 125define i16 @t8_extrause1(i8 %x) {126; CHECK-LABEL: @t8_extrause1(127; CHECK-NEXT:    [[A:%.*]] = lshr i8 [[X:%.*]], 4128; CHECK-NEXT:    call void @use8(i8 [[A]])129; CHECK-NEXT:    [[TMP1:%.*]] = ashr i8 [[X]], 4130; CHECK-NEXT:    [[C:%.*]] = sext i8 [[TMP1]] to i16131; CHECK-NEXT:    ret i16 [[C]]132;133  %a = lshr i8 %x, 4 ; has extra use, but we can deal with that134  call void @use8(i8 %a)135  %b = trunc i8 %a to i4136  %c = sext i4 %b to i16137  ret i16 %c138}139 140; TODO: We could convert %a to ashr + mask (and) and eliminate %b.141 142define <2 x i16> @t9_extrause1_vec_poison(<2 x i8> %x) {143; CHECK-LABEL: @t9_extrause1_vec_poison(144; CHECK-NEXT:    [[A:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 4, i8 poison>145; CHECK-NEXT:    call void @usevec8(<2 x i8> [[A]])146; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i8> [[X]], splat (i8 4)147; CHECK-NEXT:    [[C:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i16>148; CHECK-NEXT:    ret <2 x i16> [[C]]149;150  %a = lshr <2 x i8> %x, <i8 4, i8 poison>151  call void @usevec8(<2 x i8> %a)152  %b = trunc <2 x i8> %a to <2 x i4>153  %c = sext <2 x i4> %b to <2 x i16>154  ret <2 x i16> %c155}156define i16 @t10_extrause2(i8 %x) {157; CHECK-LABEL: @t10_extrause2(158; CHECK-NEXT:    [[A:%.*]] = lshr i8 [[X:%.*]], 4159; CHECK-NEXT:    call void @use8(i8 [[A]])160; CHECK-NEXT:    [[B:%.*]] = trunc nuw i8 [[A]] to i4161; CHECK-NEXT:    call void @use4(i4 [[B]])162; CHECK-NEXT:    [[C:%.*]] = sext i4 [[B]] to i16163; CHECK-NEXT:    ret i16 [[C]]164;165  %a = lshr i8 %x, 4 ; has extra use166  call void @use8(i8 %a)167  %b = trunc i8 %a to i4 ; has extra use168  call void @use4(i4 %b)169  %c = sext i4 %b to i16170  ret i16 %c171}172define <2 x i16> @t11_extrause2_vec_poison(<2 x i8> %x) {173; CHECK-LABEL: @t11_extrause2_vec_poison(174; CHECK-NEXT:    [[A:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 4, i8 poison>175; CHECK-NEXT:    call void @usevec8(<2 x i8> [[A]])176; CHECK-NEXT:    [[B:%.*]] = trunc nuw <2 x i8> [[A]] to <2 x i4>177; CHECK-NEXT:    call void @usevec4(<2 x i4> [[B]])178; CHECK-NEXT:    [[C:%.*]] = sext <2 x i4> [[B]] to <2 x i16>179; CHECK-NEXT:    ret <2 x i16> [[C]]180;181  %a = lshr <2 x i8> %x, <i8 4, i8 poison>182  call void @usevec8(<2 x i8> %a)183  %b = trunc <2 x i8> %a to <2 x i4>184  call void @usevec4(<2 x i4> %b)185  %c = sext <2 x i4> %b to <2 x i16>186  ret <2 x i16> %c187}188 189define <2 x i10> @wide_source_shifted_signbit(<2 x i32> %x) {190; CHECK-LABEL: @wide_source_shifted_signbit(191; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], splat (i32 24)192; CHECK-NEXT:    [[C:%.*]] = trunc nsw <2 x i32> [[TMP1]] to <2 x i10>193; CHECK-NEXT:    ret <2 x i10> [[C]]194;195  %a = lshr <2 x i32> %x, <i32 24, i32 24>196  %b = trunc <2 x i32> %a to <2 x i8>197  %c = sext <2 x i8> %b to <2 x i10>198  ret <2 x i10> %c199}200 201define i10 @wide_source_shifted_signbit_use1(i32 %x) {202; CHECK-LABEL: @wide_source_shifted_signbit_use1(203; CHECK-NEXT:    [[A:%.*]] = lshr i32 [[X:%.*]], 24204; CHECK-NEXT:    call void @use32(i32 [[A]])205; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X]], 24206; CHECK-NEXT:    [[C:%.*]] = trunc nsw i32 [[TMP1]] to i10207; CHECK-NEXT:    ret i10 [[C]]208;209  %a = lshr i32 %x, 24210  call void @use32(i32 %a)211  %b = trunc i32 %a to i8212  %c = sext i8 %b to i10213  ret i10 %c214}215 216define i10 @wide_source_shifted_signbit_use2(i32 %x) {217; CHECK-LABEL: @wide_source_shifted_signbit_use2(218; CHECK-NEXT:    [[A:%.*]] = lshr i32 [[X:%.*]], 24219; CHECK-NEXT:    [[B:%.*]] = trunc nuw i32 [[A]] to i8220; CHECK-NEXT:    call void @use8(i8 [[B]])221; CHECK-NEXT:    [[C:%.*]] = sext i8 [[B]] to i10222; CHECK-NEXT:    ret i10 [[C]]223;224  %a = lshr i32 %x, 24225  %b = trunc i32 %a to i8226  call void @use8(i8 %b)227  %c = sext i8 %b to i10228  ret i10 %c229}230 231define i32 @same_source_shifted_signbit(i32 %x) {232; CHECK-LABEL: @same_source_shifted_signbit(233; CHECK-NEXT:    [[C:%.*]] = ashr i32 [[X:%.*]], 24234; CHECK-NEXT:    ret i32 [[C]]235;236  %a = lshr i32 %x, 24237  %b = trunc i32 %a to i8238  %c = sext i8 %b to i32239  ret i32 %c240}241 242define i32 @same_source_shifted_signbit_use1(i32 %x) {243; CHECK-LABEL: @same_source_shifted_signbit_use1(244; CHECK-NEXT:    [[A:%.*]] = lshr i32 [[X:%.*]], 24245; CHECK-NEXT:    call void @use32(i32 [[A]])246; CHECK-NEXT:    [[C:%.*]] = ashr i32 [[X]], 24247; CHECK-NEXT:    ret i32 [[C]]248;249  %a = lshr i32 %x, 24250  call void @use32(i32 %a)251  %b = trunc i32 %a to i8252  %c = sext i8 %b to i32253  ret i32 %c254}255 256define i32 @same_source_shifted_signbit_use2(i32 %x) {257; CHECK-LABEL: @same_source_shifted_signbit_use2(258; CHECK-NEXT:    [[A:%.*]] = lshr i32 [[X:%.*]], 24259; CHECK-NEXT:    [[B:%.*]] = trunc nuw i32 [[A]] to i8260; CHECK-NEXT:    call void @use8(i8 [[B]])261; CHECK-NEXT:    [[C:%.*]] = sext i8 [[B]] to i32262; CHECK-NEXT:    ret i32 [[C]]263;264  %a = lshr i32 %x, 24265  %b = trunc i32 %a to i8266  call void @use8(i8 %b)267  %c = sext i8 %b to i32268  ret i32 %c269}270