diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 421a808de667a..88c6fe632d266 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2242,10 +2242,15 @@ bool PPC::isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize) { return false; for (unsigned i = EltSize, e = 16; i != e; i += EltSize) { - if (N->getMaskElt(i) < 0) continue; - for (unsigned j = 0; j != EltSize; ++j) - if (N->getMaskElt(i+j) != N->getMaskElt(j)) - return false; + // An UNDEF element is a sequence of UNDEF bytes. + if (N->getMaskElt(i) < 0) { + for (unsigned j = 1; j != EltSize; ++j) + if (N->getMaskElt(i + j) >= 0) + return false; + } else + for (unsigned j = 0; j != EltSize; ++j) + if (N->getMaskElt(i + j) != N->getMaskElt(j)) + return false; } return true; } diff --git a/llvm/test/CodeGen/PowerPC/pr141642.ll b/llvm/test/CodeGen/PowerPC/pr141642.ll new file mode 100644 index 0000000000000..38a7065747867 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/pr141642.ll @@ -0,0 +1,13 @@ +; RUN: llc -mcpu=pwr8 -mtriple=powerpc64le-unknown-linux-gnu -O0 -debug-only=selectiondag -o - < %s 2>&1 | \ +; RUN: FileCheck %s +; CHECK-NOT: lxvdsx +; CHECK-NOT: LD_SPLAT + +define weak_odr dso_local void @unpack(ptr noalias noundef %packed_in) local_unnamed_addr { +entry: + %ld = load <2 x i32>, ptr %packed_in, align 2 + %shuf = shufflevector <2 x i32> %ld, <2 x i32> poison, <4 x i32> + %ie = insertelement <4 x i32> %shuf, i32 7, i32 2 + store <4 x i32> %shuf, ptr %packed_in, align 2 + ret void +}