summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
diff options
context:
space:
mode:
authorStefan Pintilie <stefanp@ca.ibm.com>2017-10-24 17:44:27 +0000
committerStefan Pintilie <stefanp@ca.ibm.com>2017-10-24 17:44:27 +0000
commit8f0c78309562cef845cf0e130c8be2ff2a19295b (patch)
treec35fbd2fd6a5cbaa0a3c301aac7534b5247bc262 /llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
parentb8522bd97d57d6876ad6c1a33874e98282045529 (diff)
downloadbcm5719-llvm-8f0c78309562cef845cf0e130c8be2ff2a19295b.tar.gz
bcm5719-llvm-8f0c78309562cef845cf0e130c8be2ff2a19295b.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. Fixed the test case that was failing and recommit after pulling the original commit. Original revision is here: https://reviews.llvm.org/D39009 llvm-svn: 316478
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