diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index e082cc30196e..e43e721534ea 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -470,7 +470,8 @@ static Instruction *shrinkSplatShuffle(TruncInst &Trunc, InstCombiner::BuilderTy &Builder) { auto *Shuf = dyn_cast(Trunc.getOperand(0)); if (Shuf && Shuf->hasOneUse() && isa(Shuf->getOperand(1)) && - Shuf->getMask()->getSplatValue()) { + Shuf->getMask()->getSplatValue() && + Shuf->getType() == Shuf->getOperand(0)->getType()) { // trunc (shuf X, Undef, SplatMask) --> shuf (trunc X), Undef, SplatMask Constant *NarrowUndef = UndefValue::get(Trunc.getType()); Value *NarrowOp = Builder.CreateTrunc(Shuf->getOperand(0), Trunc.getType()); diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll index ba72908d3c4c..5597b578f017 100644 --- a/llvm/test/Transforms/InstCombine/trunc.ll +++ b/llvm/test/Transforms/InstCombine/trunc.ll @@ -520,3 +520,16 @@ define <3 x i31> @wide_splat3(<3 x i33> %x) { ret <3 x i31> %trunc } +; TODO: The shuffle extends the length of the input vector. Should we shrink this? + +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> undef, <8 x i32> zeroinitializer +; CHECK-NEXT: [[TR:%.*]] = trunc <8 x i16> [[SHUF]] to <8 x i8> +; CHECK-NEXT: ret <8 x i8> [[TR]] +; + %shuf = shufflevector <4 x i16> %v, <4 x i16> %v, <8 x i32> zeroinitializer + %tr = trunc <8 x i16> %shuf to <8 x i8> + ret <8 x i8> %tr +} +