diff options
author | Stefan Pintilie <stefanp@ca.ibm.com> | 2017-10-24 17:44:27 +0000 |
---|---|---|
committer | Stefan Pintilie <stefanp@ca.ibm.com> | 2017-10-24 17:44:27 +0000 |
commit | 8f0c78309562cef845cf0e130c8be2ff2a19295b (patch) | |
tree | c35fbd2fd6a5cbaa0a3c301aac7534b5247bc262 /llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | |
parent | b8522bd97d57d6876ad6c1a33874e98282045529 (diff) | |
download | bcm5719-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.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: { |