[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