[llvm] [AArch64][MacroFusion] Check register overlap in WAW check (PR #213953)
Tomer Shafir via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 4 10:48:23 PDT 2026
https://github.com/tomershafir updated https://github.com/llvm/llvm-project/pull/213953
>From 14f2c74f3bbe21a02786dfece947c8e50d5c2c23 Mon Sep 17 00:00:00 2001
From: tomershafir <tomer.shafir8 at gmail.com>
Date: Tue, 4 Aug 2026 16:50:41 +0300
Subject: [PATCH] [AArch64][MacroFusion] Check register overlap in WAW check
Architectural registers can share physical register storage, e.g. wN and xN, so a mix of writes to either effectively creates a WAW dependency to the same storage. This patch adds a check for such register overlap.
---
.../lib/Target/AArch64/AArch64MacroFusion.cpp | 30 +++++++++++--------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp b/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp
index c367b65cd28f9..67e21cf671cbe 100644
--- a/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp
@@ -150,21 +150,24 @@ static bool isArithmeticCbzPair(const MachineInstr *FirstMI,
return false;
}
-// True unless the pair provably writes different physical registers. Pre-RA
-// the dests are still virtual, and post-RA it requires a genuine WAW (same dest
-// reg).
+// True unless the pair provably writes non overlapping physical registers.
+// Pre-RA the dests are still virtual, and post-RA it requires a genuine WAW,
+// that is overlapping dest regs. Overlapping includes sub and super register
+// relations, e.g. W0 and X0, which matches the register unit based dependency
+// model of the scheduling DAG.
static bool mayHaveWAWDependency(const MachineInstr &FirstMI,
- const MachineInstr &SecondMI) {
+ const MachineInstr &SecondMI,
+ const TargetRegisterInfo *TRI) {
Register DestFirst = FirstMI.getOperand(0).getReg();
Register DestSecond = SecondMI.getOperand(0).getReg();
if (!DestFirst.isPhysical() || !DestSecond.isPhysical())
return true;
- return DestFirst == DestSecond;
+ return TRI->regsOverlap(DestFirst, DestSecond);
}
/// AES crypto encoding or decoding.
-static bool isAESPair(const MachineInstr *FirstMI,
- const MachineInstr &SecondMI) {
+static bool isAESPair(const MachineInstr *FirstMI, const MachineInstr &SecondMI,
+ const TargetRegisterInfo *TRI) {
// Assume the 1st instr to be a wildcard if it is unspecified.
unsigned SecondOpcode = SecondMI.getOpcode();
switch (SecondOpcode) {
@@ -176,7 +179,7 @@ static bool isAESPair(const MachineInstr *FirstMI,
if (FirstMI->getOpcode() != AArch64::AESErr)
return false;
return SecondOpcode == AArch64::AESMCrrTied ||
- mayHaveWAWDependency(*FirstMI, SecondMI);
+ mayHaveWAWDependency(*FirstMI, SecondMI, TRI);
// AES decode.
case AArch64::AESIMCrr:
case AArch64::AESIMCrrTied:
@@ -185,7 +188,7 @@ static bool isAESPair(const MachineInstr *FirstMI,
if (FirstMI->getOpcode() != AArch64::AESDrr)
return false;
return SecondOpcode == AArch64::AESIMCrrTied ||
- mayHaveWAWDependency(*FirstMI, SecondMI);
+ mayHaveWAWDependency(*FirstMI, SecondMI, TRI);
}
return false;
@@ -652,7 +655,8 @@ static bool isFMinFMax(unsigned Opcode) {
// FMIN + FMAX.
static bool isFMinFMaxPair(const MachineInstr *FirstMI,
- const MachineInstr &SecondMI) {
+ const MachineInstr &SecondMI,
+ const TargetRegisterInfo *TRI) {
if (!isFMinFMax(SecondMI.getOpcode()))
return false;
@@ -663,7 +667,7 @@ static bool isFMinFMaxPair(const MachineInstr *FirstMI,
if (!isFMinFMax(FirstMI->getOpcode()))
return false;
- return mayHaveWAWDependency(*FirstMI, SecondMI);
+ return mayHaveWAWDependency(*FirstMI, SecondMI, TRI);
}
/// \brief Check if the instr pair, FirstMI and SecondMI, should be fused
@@ -702,7 +706,7 @@ static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
++NumFusedArithmeticCbz;
return true;
}
- if (ST.hasFuseAES() && isAESPair(FirstMI, SecondMI)) {
+ if (ST.hasFuseAES() && isAESPair(FirstMI, SecondMI, TRI)) {
++NumFusedAES;
return true;
}
@@ -743,7 +747,7 @@ static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
++NumFusedAddSub2RegAndConstOne;
return true;
}
- if (ST.hasFuseFMinFMax() && isFMinFMaxPair(FirstMI, SecondMI)) {
+ if (ST.hasFuseFMinFMax() && isFMinFMaxPair(FirstMI, SecondMI, TRI)) {
++NumFusedFMinFMax;
return true;
}
More information about the llvm-commits
mailing list