From 3778c04b2e3bc879cb7f175ba4d42f23fb9cef76 Mon Sep 17 00:00:00 2001 From: Hao Liu Date: Mon, 13 May 2013 02:07:05 +0000 Subject: [PATCH] Fix PR15950 A bug in DAG Combiner about undef mask git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181682 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 37 +++++++++++++------ .../ARM/2013-05-13-DAGCombiner-undef-mask.ll | 10 +++++ 2 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 test/CodeGen/ARM/2013-05-13-DAGCombiner-undef-mask.ll diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index c54dffbb132..076684993ab 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -9254,19 +9254,34 @@ static SDValue partitionShuffleOfConcats(SDNode *N, SelectionDAG &DAG) { for (unsigned I = 0; I != NumConcats; ++I) { // Make sure we're dealing with a copy. unsigned Begin = I * NumElemsPerConcat; - if (SVN->getMaskElt(Begin) % NumElemsPerConcat != 0) - return SDValue(); - - for (unsigned J = 1; J != NumElemsPerConcat; ++J) { - if (SVN->getMaskElt(Begin + J - 1) + 1 != SVN->getMaskElt(Begin + J)) - return SDValue(); + bool AllUndef = true, NoUndef = true; + for (unsigned J = Begin; J != Begin + NumElemsPerConcat; ++J) { + if (SVN->getMaskElt(J) >= 0) + AllUndef = false; + else + NoUndef = false; } - unsigned FirstElt = SVN->getMaskElt(Begin) / NumElemsPerConcat; - if (FirstElt < N0.getNumOperands()) - Ops.push_back(N0.getOperand(FirstElt)); - else - Ops.push_back(N1.getOperand(FirstElt - N0.getNumOperands())); + if (NoUndef) { + unsigned Begin = I * NumElemsPerConcat; + if (SVN->getMaskElt(Begin) % NumElemsPerConcat != 0) + return SDValue(); + + for (unsigned J = 1; J != NumElemsPerConcat; ++J) + if (SVN->getMaskElt(Begin + J - 1) + 1 != SVN->getMaskElt(Begin + J)) + return SDValue(); + + unsigned FirstElt = SVN->getMaskElt(Begin) / NumElemsPerConcat; + if (FirstElt < N0.getNumOperands()) + Ops.push_back(N0.getOperand(FirstElt)); + else + Ops.push_back(N1.getOperand(FirstElt - N0.getNumOperands())); + + } else if (AllUndef) { + Ops.push_back(DAG.getUNDEF(N0.getOperand(0).getValueType())); + } else { // Mixed with general masks and undefs, can't do optimization. + return SDValue(); + } } return DAG.getNode(ISD::CONCAT_VECTORS, N->getDebugLoc(), VT, Ops.data(), diff --git a/test/CodeGen/ARM/2013-05-13-DAGCombiner-undef-mask.ll b/test/CodeGen/ARM/2013-05-13-DAGCombiner-undef-mask.ll new file mode 100644 index 00000000000..8f6709ec5e7 --- /dev/null +++ b/test/CodeGen/ARM/2013-05-13-DAGCombiner-undef-mask.ll @@ -0,0 +1,10 @@ +; RUN: llc < %s +target triple = "armv7-none-linux-gnueabi" + +define <3 x i64> @shuffle(i1 %dec1, i1 %dec0, <3 x i64> %b) { +entry: + %.sink = select i1 %dec1, <3 x i64> %b, <3 x i64> zeroinitializer + %.sink15 = select i1 %dec0, <3 x i64> %b, <3 x i64> zeroinitializer + %vecinit7 = shufflevector <3 x i64> %.sink, <3 x i64> %.sink15, <3 x i32> + ret <3 x i64> %vecinit7 +}