From 8381475a7511c17e046bf25b53185a4d109df467 Mon Sep 17 00:00:00 2001 From: Andrea Di Biagio Date: Sat, 24 Jan 2015 11:54:29 +0000 Subject: [PATCH] [DAG] Fix wrong canonicalization performed on shuffle nodes. This fixes a regression introduced by r226816. When replacing a splat shuffle node with a constant build_vector, make sure that the new build_vector has a valid number of elements. Thanks to Patrik Hagglund for reporting this problem and providing a small reproducible. llvm-svn: 227002 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 16 +++++++++------- llvm/test/CodeGen/X86/selectiondag-crash.ll | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 llvm/test/CodeGen/X86/selectiondag-crash.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index c354155b0358..565e4bbe87a2 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1538,13 +1538,15 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, if (Splat && Splat.getOpcode() == ISD::UNDEF) return getUNDEF(VT); + bool SameNumElts = + V.getValueType().getVectorNumElements() == VT.getVectorNumElements(); + // We only have a splat which can skip shuffles if there is a splatted // value and no undef lanes rearranged by the shuffle. if (Splat && UndefElements.none()) { // Splat of , return , provided that the // number of elements match or the value splatted is a zero constant. - if (V.getValueType().getVectorNumElements() == - VT.getVectorNumElements()) + if (SameNumElts) return N1; if (auto *C = dyn_cast(Splat)) if (C->isNullValue()) @@ -1553,15 +1555,15 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, // If the shuffle itself creates a constant splat, build the vector // directly. - if (AllSame) { + if (AllSame && SameNumElts) { const SDValue &Splatted = BV->getOperand(MaskVec[0]); if (isa(Splatted) || isa(Splatted)) { SmallVector Ops; - for (unsigned i = 0; i != NElts; ++i) { + for (unsigned i = 0; i != NElts; ++i) Ops.push_back(Splatted); - } - SDValue NewBV = getNode(ISD::BUILD_VECTOR, dl, - BV->getValueType(0), Ops); + + SDValue NewBV = + getNode(ISD::BUILD_VECTOR, dl, BV->getValueType(0), Ops); // We may have jumped through bitcasts, so the type of the // BUILD_VECTOR may not match the type of the shuffle. diff --git a/llvm/test/CodeGen/X86/selectiondag-crash.ll b/llvm/test/CodeGen/X86/selectiondag-crash.ll new file mode 100644 index 000000000000..99789021a737 --- /dev/null +++ b/llvm/test/CodeGen/X86/selectiondag-crash.ll @@ -0,0 +1,15 @@ +; RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=corei7 < %s + +; Check that llc doesn't crash in the attempt to fold a shuffle with +; a splat mask into a constant build_vector. + +define <8 x i8> @autogen_SD26299(i8) { +BB: + %Shuff = shufflevector <8 x i32> , <8 x i32> zeroinitializer, <8 x i32> + %Shuff14 = shufflevector <8 x i32> %Shuff, <8 x i32> %Shuff, <8 x i32> + %Shuff35 = shufflevector <8 x i32> %Shuff14, <8 x i32> %Shuff, <8 x i32> + %I42 = insertelement <8 x i32> %Shuff35, i32 88608, i32 0 + %Shuff48 = shufflevector <8 x i32> %Shuff35, <8 x i32> %I42, <8 x i32> + %Tr59 = trunc <8 x i32> %Shuff48 to <8 x i8> + ret <8 x i8> %Tr59 +}