diff options
author | Stefan Pintilie <stefanp@ca.ibm.com> | 2017-10-23 19:33:31 +0000 |
---|---|---|
committer | Stefan Pintilie <stefanp@ca.ibm.com> | 2017-10-23 19:33:31 +0000 |
commit | feafa1d7f01ee3ca8e33f14af729d962fea91308 (patch) | |
tree | 506b30a964b3c5a262fc1020fd77fe0694993b5e /llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | |
parent | 70abb6e204063195bf57a05203f1b1cbf05229fb (diff) | |
download | bcm5719-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.cpp | 47 |
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: { |