diff options
| author | Hao Liu <Hao.Liu@arm.com> | 2013-05-13 02:07:05 +0000 |
|---|---|---|
| committer | Hao Liu <Hao.Liu@arm.com> | 2013-05-13 02:07:05 +0000 |
| commit | bc60196951e80b4bc7d6c95c0fe377bd85dfaa21 (patch) | |
| tree | e0d8fbbd2e8db45431fcfd27fe9666d4e776265e /llvm | |
| parent | 77056237d79556156cd5f0afb900ac2c73a3afd9 (diff) | |
| download | bcm5719-llvm-bc60196951e80b4bc7d6c95c0fe377bd85dfaa21.tar.gz bcm5719-llvm-bc60196951e80b4bc7d6c95c0fe377bd85dfaa21.zip | |
Fix PR15950 A bug in DAG Combiner about undef mask
llvm-svn: 181682
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 35 | ||||
| -rw-r--r-- | llvm/test/CodeGen/ARM/2013-05-13-DAGCombiner-undef-mask.ll | 10 |
2 files changed, 35 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index c54dffbb132..076684993ab 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/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(); + bool AllUndef = true, NoUndef = true; + for (unsigned J = Begin; J != Begin + NumElemsPerConcat; ++J) { + if (SVN->getMaskElt(J) >= 0) + AllUndef = false; + else + NoUndef = false; + } - for (unsigned J = 1; J != NumElemsPerConcat; ++J) { - if (SVN->getMaskElt(Begin + J - 1) + 1 != SVN->getMaskElt(Begin + J)) + if (NoUndef) { + unsigned Begin = I * NumElemsPerConcat; + if (SVN->getMaskElt(Begin) % NumElemsPerConcat != 0) 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())); + 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/llvm/test/CodeGen/ARM/2013-05-13-DAGCombiner-undef-mask.ll b/llvm/test/CodeGen/ARM/2013-05-13-DAGCombiner-undef-mask.ll new file mode 100644 index 00000000000..8f6709ec5e7 --- /dev/null +++ b/llvm/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> <i32 0, i32 4, i32 undef> + ret <3 x i64> %vecinit7 +} |

