aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
diff options
context:
space:
mode:
authoresmeyi <esme.yi@ibm.com>2023-09-26 06:24:47 -0400
committeresmeyi <esme.yi@ibm.com>2023-09-26 06:24:47 -0400
commitd7195c57d823f9bff3e485ba1c4047376ee620f3 (patch)
tree145a3083fbe94ccfacdcdf8c583ab13a4a958c32 /llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
parentcab01a8b4904013a5c66077eb8cbb7880d20cabe (diff)
downloadllvm-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.cpp54
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: