From 7dbf2e7b576f52f1c459665fe524d7521d560dae Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Mon, 16 May 2022 16:27:39 -0700 Subject: [PATCH] Teach PeepholeOpt to eliminate redundant copy from constant physreg (e.g VLENB on RISCV) The existing redundant copy elimination required a virtual register source, but the same logic works for any physreg where we don't have to worry about clobbers. On RISCV, this helps eliminate redundant CSR reads from VLENB. Differential Revision: https://reviews.llvm.org/D125564 --- llvm/lib/CodeGen/PeepholeOptimizer.cpp | 11 ++++++----- llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp | 2 +- llvm/test/CodeGen/RISCV/vlenb.ll | 3 +-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp index 1b04748..31e37c4 100644 --- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp +++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp @@ -213,8 +213,9 @@ namespace { const SmallSet &TargetReg, RecurrenceCycle &RC); - /// If copy instruction \p MI is a virtual register copy, track it in - /// the set \p CopyMIs. If this virtual register was previously seen as a + /// If copy instruction \p MI is a virtual register copy or a copy of a + /// constant physical register to a virtual register, track it in the + /// set \p CopyMIs. If this virtual register was previously seen as a /// copy, replace the uses of this copy with the previously seen copy's /// destination register. bool foldRedundantCopy(MachineInstr &MI, @@ -1411,7 +1412,7 @@ bool PeepholeOptimizer::foldRedundantCopy( Register SrcReg = MI.getOperand(1).getReg(); unsigned SrcSubReg = MI.getOperand(1).getSubReg(); - if (!SrcReg.isVirtual()) + if (!SrcReg.isVirtual() && !MRI->isConstantPhysReg(SrcReg)) return false; Register DstReg = MI.getOperand(0).getReg(); @@ -1642,8 +1643,8 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) { // without any intervening re-definition of $physreg. DenseMap NAPhysToVirtMIs; - // Set of pairs of virtual registers and their subregs that are copied - // from. + // Set of copies to virtual registers keyed by source register. Never + // holds any physreg which requires def tracking. DenseMap CopySrcMIs; bool IsLoopHeader = MLI->isLoopHeader(&MBB); diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index bcbaf5b..eb32332 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -118,7 +118,7 @@ bool RISCVRegisterInfo::isAsmClobberable(const MachineFunction &MF, } bool RISCVRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { - return PhysReg == RISCV::X0; + return PhysReg == RISCV::X0 || PhysReg == RISCV::VLENB; } const uint32_t *RISCVRegisterInfo::getNoPreservedMask() const { diff --git a/llvm/test/CodeGen/RISCV/vlenb.ll b/llvm/test/CodeGen/RISCV/vlenb.ll index b53d02a..6ce7f53 100644 --- a/llvm/test/CodeGen/RISCV/vlenb.ll +++ b/llvm/test/CodeGen/RISCV/vlenb.ll @@ -16,8 +16,7 @@ define i32 @simple_cse() { ; CHECK-LABEL: simple_cse: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: csrr a1, vlenb -; CHECK-NEXT: sub a0, a0, a1 +; CHECK-NEXT: sub a0, a0, a0 ; CHECK-NEXT: ret entry: %v1 = call i32 @llvm.read_register.i32(metadata !0) -- 2.7.4