diff options
| author | Nemanja Ivanovic <nemanja.i.ibm@gmail.com> | 2018-09-18 13:43:16 +0000 |
|---|---|---|
| committer | Nemanja Ivanovic <nemanja.i.ibm@gmail.com> | 2018-09-18 13:43:16 +0000 |
| commit | 87c31a61134f523a09d4cd1cca09e4afe09afa7d (patch) | |
| tree | 263baace5eecee78210d919f6ef06c40979f3a84 /llvm/lib/Target/PowerPC | |
| parent | 5e1c0e7610406df5300be63e4b4cd5a05cc0a2a2 (diff) | |
| download | bcm5719-llvm-87c31a61134f523a09d4cd1cca09e4afe09afa7d.tar.gz bcm5719-llvm-87c31a61134f523a09d4cd1cca09e4afe09afa7d.zip | |
[PowerPC] Do not emit record-form rotates when record-form andi/andis suffices
This is a follow-up to the previous patch that eliminated some of the rotates.
With this addition, we will also emit the record-form andis.
This patch increases the number of record-form rotates we eliminate by
more than 70%.
Differential revision: https://reviews.llvm.org/D44897
llvm-svn: 342478
Diffstat (limited to 'llvm/lib/Target/PowerPC')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index c3a280ad9ae..f9d173699ec 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1913,14 +1913,36 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, // compare). // Rotates are expensive instructions. If we're emitting a record-form - // rotate that can just be an andi, we should just emit the andi. - if ((MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) && - MI->getOperand(2).getImm() == 0) { + // rotate that can just be an andi/andis, we should just emit that. + if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) { + unsigned GPRRes = MI->getOperand(0).getReg(); + int64_t SH = MI->getOperand(2).getImm(); int64_t MB = MI->getOperand(3).getImm(); int64_t ME = MI->getOperand(4).getImm(); - if (MB < ME && MB >= 16) { - uint64_t Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1); - NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIo : PPC::ANDIo8; + // We can only do this if both the start and end of the mask are in the + // same halfword. + bool MBInLoHWord = MB >= 16; + bool MEInLoHWord = ME >= 16; + uint64_t Mask = ~0LLU; + + if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) { + Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1); + // The mask value needs to shift right 16 if we're emitting andis. + Mask >>= MBInLoHWord ? 0 : 16; + NewOpC = MIOpC == PPC::RLWINM ? + (MBInLoHWord ? PPC::ANDIo : PPC::ANDISo) : + (MBInLoHWord ? PPC::ANDIo8 :PPC::ANDISo8); + } else if (MRI->use_empty(GPRRes) && (ME == 31) && + (ME - MB + 1 == SH) && (MB >= 16)) { + // If we are rotating by the exact number of bits as are in the mask + // and the mask is in the least significant bits of the register, + // that's just an andis. (as long as the GPR result has no uses). + Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1); + Mask >>= 16; + NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDISo :PPC::ANDISo8; + } + // If we've set the mask, we can transform. + if (Mask != ~0LLU) { MI->RemoveOperand(4); MI->RemoveOperand(3); MI->getOperand(2).setImm(Mask); |

