Skip to content

Commit d9f064d

Browse files
committed
[InstCombine] visitTrunc - trunc(shl(X, C)) --> shl(trunc(X),trunc(C)) vector support
Annoyingly vectors aren't supported by shouldChangeType(), but we have precedents for always performing this on vector types (e.g. narrowBinOp). Differential Revision: https://reviews.llvm.org/D89067
1 parent fd8275e commit d9f064d

File tree

4 files changed

+41
-44
lines changed

4 files changed

+41
-44
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,6 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
714714
Type *DestTy = Trunc.getType(), *SrcTy = Src->getType();
715715
unsigned DestWidth = DestTy->getScalarSizeInBits();
716716
unsigned SrcWidth = SrcTy->getScalarSizeInBits();
717-
ConstantInt *Cst;
718717

719718
// Attempt to truncate the entire input expression tree to the destination
720719
// type. Only do this if the dest type is a simple type, don't convert the
@@ -866,20 +865,19 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
866865
if (Instruction *I = shrinkInsertElt(Trunc, Builder))
867866
return I;
868867

869-
if (Src->hasOneUse() && isa<IntegerType>(SrcTy) &&
870-
shouldChangeType(SrcTy, DestTy)) {
868+
if (Src->hasOneUse() &&
869+
(isa<VectorType>(SrcTy) || shouldChangeType(SrcTy, DestTy))) {
871870
// Transform "trunc (shl X, cst)" -> "shl (trunc X), cst" so long as the
872871
// dest type is native and cst < dest size.
873-
if (match(Src, m_Shl(m_Value(A), m_ConstantInt(Cst))) &&
872+
if (match(Src, m_Shl(m_Value(A), m_Constant(C))) &&
874873
!match(A, m_Shr(m_Value(), m_Constant()))) {
875874
// Skip shifts of shift by constants. It undoes a combine in
876875
// FoldShiftByConstant and is the extend in reg pattern.
877-
if (Cst->getValue().ult(DestWidth)) {
876+
APInt Threshold = APInt(C->getType()->getScalarSizeInBits(), DestWidth);
877+
if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold))) {
878878
Value *NewTrunc = Builder.CreateTrunc(A, DestTy, A->getName() + ".tr");
879-
880-
return BinaryOperator::Create(
881-
Instruction::Shl, NewTrunc,
882-
ConstantInt::get(DestTy, Cst->getValue().trunc(DestWidth)));
879+
return BinaryOperator::Create(Instruction::Shl, NewTrunc,
880+
ConstantExpr::getTrunc(C, DestTy));
883881
}
884882
}
885883
}
@@ -896,6 +894,7 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
896894
// --->
897895
// extractelement <8 x i32> (bitcast <4 x i64> %X to <8 x i32>), i32 0
898896
Value *VecOp;
897+
ConstantInt *Cst;
899898
if (match(Src, m_OneUse(m_ExtractElt(m_Value(VecOp), m_ConstantInt(Cst))))) {
900899
auto *VecOpTy = cast<FixedVectorType>(VecOp->getType());
901900
unsigned VecNumElts = VecOpTy->getNumElements();

llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest-with-truncation-shl.ll

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -362,12 +362,11 @@ define i1 @t10_constants(i32 %x, i64 %y) {
362362

363363
define <2 x i1> @t11_constants_vec_splat(<2 x i32> %x, <2 x i64> %y) {
364364
; CHECK-LABEL: @t11_constants_vec_splat(
365-
; CHECK-NEXT: [[T0:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 12, i32 12>
366-
; CHECK-NEXT: [[T1:%.*]] = shl <2 x i64> [[Y:%.*]], <i64 14, i64 14>
367-
; CHECK-NEXT: [[T1_TRUNC:%.*]] = trunc <2 x i64> [[T1]] to <2 x i32>
368-
; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[T0]], [[T1_TRUNC]]
369-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], zeroinitializer
370-
; CHECK-NEXT: ret <2 x i1> [[T3]]
365+
; CHECK-NEXT: [[Y_TR:%.*]] = trunc <2 x i64> [[Y:%.*]] to <2 x i32>
366+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 26, i32 26>
367+
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[Y_TR]]
368+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
369+
; CHECK-NEXT: ret <2 x i1> [[TMP3]]
371370
;
372371
%t0 = lshr <2 x i32> %x, <i32 12, i32 12>
373372
%t1 = shl <2 x i64> %y, <i64 14, i64 14>
@@ -378,12 +377,11 @@ define <2 x i1> @t11_constants_vec_splat(<2 x i32> %x, <2 x i64> %y) {
378377
}
379378
define <2 x i1> @t12_constants_vec_nonsplat(<2 x i32> %x, <2 x i64> %y) {
380379
; CHECK-LABEL: @t12_constants_vec_nonsplat(
381-
; CHECK-NEXT: [[T0:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 12, i32 14>
382-
; CHECK-NEXT: [[T1:%.*]] = shl <2 x i64> [[Y:%.*]], <i64 16, i64 14>
383-
; CHECK-NEXT: [[T1_TRUNC:%.*]] = trunc <2 x i64> [[T1]] to <2 x i32>
384-
; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[T0]], [[T1_TRUNC]]
385-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], zeroinitializer
386-
; CHECK-NEXT: ret <2 x i1> [[T3]]
380+
; CHECK-NEXT: [[Y_TR:%.*]] = trunc <2 x i64> [[Y:%.*]] to <2 x i32>
381+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 28, i32 28>
382+
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[Y_TR]]
383+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
384+
; CHECK-NEXT: ret <2 x i1> [[TMP3]]
387385
;
388386
%t0 = lshr <2 x i32> %x, <i32 12, i32 14>
389387
%t1 = shl <2 x i64> %y, <i64 16, i64 14>

llvm/test/Transforms/InstCombine/shift-amount-reassociation-with-truncation-shl.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ define i16 @t0(i32 %x, i16 %y) {
2727

2828
define <2 x i16> @t1_vec_splat(<2 x i32> %x, <2 x i16> %y) {
2929
; CHECK-LABEL: @t1_vec_splat(
30-
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 8, i32 8>
31-
; CHECK-NEXT: [[T5:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i16>
30+
; CHECK-NEXT: [[X_TR:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16>
31+
; CHECK-NEXT: [[T5:%.*]] = shl <2 x i16> [[X_TR]], <i16 8, i16 8>
3232
; CHECK-NEXT: ret <2 x i16> [[T5]]
3333
;
3434
%t0 = sub <2 x i16> <i16 32, i16 32>, %y
@@ -59,8 +59,8 @@ define <2 x i16> @t2_vec_nonsplat(<2 x i32> %x, <2 x i16> %y) {
5959

6060
define <3 x i16> @t3_vec_nonsplat_undef0(<3 x i32> %x, <3 x i16> %y) {
6161
; CHECK-LABEL: @t3_vec_nonsplat_undef0(
62-
; CHECK-NEXT: [[TMP1:%.*]] = shl <3 x i32> [[X:%.*]], <i32 8, i32 0, i32 8>
63-
; CHECK-NEXT: [[T5:%.*]] = trunc <3 x i32> [[TMP1]] to <3 x i16>
62+
; CHECK-NEXT: [[X_TR:%.*]] = trunc <3 x i32> [[X:%.*]] to <3 x i16>
63+
; CHECK-NEXT: [[T5:%.*]] = shl <3 x i16> [[X_TR]], <i16 8, i16 0, i16 8>
6464
; CHECK-NEXT: ret <3 x i16> [[T5]]
6565
;
6666
%t0 = sub <3 x i16> <i16 32, i16 undef, i16 32>, %y
@@ -74,8 +74,8 @@ define <3 x i16> @t3_vec_nonsplat_undef0(<3 x i32> %x, <3 x i16> %y) {
7474

7575
define <3 x i16> @t4_vec_nonsplat_undef1(<3 x i32> %x, <3 x i16> %y) {
7676
; CHECK-LABEL: @t4_vec_nonsplat_undef1(
77-
; CHECK-NEXT: [[TMP1:%.*]] = shl <3 x i32> [[X:%.*]], <i32 8, i32 0, i32 8>
78-
; CHECK-NEXT: [[T5:%.*]] = trunc <3 x i32> [[TMP1]] to <3 x i16>
77+
; CHECK-NEXT: [[X_TR:%.*]] = trunc <3 x i32> [[X:%.*]] to <3 x i16>
78+
; CHECK-NEXT: [[T5:%.*]] = shl <3 x i16> [[X_TR]], <i16 8, i16 0, i16 8>
7979
; CHECK-NEXT: ret <3 x i16> [[T5]]
8080
;
8181
%t0 = sub <3 x i16> <i16 32, i16 32, i16 32>, %y
@@ -89,8 +89,8 @@ define <3 x i16> @t4_vec_nonsplat_undef1(<3 x i32> %x, <3 x i16> %y) {
8989

9090
define <3 x i16> @t5_vec_nonsplat_undef1(<3 x i32> %x, <3 x i16> %y) {
9191
; CHECK-LABEL: @t5_vec_nonsplat_undef1(
92-
; CHECK-NEXT: [[TMP1:%.*]] = shl <3 x i32> [[X:%.*]], <i32 8, i32 0, i32 8>
93-
; CHECK-NEXT: [[T5:%.*]] = trunc <3 x i32> [[TMP1]] to <3 x i16>
92+
; CHECK-NEXT: [[X_TR:%.*]] = trunc <3 x i32> [[X:%.*]] to <3 x i16>
93+
; CHECK-NEXT: [[T5:%.*]] = shl <3 x i16> [[X_TR]], <i16 8, i16 0, i16 8>
9494
; CHECK-NEXT: ret <3 x i16> [[T5]]
9595
;
9696
%t0 = sub <3 x i16> <i16 32, i16 undef, i16 32>, %y

llvm/test/Transforms/InstCombine/trunc.ll

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -704,11 +704,11 @@ define i32 @trunc_shl_32_i32_i64(i64 %val) {
704704
ret i32 %trunc
705705
}
706706

707-
; TODO: Should be able to handle vectors
707+
; Should be able to handle vectors
708708
define <2 x i32> @trunc_shl_16_v2i32_v2i64(<2 x i64> %val) {
709709
; CHECK-LABEL: @trunc_shl_16_v2i32_v2i64(
710-
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i64> [[VAL:%.*]], <i64 16, i64 16>
711-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> [[SHL]] to <2 x i32>
710+
; CHECK-NEXT: [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>
711+
; CHECK-NEXT: [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 16, i32 16>
712712
; CHECK-NEXT: ret <2 x i32> [[TRUNC]]
713713
;
714714
%shl = shl <2 x i64> %val, <i64 16, i64 16>
@@ -718,8 +718,8 @@ define <2 x i32> @trunc_shl_16_v2i32_v2i64(<2 x i64> %val) {
718718

719719
define <2 x i32> @trunc_shl_nosplat_v2i32_v2i64(<2 x i64> %val) {
720720
; CHECK-LABEL: @trunc_shl_nosplat_v2i32_v2i64(
721-
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i64> [[VAL:%.*]], <i64 15, i64 16>
722-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> [[SHL]] to <2 x i32>
721+
; CHECK-NEXT: [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>
722+
; CHECK-NEXT: [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 15, i32 16>
723723
; CHECK-NEXT: ret <2 x i32> [[TRUNC]]
724724
;
725725
%shl = shl <2 x i64> %val, <i64 15, i64 16>
@@ -757,8 +757,8 @@ define i32 @trunc_shl_lshr_infloop(i64 %arg) {
757757

758758
define <2 x i32> @trunc_shl_v2i32_v2i64_uniform(<2 x i64> %val) {
759759
; CHECK-LABEL: @trunc_shl_v2i32_v2i64_uniform(
760-
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i64> [[VAL:%.*]], <i64 31, i64 31>
761-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> [[SHL]] to <2 x i32>
760+
; CHECK-NEXT: [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>
761+
; CHECK-NEXT: [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 31, i32 31>
762762
; CHECK-NEXT: ret <2 x i32> [[TRUNC]]
763763
;
764764
%shl = shl <2 x i64> %val, <i64 31, i64 31>
@@ -768,8 +768,8 @@ define <2 x i32> @trunc_shl_v2i32_v2i64_uniform(<2 x i64> %val) {
768768

769769
define <2 x i32> @trunc_shl_v2i32_v2i64_undef(<2 x i64> %val) {
770770
; CHECK-LABEL: @trunc_shl_v2i32_v2i64_undef(
771-
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i64> [[VAL:%.*]], <i64 31, i64 undef>
772-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> [[SHL]] to <2 x i32>
771+
; CHECK-NEXT: [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>
772+
; CHECK-NEXT: [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 31, i32 undef>
773773
; CHECK-NEXT: ret <2 x i32> [[TRUNC]]
774774
;
775775
%shl = shl <2 x i64> %val, <i64 31, i64 undef>
@@ -779,8 +779,8 @@ define <2 x i32> @trunc_shl_v2i32_v2i64_undef(<2 x i64> %val) {
779779

780780
define <2 x i32> @trunc_shl_v2i32_v2i64_nonuniform(<2 x i64> %val) {
781781
; CHECK-LABEL: @trunc_shl_v2i32_v2i64_nonuniform(
782-
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i64> [[VAL:%.*]], <i64 31, i64 12>
783-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> [[SHL]] to <2 x i32>
782+
; CHECK-NEXT: [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>
783+
; CHECK-NEXT: [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 31, i32 12>
784784
; CHECK-NEXT: ret <2 x i32> [[TRUNC]]
785785
;
786786
%shl = shl <2 x i64> %val, <i64 31, i64 12>
@@ -865,8 +865,8 @@ define i32 @trunc_shl_shl_var(i64 %arg, i64 %val) {
865865

866866
define <8 x i16> @trunc_shl_v8i15_v8i32_15(<8 x i32> %a) {
867867
; CHECK-LABEL: @trunc_shl_v8i15_v8i32_15(
868-
; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i32> [[A:%.*]], <i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15>
869-
; CHECK-NEXT: [[CONV:%.*]] = trunc <8 x i32> [[SHL]] to <8 x i16>
868+
; CHECK-NEXT: [[A_TR:%.*]] = trunc <8 x i32> [[A:%.*]] to <8 x i16>
869+
; CHECK-NEXT: [[CONV:%.*]] = shl <8 x i16> [[A_TR]], <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>
870870
; CHECK-NEXT: ret <8 x i16> [[CONV]]
871871
;
872872
%shl = shl <8 x i32> %a, <i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15>
@@ -894,8 +894,8 @@ define <8 x i16> @trunc_shl_v8i16_v8i32_17(<8 x i32> %a) {
894894

895895
define <8 x i16> @trunc_shl_v8i16_v8i32_4(<8 x i32> %a) {
896896
; CHECK-LABEL: @trunc_shl_v8i16_v8i32_4(
897-
; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i32> [[A:%.*]], <i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4>
898-
; CHECK-NEXT: [[CONV:%.*]] = trunc <8 x i32> [[SHL]] to <8 x i16>
897+
; CHECK-NEXT: [[A_TR:%.*]] = trunc <8 x i32> [[A:%.*]] to <8 x i16>
898+
; CHECK-NEXT: [[CONV:%.*]] = shl <8 x i16> [[A_TR]], <i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4>
899899
; CHECK-NEXT: ret <8 x i16> [[CONV]]
900900
;
901901
%shl = shl <8 x i32> %a, <i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4>

0 commit comments

Comments
 (0)