summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2014-07-08 15:22:29 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2014-07-08 15:22:29 +0000
commitd261e98f3db16c0ba257878d2662d6e39e9bfa0f (patch)
treec1ca1b9b71a078684878ec39ad550ae67584de12 /llvm/lib/CodeGen
parent56cca89fc3aefa73e0da3e5bd10b9c85209a726a (diff)
downloadbcm5719-llvm-d261e98f3db16c0ba257878d2662d6e39e9bfa0f.tar.gz
bcm5719-llvm-d261e98f3db16c0ba257878d2662d6e39e9bfa0f.zip
[DAG] Teach how to combine a pair of shuffles into a single shuffle if the resulting mask is legal.
This patch teaches how to fold a shuffle according to rule: shuffle (shuffle (x, undef, M0), undef, M1) -> shuffle(x, undef, M2) We do this only if the resulting mask M2 is legal; this is to avoid introducing illegal shuffles that are potentially expanded into a sub-optimal sequence of target specific dag nodes. This patch has the advantage of being target independent, since it works on ISD nodes. Therefore, all targets (not only x86) can take advantage of this rule. The idea behind this patch is that most shuffle pairs can be safely combined before we run the legalizer on vector operations. This allows us to combine/simplify dag nodes earlier in the process and not only immediately before instruction selection stage. That said. This patch is not meant to replace any existing target specific combine rules; backends might still introduce new shuffles during legalization stage. Also, this rule is very simple and avoids to aggressively optimize shuffles. llvm-svn: 212539
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 5d2b02b4bff..d58824a92d6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -10670,6 +10670,8 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
assert(OtherSV->getOperand(0).getValueType() == VT &&
"Shuffle types don't match");
+ SmallVector<int, 4> Mask;
+ // Compute the combined shuffle mask.
for (unsigned i = 0; i != NumElts; ++i) {
int Idx = SVN->getMaskElt(i);
assert(Idx < (int)NumElts && "Index references undef operand");
@@ -10677,13 +10679,29 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
// shuffle. Adopt the incoming index.
if (Idx >= 0)
Idx = OtherSV->getMaskElt(Idx);
+ Mask.push_back(Idx);
+ }
+
+ bool IsIdentityMask = true;
+ for (unsigned i = 0; i != NumElts && IsIdentityMask; ++i) {
+ // Skip Undefs.
+ if (Mask[i] < 0)
+ continue;
// The combined shuffle must map each index to itself.
- if (Idx >= 0 && (unsigned)Idx != i)
- return SDValue();
+ IsIdentityMask = (unsigned)Mask[i] == i;
}
- return OtherSV->getOperand(0);
+ if (IsIdentityMask)
+ // optimize shuffle(shuffle(x, undef), undef) -> x.
+ return OtherSV->getOperand(0);
+
+ // It may still be beneficial to combine the two shuffles if the
+ // resulting shuffle is legal.
+ // shuffle(shuffle(x, undef, M1), undef, M2) -> shuffle(x, undef, M3).
+ if (TLI.isShuffleMaskLegal(Mask, VT))
+ return DAG.getVectorShuffle(VT, SDLoc(N), N0->getOperand(0), N1,
+ &Mask[0]);
}
return SDValue();
OpenPOWER on IntegriCloud