summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
diff options
context:
space:
mode:
authorStefan Pintilie <stefanp@ca.ibm.com>2017-10-23 19:33:31 +0000
committerStefan Pintilie <stefanp@ca.ibm.com>2017-10-23 19:33:31 +0000
commitfeafa1d7f01ee3ca8e33f14af729d962fea91308 (patch)
tree506b30a964b3c5a262fc1020fd77fe0694993b5e /llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
parent70abb6e204063195bf57a05203f1b1cbf05229fb (diff)
downloadbcm5719-llvm-feafa1d7f01ee3ca8e33f14af729d962fea91308.tar.gz
bcm5719-llvm-feafa1d7f01ee3ca8e33f14af729d962fea91308.zip
[PowerPC] Try to simplify a Swap if it feeds a Splat
If we have the situation where a Swap feeds a Splat we can sometimes change the index on the Splat and then remove the Swap instruction. Differential Revision: https://reviews.llvm.org/D39009 llvm-svn: 316366
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCMIPeephole.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/PPCMIPeephole.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
index 80b7ac24345..beb40992900 100644
--- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
@@ -375,6 +375,53 @@ bool PPCMIPeephole::simplifyCode(void) {
MI.getOperand(2).setImm(NewElem);
}
}
+
+ // Splat is fed by a SWAP which is a permute of this form
+ // XXPERMDI %VA, %VA, 2
+ // Since the splat instruction can use any of the vector elements to do
+ // the splat we do not have to rearrange the elements in the vector
+ // with a swap before we do the splat. We can simply do the splat from
+ // a different index.
+ // If the swap has only one use (the splat) then we can completely
+ // remove the swap too.
+ if (DefOpcode == PPC::XXPERMDI && MI.getOperand(1).isImm()) {
+ unsigned SwapRes = DefMI->getOperand(0).getReg();
+ unsigned SwapOp1 = DefMI->getOperand(1).getReg();
+ unsigned SwapOp2 = DefMI->getOperand(2).getReg();
+ unsigned SwapImm = DefMI->getOperand(3).getImm();
+ unsigned SplatImm = MI.getOperand(1).getImm();
+
+ // Break if this permute is not a swap.
+ if (SwapOp1 != SwapOp2 || SwapImm != 2)
+ break;
+
+ unsigned NewElem = 0;
+ // Compute the new index to use for the splat.
+ if (MI.getOpcode() == PPC::VSPLTB)
+ NewElem = (SplatImm + 8) & 0xF;
+ else if (MI.getOpcode() == PPC::VSPLTH)
+ NewElem = (SplatImm + 4) & 0x7;
+ else if (MI.getOpcode() == PPC::XXSPLTW)
+ NewElem = (SplatImm + 2) & 0x3;
+ else {
+ DEBUG(dbgs() << "Unknown splat opcode.");
+ DEBUG(MI.dump());
+ break;
+ }
+
+ if (MRI->hasOneNonDBGUse(SwapRes)) {
+ DEBUG(dbgs() << "Removing redundant swap: ");
+ DEBUG(DefMI->dump());
+ ToErase = DefMI;
+ }
+ Simplified = true;
+ DEBUG(dbgs() << "Changing splat immediate from " << SplatImm <<
+ " to " << NewElem << " in instruction: ");
+ DEBUG(MI.dump());
+ MI.getOperand(1).setImm(NewElem);
+ MI.getOperand(2).setReg(SwapOp1);
+ }
+
break;
}
case PPC::XVCVDPSP: {
OpenPOWER on IntegriCloud