mirror of
https://github.com/intel/llvm.git
synced 2026-01-31 07:27:33 +08:00
[InstCombine] Let shrinkSplatShuffle act on vectors of different lengths (#148593)
shrinkSplatShuffle in InstCombine would only move truncs up through shuffles if those shuffles inputs had the exact same type as their output, this PR weakens this constraint to only requiring that the scalar type of the input and output match.
This commit is contained in:
@@ -708,10 +708,14 @@ static Instruction *shrinkSplatShuffle(TruncInst &Trunc,
|
||||
auto *Shuf = dyn_cast<ShuffleVectorInst>(Trunc.getOperand(0));
|
||||
if (Shuf && Shuf->hasOneUse() && match(Shuf->getOperand(1), m_Undef()) &&
|
||||
all_equal(Shuf->getShuffleMask()) &&
|
||||
Shuf->getType() == Shuf->getOperand(0)->getType()) {
|
||||
ElementCount::isKnownGE(Shuf->getType()->getElementCount(),
|
||||
cast<VectorType>(Shuf->getOperand(0)->getType())
|
||||
->getElementCount())) {
|
||||
// trunc (shuf X, Undef, SplatMask) --> shuf (trunc X), Poison, SplatMask
|
||||
// trunc (shuf X, Poison, SplatMask) --> shuf (trunc X), Poison, SplatMask
|
||||
Value *NarrowOp = Builder.CreateTrunc(Shuf->getOperand(0), Trunc.getType());
|
||||
Type *NewTruncTy = Shuf->getOperand(0)->getType()->getWithNewType(
|
||||
Trunc.getType()->getScalarType());
|
||||
Value *NarrowOp = Builder.CreateTrunc(Shuf->getOperand(0), NewTruncTy);
|
||||
return new ShuffleVectorInst(NarrowOp, Shuf->getShuffleMask());
|
||||
}
|
||||
|
||||
|
||||
@@ -959,8 +959,8 @@ define <3 x i31> @wide_splat3(<3 x i33> %x) {
|
||||
|
||||
define <8 x i8> @wide_lengthening_splat(<4 x i16> %v) {
|
||||
; CHECK-LABEL: @wide_lengthening_splat(
|
||||
; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <4 x i16> [[V:%.*]], <4 x i16> poison, <8 x i32> zeroinitializer
|
||||
; CHECK-NEXT: [[TR:%.*]] = trunc <8 x i16> [[SHUF]] to <8 x i8>
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = trunc <4 x i16> [[V:%.*]] to <4 x i8>
|
||||
; CHECK-NEXT: [[TR:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <8 x i32> zeroinitializer
|
||||
; CHECK-NEXT: ret <8 x i8> [[TR]]
|
||||
;
|
||||
%shuf = shufflevector <4 x i16> %v, <4 x i16> %v, <8 x i32> zeroinitializer
|
||||
|
||||
@@ -960,8 +960,8 @@ define <3 x i31> @wide_splat3(<3 x i33> %x) {
|
||||
|
||||
define <8 x i8> @wide_lengthening_splat(<4 x i16> %v) {
|
||||
; CHECK-LABEL: @wide_lengthening_splat(
|
||||
; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <4 x i16> [[V:%.*]], <4 x i16> poison, <8 x i32> zeroinitializer
|
||||
; CHECK-NEXT: [[TR:%.*]] = trunc <8 x i16> [[SHUF]] to <8 x i8>
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = trunc <4 x i16> [[V:%.*]] to <4 x i8>
|
||||
; CHECK-NEXT: [[TR:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <8 x i32> zeroinitializer
|
||||
; CHECK-NEXT: ret <8 x i8> [[TR]]
|
||||
;
|
||||
%shuf = shufflevector <4 x i16> %v, <4 x i16> %v, <8 x i32> zeroinitializer
|
||||
@@ -969,6 +969,19 @@ define <8 x i8> @wide_lengthening_splat(<4 x i16> %v) {
|
||||
ret <8 x i8> %tr
|
||||
}
|
||||
|
||||
; This is a negative test, we expect the trunc to remain after the shuffle as it
|
||||
; might not be beneficial to preform trunc on a wider type
|
||||
define <4 x i8> @wide_shortening_splat(<8 x i16> %v) {
|
||||
; CHECK-LABEL: @wide_shortening_splat(
|
||||
; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <8 x i16> [[V:%.*]], <8 x i16> poison, <4 x i32> zeroinitializer
|
||||
; CHECK-NEXT: [[TR:%.*]] = trunc <4 x i16> [[SHUF]] to <4 x i8>
|
||||
; CHECK-NEXT: ret <4 x i8> [[TR]]
|
||||
;
|
||||
%shuf = shufflevector <8 x i16> %v, <8 x i16> %v, <4 x i32> zeroinitializer
|
||||
%tr = trunc <4 x i16> %shuf to <4 x i8>
|
||||
ret <4 x i8> %tr
|
||||
}
|
||||
|
||||
define <2 x i8> @narrow_add_vec_constant(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @narrow_add_vec_constant(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
|
||||
|
||||
Reference in New Issue
Block a user