[llvm] [X86] Add post-RA redundant copy elimination for TEST/CMP branch paths (PR #203733)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 13 17:23:51 PDT 2026
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff origin/main HEAD --extensions h,cpp -- llvm/lib/Target/X86/X86RedundantCopyElimination.cpp llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp llvm/lib/Target/X86/X86TargetMachine.cpp --diff_from_common_commit
``````````
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index f240e1069..bd484ea62 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -163,8 +163,7 @@ void X86CodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
}
void X86CodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
- if (getOptLevel() != CodeGenOptLevel::None &&
- EnableRedundantCopyElimination)
+ if (getOptLevel() != CodeGenOptLevel::None && EnableRedundantCopyElimination)
addMachineFunctionPass(X86RedundantCopyEliminationPass(), PMW);
addMachineFunctionPass(X86LowerTileCopyPass(), PMW);
addMachineFunctionPass(X86FPStackifierPass(), PMW);
diff --git a/llvm/lib/Target/X86/X86RedundantCopyElimination.cpp b/llvm/lib/Target/X86/X86RedundantCopyElimination.cpp
index 46bb7577d..3086d1e3f 100644
--- a/llvm/lib/Target/X86/X86RedundantCopyElimination.cpp
+++ b/llvm/lib/Target/X86/X86RedundantCopyElimination.cpp
@@ -66,7 +66,6 @@ public:
bool run(MachineFunction &MF);
private:
-
const TargetRegisterInfo *TRI;
const TargetInstrInfo *TII;
@@ -111,7 +110,7 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
return false;
X86::CondCode CC = static_cast<X86::CondCode>(Cond[0].getImm());
-
+
MachineBasicBlock *NextOnPath = Path.empty() ? &MBB : Path.back();
bool IsTruePath = (NextOnPath == TBB);
if (!IsTruePath) {
@@ -148,8 +147,8 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
SmallVector<std::pair<MCPhysReg, KnownValue>, 4> KnownRegs;
// Helper: is the equality/zero path taken?
- bool IsEqualPath = (CC == X86::COND_E && IsTruePath) ||
- (CC == X86::COND_NE && !IsTruePath);
+ bool IsEqualPath =
+ (CC == X86::COND_E && IsTruePath) || (CC == X86::COND_NE && !IsTruePath);
// Analyze the flag setter.
switch (FlagSetter->getOpcode()) {
@@ -158,8 +157,10 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
// TEST is BinOpRR_F: (outs), (ins $src1, $src2) — no destination register.
// Operand 0 = $src1, Operand 1 = $src2.
- case X86::TEST8rr: case X86::TEST16rr:
- case X86::TEST32rr: case X86::TEST64rr:
+ case X86::TEST8rr:
+ case X86::TEST16rr:
+ case X86::TEST32rr:
+ case X86::TEST64rr:
if (FlagSetter->getOperand(0).getReg() ==
FlagSetter->getOperand(1).getReg()) {
if (IsEqualPath)
@@ -171,10 +172,14 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
// AND/OR are BinOpRR_RF: (outs $dst), (ins $src1, $src2).
// Operand 0 = $dst (tied to $src1), Operand 1 = $src1, Operand 2 = $src2.
// Self-AND/OR (src1 == src2) sets ZF iff the value is zero.
- case X86::AND8rr: case X86::AND16rr:
- case X86::AND32rr: case X86::AND64rr:
- case X86::OR8rr: case X86::OR16rr:
- case X86::OR32rr: case X86::OR64rr:
+ case X86::AND8rr:
+ case X86::AND16rr:
+ case X86::AND32rr:
+ case X86::AND64rr:
+ case X86::OR8rr:
+ case X86::OR16rr:
+ case X86::OR32rr:
+ case X86::OR64rr:
if (FlagSetter->getOperand(1).getReg() ==
FlagSetter->getOperand(2).getReg()) {
if (IsEqualPath)
@@ -185,21 +190,29 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
// CMP reg, reg is BinOpRR_F: (outs), (ins $src1, $src2).
// If equal, $src1 == $src2.
- case X86::CMP8rr: case X86::CMP16rr:
- case X86::CMP32rr: case X86::CMP64rr:
+ case X86::CMP8rr:
+ case X86::CMP16rr:
+ case X86::CMP32rr:
+ case X86::CMP64rr:
if (IsEqualPath) {
- KnownRegs.push_back({FlagSetter->getOperand(0).getReg(),
- KnownValue((MCPhysReg)FlagSetter->getOperand(1).getReg())});
- KnownRegs.push_back({FlagSetter->getOperand(1).getReg(),
- KnownValue((MCPhysReg)FlagSetter->getOperand(0).getReg())});
+ KnownRegs.push_back(
+ {FlagSetter->getOperand(0).getReg(),
+ KnownValue((MCPhysReg)FlagSetter->getOperand(1).getReg())});
+ KnownRegs.push_back(
+ {FlagSetter->getOperand(1).getReg(),
+ KnownValue((MCPhysReg)FlagSetter->getOperand(0).getReg())});
}
break;
// CMP reg, imm: (outs), (ins $src1, $imm).
// If equal, $src1 == $imm.
- case X86::CMP8ri: case X86::CMP16ri: case X86::CMP16ri8:
- case X86::CMP32ri: case X86::CMP32ri8:
- case X86::CMP64ri8: case X86::CMP64ri32:
+ case X86::CMP8ri:
+ case X86::CMP16ri:
+ case X86::CMP16ri8:
+ case X86::CMP32ri:
+ case X86::CMP32ri8:
+ case X86::CMP64ri8:
+ case X86::CMP64ri32:
if (IsEqualPath && FlagSetter->getOperand(1).isImm()) {
int64_t Imm = FlagSetter->getOperand(1).getImm();
KnownRegs.push_back(
@@ -208,10 +221,13 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
break;
// SUB reg, reg is BinOpRR_RF: (outs $dst), (ins $src1, $src2).
- // If ZF set, $dst is zero. (Note: src1 and src2 were equal before the instruction,
- // but $dst is tied to $src1, so $src1 is overwritten with zero and no longer equals $src2).
- case X86::SUB8rr: case X86::SUB16rr:
- case X86::SUB32rr: case X86::SUB64rr:
+ // If ZF set, $dst is zero. (Note: src1 and src2 were equal before the
+ // instruction, but $dst is tied to $src1, so $src1 is overwritten with zero
+ // and no longer equals $src2).
+ case X86::SUB8rr:
+ case X86::SUB16rr:
+ case X86::SUB32rr:
+ case X86::SUB64rr:
if (IsEqualPath) {
KnownRegs.push_back(
{FlagSetter->getOperand(0).getReg(), KnownValue((int64_t)0)});
@@ -225,13 +241,17 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
// Check if any known register was clobbered in the path.
auto isClobbered = [&](MCPhysReg Reg) {
// Check BranchMBB from FlagSetter to end
- for (MachineInstr &MI : make_range(std::next(MachineBasicBlock::iterator(FlagSetter)), BranchMBB->end())) {
- if (MI.modifiesRegister(Reg, TRI)) return true;
+ for (MachineInstr &MI :
+ make_range(std::next(MachineBasicBlock::iterator(FlagSetter)),
+ BranchMBB->end())) {
+ if (MI.modifiesRegister(Reg, TRI))
+ return true;
}
// Check Path blocks
for (auto *PMBB : llvm::reverse(Path)) {
for (MachineInstr &MI : *PMBB) {
- if (MI.modifiesRegister(Reg, TRI)) return true;
+ if (MI.modifiesRegister(Reg, TRI))
+ return true;
}
}
return false;
@@ -252,7 +272,7 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
bool Changed = false;
MachineBasicBlock::iterator LastChange = MBB.begin();
-
+
SmallVector<MCPhysReg, 4> OptimizedRegs;
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E;) {
@@ -264,9 +284,10 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
// move-immediates matching a known constant from CMP reg, imm.
if (isRedundantZeroDefinition(*MI)) {
Register DefReg = MI->getOperand(0).getReg();
- auto It = llvm::find_if(KnownRegs, [&](const std::pair<MCPhysReg, KnownValue> &K) {
- return K.first == DefReg;
- });
+ auto It = llvm::find_if(KnownRegs,
+ [&](const std::pair<MCPhysReg, KnownValue> &K) {
+ return K.first == DefReg;
+ });
if (It != KnownRegs.end() && !It->second.IsReg && It->second.U.Imm == 0) {
LLVM_DEBUG(dbgs() << "Remove redundant zero definition: " << *MI);
MI->eraseFromParent();
@@ -279,9 +300,10 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
} else if (MI->isMoveImmediate() && MI->getOperand(1).isImm()) {
Register DefReg = MI->getOperand(0).getReg();
int64_t MIImm = MI->getOperand(1).getImm();
- auto It = llvm::find_if(KnownRegs, [&](const std::pair<MCPhysReg, KnownValue> &K) {
- return K.first == DefReg;
- });
+ auto It = llvm::find_if(KnownRegs,
+ [&](const std::pair<MCPhysReg, KnownValue> &K) {
+ return K.first == DefReg;
+ });
if (It != KnownRegs.end() && !It->second.IsReg &&
It->second.U.Imm == MIImm) {
LLVM_DEBUG(dbgs() << "Remove redundant immediate definition: " << *MI);
@@ -298,10 +320,12 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
if (MI->isCopy() || MI->isMoveReg()) {
Register DefReg = MI->getOperand(0).getReg();
Register SrcReg = MI->getOperand(1).getReg();
- auto It = llvm::find_if(KnownRegs, [&](const std::pair<MCPhysReg, KnownValue> &K) {
- return K.first == DefReg;
- });
- if (It != KnownRegs.end() && It->second.IsReg && It->second.U.Reg == SrcReg) {
+ auto It = llvm::find_if(KnownRegs,
+ [&](const std::pair<MCPhysReg, KnownValue> &K) {
+ return K.first == DefReg;
+ });
+ if (It != KnownRegs.end() && It->second.IsReg &&
+ It->second.U.Reg == SrcReg) {
LLVM_DEBUG(dbgs() << "Remove redundant register copy: " << *MI);
MI->eraseFromParent();
Changed = true;
@@ -315,7 +339,8 @@ bool X86RedundantCopyEliminationImpl::optimizeBlock(MachineBasicBlock &MBB) {
// Remove clobbered registers from KnownRegs.
for (unsigned i = 0; i < KnownRegs.size();) {
if (MI->modifiesRegister(KnownRegs[i].first, TRI) ||
- (KnownRegs[i].second.IsReg && MI->modifiesRegister(KnownRegs[i].second.U.Reg, TRI))) {
+ (KnownRegs[i].second.IsReg &&
+ MI->modifiesRegister(KnownRegs[i].second.U.Reg, TRI))) {
KnownRegs[i] = KnownRegs.back();
KnownRegs.pop_back();
} else {
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index d12133358..4fc4c3bf4 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -540,8 +540,7 @@ void X86PassConfig::addMachineSSAOptimization() {
}
void X86PassConfig::addPostRegAlloc() {
- if (getOptLevel() != CodeGenOptLevel::None &&
- EnableRedundantCopyElimination)
+ if (getOptLevel() != CodeGenOptLevel::None && EnableRedundantCopyElimination)
addPass(createX86RedundantCopyEliminationLegacyPass());
addPass(createX86LowerTileCopyLegacyPass());
addPass(createX86FPStackifierLegacyPass());
``````````
</details>
https://github.com/llvm/llvm-project/pull/203733
More information about the llvm-commits
mailing list