diff options
author | esmeyi <esme.yi@ibm.com> | 2023-09-26 06:24:47 -0400 |
---|---|---|
committer | esmeyi <esme.yi@ibm.com> | 2023-09-26 06:24:47 -0400 |
commit | d7195c57d823f9bff3e485ba1c4047376ee620f3 (patch) | |
tree | 145a3083fbe94ccfacdcdf8c583ab13a4a958c32 /llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | |
parent | cab01a8b4904013a5c66077eb8cbb7880d20cabe (diff) | |
download | llvm-d7195c57d823f9bff3e485ba1c4047376ee620f3.zip llvm-d7195c57d823f9bff3e485ba1c4047376ee620f3.tar.gz llvm-d7195c57d823f9bff3e485ba1c4047376ee620f3.tar.bz2 |
Reland https://reviews.llvm.org/D159073.
The patch failed in test-suite due to a liveness error after rebasing on https://reviews.llvm.org/D133103, and now it's fixed.
```
[PowerPC][Peephole] Combine rldicl/rldicr and andi/andis after isel.
Summary: rldicl/rldicr can be eliminated if it's used to clear thehigh-order or low-order n bits and all bits cleared will be ANDed with 0 byandi/andis. Or they can be folded to `andi 0` if all bits to AND are alreadyzero in the input.
Reviewed By: qiucf, shchenz
Differential Revision: https://reviews.llvm.org/D159073
```
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCMIPeephole.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp index 9ad319d..5fd604b 100644 --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -1197,6 +1197,60 @@ bool PPCMIPeephole::simplifyCode() { combineSEXTAndSHL(MI, ToErase); break; } + case PPC::ANDI_rec: + case PPC::ANDI8_rec: + case PPC::ANDIS_rec: + case PPC::ANDIS8_rec: { + Register TrueReg = + TRI->lookThruCopyLike(MI.getOperand(1).getReg(), MRI); + if (!TrueReg.isVirtual() || !MRI->hasOneNonDBGUse(TrueReg)) + break; + + MachineInstr *SrcMI = MRI->getVRegDef(TrueReg); + if (!SrcMI) + break; + + unsigned SrcOpCode = SrcMI->getOpcode(); + if (SrcOpCode != PPC::RLDICL && SrcOpCode != PPC::RLDICR) + break; + + uint64_t AndImm = MI.getOperand(2).getImm(); + if (MI.getOpcode() == PPC::ANDIS_rec || + MI.getOpcode() == PPC::ANDIS8_rec) + AndImm <<= 16; + uint64_t LZeroAndImm = llvm::countl_zero<uint64_t>(AndImm); + uint64_t RZeroAndImm = llvm::countr_zero<uint64_t>(AndImm); + uint64_t ImmSrc = SrcMI->getOperand(3).getImm(); + + // We can transfer `RLDICL/RLDICR + ANDI_rec/ANDIS_rec` to `ANDI_rec 0` + // if all bits to AND are already zero in the input. + bool PatternResultZero = + (SrcOpCode == PPC::RLDICL && (RZeroAndImm + ImmSrc > 63)) || + (SrcOpCode == PPC::RLDICR && LZeroAndImm > ImmSrc); + + // We can eliminate RLDICL/RLDICR if it's used to clear bits and all + // bits cleared will be ANDed with 0 by ANDI_rec/ANDIS_rec. + bool PatternRemoveRotate = + SrcMI->getOperand(2).getImm() == 0 && + ((SrcOpCode == PPC::RLDICL && LZeroAndImm >= ImmSrc) || + (SrcOpCode == PPC::RLDICR && (RZeroAndImm + ImmSrc > 63))); + + if (!PatternResultZero && !PatternRemoveRotate) + break; + + LLVM_DEBUG(dbgs() << "Combining pair: "); + LLVM_DEBUG(SrcMI->dump()); + LLVM_DEBUG(MI.dump()); + if (PatternResultZero) + MI.getOperand(2).setImm(0); + MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg()); + LLVM_DEBUG(dbgs() << "To: "); + LLVM_DEBUG(MI.dump()); + addRegToUpdate(MI.getOperand(1).getReg()); + addRegToUpdate(SrcMI->getOperand(0).getReg()); + Simplified = true; + break; + } case PPC::RLWINM: case PPC::RLWINM_rec: case PPC::RLWINM8: |