[llvm] [MacroFusion] Add SDep param to predicates(NFC) (PR #212255)

Tomer Shafir via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 29 01:24:43 PDT 2026


https://github.com/tomershafir updated https://github.com/llvm/llvm-project/pull/212255

>From 1692b8c1ec25a1a40f6411e57de65cab16777c0b Mon Sep 17 00:00:00 2001
From: tomershafir <tomer.shafir8 at gmail.com>
Date: Mon, 27 Jul 2026 16:44:35 +0300
Subject: [PATCH 1/2] [MacroFusion] Add SDep param to predicates(NFC)

This patch aims to extend the API for macro fusion predicates with a n additionl SDep param which allows each predicate to individually decide wether a pair should be macro fused based on the kind of dependency between the 2 instructions.

A followup patch introduces a real user in AArch64 backend that doesnt require the default data dependency.
---
 llvm/include/llvm/CodeGen/MacroFusion.h       |  7 +++-
 llvm/lib/CodeGen/MacroFusion.cpp              | 19 +++++----
 .../lib/Target/AArch64/AArch64MacroFusion.cpp |  5 ++-
 .../Target/AArch64/AArch64TargetMachine.cpp   |  5 ++-
 llvm/lib/Target/AMDGPU/AMDGPUMacroFusion.cpp  |  5 ++-
 llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp       |  7 ++--
 llvm/lib/Target/ARM/ARMMacroFusion.cpp        |  5 ++-
 llvm/lib/Target/PowerPC/PPCMacroFusion.cpp    |  5 ++-
 llvm/lib/Target/RISCV/RISCVSubtarget.cpp      |  1 +
 llvm/lib/Target/X86/X86MacroFusion.cpp        |  5 ++-
 llvm/test/TableGen/MacroFusion.td             | 42 ++++++++++++-------
 .../TableGen/MacroFusionPredicatorEmitter.cpp | 10 +++--
 12 files changed, 80 insertions(+), 36 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/MacroFusion.h b/llvm/include/llvm/CodeGen/MacroFusion.h
index b860c29f0ea3b..1ff590d8f260f 100644
--- a/llvm/include/llvm/CodeGen/MacroFusion.h
+++ b/llvm/include/llvm/CodeGen/MacroFusion.h
@@ -26,6 +26,7 @@ class TargetInstrInfo;
 class TargetSubtargetInfo;
 class ScheduleDAGInstrs;
 class SUnit;
+class SDep;
 
 /// Check if the instr pair, FirstMI and SecondMI, should be fused
 /// together. Given SecondMI, when FirstMI is unspecified, then check if
@@ -33,12 +34,16 @@ class SUnit;
 using MacroFusionPredTy = bool (*)(const TargetInstrInfo &TII,
                                    const TargetSubtargetInfo &STI,
                                    const MachineInstr *FirstMI,
-                                   const MachineInstr &SecondMI);
+                                   const MachineInstr &SecondMI,
+                                   const SDep *Dep);
 
 /// Checks if the number of cluster edges between SU and its predecessors is
 /// less than FuseLimit
 LLVM_ABI bool hasLessThanNumFused(const SUnit &SU, unsigned FuseLimit);
 
+/// Returns true if \p Dep is a non-null non-data dependency.
+LLVM_ABI bool isNonDataDep(const SDep *Dep);
+
 /// Create an artificial edge between FirstSU and SecondSU.
 /// Make data dependencies from the FirstSU also dependent on the SecondSU to
 /// prevent them from being scheduled between the FirstSU and the SecondSU
diff --git a/llvm/lib/CodeGen/MacroFusion.cpp b/llvm/lib/CodeGen/MacroFusion.cpp
index df37aa88b4567..9194c14335fa5 100644
--- a/llvm/lib/CodeGen/MacroFusion.cpp
+++ b/llvm/lib/CodeGen/MacroFusion.cpp
@@ -53,6 +53,10 @@ bool llvm::hasLessThanNumFused(const SUnit &SU, unsigned FuseLimit) {
   return Num < FuseLimit;
 }
 
+bool llvm::isNonDataDep(const SDep *Dep) {
+  return Dep && Dep->getKind() != SDep::Data;
+}
+
 bool llvm::fuseInstructionPair(ScheduleDAGInstrs &DAG, SUnit &FirstSU,
                                SUnit &SecondSU) {
   // Check that neither instr is already associated with a cluster (either
@@ -165,7 +169,7 @@ class MacroFusion : public ScheduleDAGMutation {
   bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
                               const TargetSubtargetInfo &STI,
                               const MachineInstr *FirstMI,
-                              const MachineInstr &SecondMI);
+                              const MachineInstr &SecondMI, const SDep *Dep);
 };
 
 } // end anonymous namespace
@@ -173,9 +177,10 @@ class MacroFusion : public ScheduleDAGMutation {
 bool MacroFusion::shouldScheduleAdjacent(const TargetInstrInfo &TII,
                                          const TargetSubtargetInfo &STI,
                                          const MachineInstr *FirstMI,
-                                         const MachineInstr &SecondMI) {
+                                         const MachineInstr &SecondMI,
+                                         const SDep *Dep) {
   return llvm::any_of(Predicates, [&](MacroFusionPredTy Predicate) {
-    return Predicate(TII, STI, FirstMI, SecondMI);
+    return Predicate(TII, STI, FirstMI, SecondMI, Dep);
   });
 }
 
@@ -199,15 +204,11 @@ bool MacroFusion::scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU)
   const TargetSubtargetInfo &ST = DAG.MF.getSubtarget();
 
   // Check if the anchor instr may be fused.
-  if (!shouldScheduleAdjacent(TII, ST, nullptr, AnchorMI))
+  if (!shouldScheduleAdjacent(TII, ST, nullptr, AnchorMI, nullptr))
     return false;
 
   // Explorer for fusion candidates among the dependencies of the anchor instr.
   for (SDep &Dep : AnchorSU.Preds) {
-    // Ignore dependencies other than data
-    if (Dep.getKind() != SDep::Data)
-      continue;
-
     SUnit &DepSU = *Dep.getSUnit();
     if (DepSU.isBoundaryNode())
       continue;
@@ -215,7 +216,7 @@ bool MacroFusion::scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU)
     // Only chain two instructions together at most.
     const MachineInstr *DepMI = DepSU.getInstr();
     if (!hasLessThanNumFused(DepSU, 2) ||
-        !shouldScheduleAdjacent(TII, ST, DepMI, AnchorMI))
+        !shouldScheduleAdjacent(TII, ST, DepMI, AnchorMI, &Dep))
       continue;
 
     if (fuseInstructionPair(DAG, DepSU, AnchorSU))
diff --git a/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp b/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp
index 2ab68f1539883..aa742793a0f1a 100644
--- a/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp
@@ -672,7 +672,10 @@ static bool isFMinFMaxPair(const MachineInstr *FirstMI,
 static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
                                    const TargetSubtargetInfo &TSI,
                                    const MachineInstr *FirstMI,
-                                   const MachineInstr &SecondMI) {
+                                   const MachineInstr &SecondMI,
+                                   const SDep *Dep) {
+  if (isNonDataDep(Dep))
+    return false;
   const AArch64Subtarget &ST = static_cast<const AArch64Subtarget&>(TSI);
 
   // All checking functions assume that the 1st instr is a wildcard if it is
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index 2b4d50a89ff59..dee61a4f2ac8c 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -511,7 +511,10 @@ AArch64TargetMachine::getSubtargetImpl(const Function &F) const {
 // for the hints in AArch64RegisterInfo::getRegAllocationHints).
 static bool scheduleFormTransposedTupleAdjacentToUsers(
     const TargetInstrInfo &TII, const TargetSubtargetInfo &TSI,
-    const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
+    const MachineInstr *FirstMI, const MachineInstr &SecondMI,
+    const SDep *Dep) {
+  if (isNonDataDep(Dep))
+    return false;
   return !FirstMI ||
          FirstMI->getOpcode() == AArch64::FORM_TRANSPOSED_REG_TUPLE_X2_PSEUDO ||
          FirstMI->getOpcode() == AArch64::FORM_TRANSPOSED_REG_TUPLE_X4_PSEUDO;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMacroFusion.cpp b/llvm/lib/Target/AMDGPU/AMDGPUMacroFusion.cpp
index 0cbabf3895a67..778123656b315 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUMacroFusion.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUMacroFusion.cpp
@@ -26,7 +26,10 @@ namespace {
 static bool shouldScheduleAdjacent(const TargetInstrInfo &TII_,
                                    const TargetSubtargetInfo &TSI,
                                    const MachineInstr *FirstMI,
-                                   const MachineInstr &SecondMI) {
+                                   const MachineInstr &SecondMI,
+                                   const SDep *Dep) {
+  if (isNonDataDep(Dep))
+    return false;
   const SIInstrInfo &TII = static_cast<const SIInstrInfo&>(TII_);
 
   switch (SecondMI.getOpcode()) {
diff --git a/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp b/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp
index 5cf4e3cd6e8aa..29dec3b8bba6f 100644
--- a/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp
@@ -298,7 +298,8 @@ std::optional<VOPDMatchInfo> llvm::tryMatchVOPDPair(const SIInstrInfo &TII,
 static bool shouldScheduleVOPDAdjacent(const TargetInstrInfo &TII,
                                        const TargetSubtargetInfo &TSI,
                                        const MachineInstr *FirstMI,
-                                       const MachineInstr &SecondMI) {
+                                       const MachineInstr &SecondMI,
+                                       const SDep *) {
   const SIInstrInfo &STII = static_cast<const SIInstrInfo &>(TII);
   const GCNSubtarget &ST = STII.getSubtarget();
 
@@ -446,7 +447,7 @@ struct VOPDPairingMutation : ScheduleDAGMutation {
     for (auto ISUI = DAG->SUnits.begin(), E = DAG->SUnits.end(); ISUI != E;
          ++ISUI, ++IIdx) {
       const MachineInstr *IMI = ISUI->getInstr();
-      if (shouldScheduleAdjacent(TII, ST, nullptr, *IMI) &&
+      if (shouldScheduleAdjacent(TII, ST, nullptr, *IMI, nullptr) &&
           hasLessThanNumFused(*ISUI, 2))
         VOPDCapable[IIdx] = true;
     }
@@ -477,7 +478,7 @@ struct VOPDPairingMutation : ScheduleDAGMutation {
           continue;
         const MachineInstr *JMI = JSUI->getInstr();
         if (!hasLessThanNumFused(*JSUI, 2) ||
-            !shouldScheduleAdjacent(TII, ST, IMI, *JMI))
+            !shouldScheduleAdjacent(TII, ST, IMI, *JMI, nullptr))
           continue;
 
         if (loadsMayOverlap(*ISUI, ILoadSuccs, *JSUI, LoadPredsComputed,
diff --git a/llvm/lib/Target/ARM/ARMMacroFusion.cpp b/llvm/lib/Target/ARM/ARMMacroFusion.cpp
index 5aeb7abe92a38..226b244488b08 100644
--- a/llvm/lib/Target/ARM/ARMMacroFusion.cpp
+++ b/llvm/lib/Target/ARM/ARMMacroFusion.cpp
@@ -51,7 +51,10 @@ static bool isLiteralsPair(const MachineInstr *FirstMI,
 static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
                                    const TargetSubtargetInfo &TSI,
                                    const MachineInstr *FirstMI,
-                                   const MachineInstr &SecondMI) {
+                                   const MachineInstr &SecondMI,
+                                   const SDep *Dep) {
+  if (isNonDataDep(Dep))
+    return false;
   const ARMSubtarget &ST = static_cast<const ARMSubtarget&>(TSI);
 
   if (ST.hasFuseAES() && isAESPair(FirstMI, SecondMI))
diff --git a/llvm/lib/Target/PowerPC/PPCMacroFusion.cpp b/llvm/lib/Target/PowerPC/PPCMacroFusion.cpp
index 7ad6ef8c39286..0721916f64e19 100644
--- a/llvm/lib/Target/PowerPC/PPCMacroFusion.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMacroFusion.cpp
@@ -234,7 +234,10 @@ static bool checkOpConstraints(FusionFeature::FusionKind Kd,
 static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
                                    const TargetSubtargetInfo &TSI,
                                    const MachineInstr *FirstMI,
-                                   const MachineInstr &SecondMI) {
+                                   const MachineInstr &SecondMI,
+                                   const SDep *Dep) {
+  if (isNonDataDep(Dep))
+    return false;
   // We use the PPC namespace to avoid the need to prefix opcodes with PPC:: in
   // the def file.
   using namespace PPC;
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
index 319dbdd03fb79..b807534e986c1 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -20,6 +20,7 @@
 #include "RISCVTargetMachine.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MacroFusion.h"
 #include "llvm/MC/MCSchedule.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Support/CommandLine.h"
diff --git a/llvm/lib/Target/X86/X86MacroFusion.cpp b/llvm/lib/Target/X86/X86MacroFusion.cpp
index c0fa9aa703243..7c1411bf98c2c 100644
--- a/llvm/lib/Target/X86/X86MacroFusion.cpp
+++ b/llvm/lib/Target/X86/X86MacroFusion.cpp
@@ -35,7 +35,10 @@ static X86::SecondMacroFusionInstKind classifySecond(const MachineInstr &MI) {
 static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
                                    const TargetSubtargetInfo &TSI,
                                    const MachineInstr *FirstMI,
-                                   const MachineInstr &SecondMI) {
+                                   const MachineInstr &SecondMI,
+                                   const SDep *Dep) {
+  if (isNonDataDep(Dep))
+    return false;
   const X86Subtarget &ST = static_cast<const X86Subtarget &>(TSI);
 
   // Check if this processor supports any kind of fusion.
diff --git a/llvm/test/TableGen/MacroFusion.td b/llvm/test/TableGen/MacroFusion.td
index f9559c8dcf980..da4adf75ac7eb 100644
--- a/llvm/test/TableGen/MacroFusion.td
+++ b/llvm/test/TableGen/MacroFusion.td
@@ -87,13 +87,13 @@ def TestPostRAOnlyFusion: SimpleFusion<"test-postra-only", "HasTestPostRAOnlyFus
 // CHECK-PREDICATOR-EMPTY:
 // CHECK-PREDICATOR-NEXT:  namespace llvm {
 // CHECK-PREDICATOR-EMPTY:
-// CHECK-PREDICATOR-NEXT:  bool isTestBothFusionPredicate(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
-// CHECK-PREDICATOR-NEXT:  bool isTestCommutableFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
-// CHECK-PREDICATOR-NEXT:  bool isTestFirstSameRegFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
-// CHECK-PREDICATOR-NEXT:  bool isTestFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
-// CHECK-PREDICATOR-NEXT:  bool isTestPostRAOnlyFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
-// CHECK-PREDICATOR-NEXT:  bool isTestPreRAOnlyFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
-// CHECK-PREDICATOR-NEXT:  bool isTestSingleFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
+// CHECK-PREDICATOR-NEXT:  bool isTestBothFusionPredicate(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
+// CHECK-PREDICATOR-NEXT:  bool isTestCommutableFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
+// CHECK-PREDICATOR-NEXT:  bool isTestFirstSameRegFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
+// CHECK-PREDICATOR-NEXT:  bool isTestFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
+// CHECK-PREDICATOR-NEXT:  bool isTestPostRAOnlyFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
+// CHECK-PREDICATOR-NEXT:  bool isTestPreRAOnlyFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
+// CHECK-PREDICATOR-NEXT:  bool isTestSingleFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
 // CHECK-PREDICATOR-EMPTY:
 // CHECK-PREDICATOR-NEXT:  } // namespace llvm
 // CHECK-PREDICATOR-EMPTY:
@@ -111,7 +111,9 @@ def TestPostRAOnlyFusion: SimpleFusion<"test-postra-only", "HasTestPostRAOnlyFus
 // CHECK-PREDICATOR-NEXT:      const TargetInstrInfo &TII,
 // CHECK-PREDICATOR-NEXT:      const TargetSubtargetInfo &STI,
 // CHECK-PREDICATOR-NEXT:      const MachineInstr *FirstMI,
-// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI) {
+// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI, const SDep *Dep) {
+// CHECK-PREDICATOR-NEXT:    if (isNonDataDep(Dep))
+// CHECK-PREDICATOR-NEXT:      return false;
 // CHECK-PREDICATOR-NEXT:    {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo();
 // CHECK-PREDICATOR-NEXT:    {
 // CHECK-PREDICATOR-NEXT:      {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} const MachineInstr *MI = FirstMI;
@@ -135,7 +137,9 @@ def TestPostRAOnlyFusion: SimpleFusion<"test-postra-only", "HasTestPostRAOnlyFus
 // CHECK-PREDICATOR-NEXT:      const TargetInstrInfo &TII,
 // CHECK-PREDICATOR-NEXT:      const TargetSubtargetInfo &STI,
 // CHECK-PREDICATOR-NEXT:      const MachineInstr *FirstMI,
-// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI) {
+// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI, const SDep *Dep) {
+// CHECK-PREDICATOR-NEXT:    if (isNonDataDep(Dep))
+// CHECK-PREDICATOR-NEXT:      return false;
 // CHECK-PREDICATOR-NEXT:    {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo();
 // CHECK-PREDICATOR-NEXT:    {
 // CHECK-PREDICATOR-NEXT:      {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} const MachineInstr *MI = &SecondMI;
@@ -189,7 +193,9 @@ def TestPostRAOnlyFusion: SimpleFusion<"test-postra-only", "HasTestPostRAOnlyFus
 // CHECK-PREDICATOR-NEXT:      const TargetInstrInfo &TII,
 // CHECK-PREDICATOR-NEXT:      const TargetSubtargetInfo &STI,
 // CHECK-PREDICATOR-NEXT:      const MachineInstr *FirstMI,
-// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI) {
+// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI, const SDep *Dep) {
+// CHECK-PREDICATOR-NEXT:    if (isNonDataDep(Dep))
+// CHECK-PREDICATOR-NEXT:      return false;
 // CHECK-PREDICATOR-NEXT:    {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo();
 // CHECK-PREDICATOR-NEXT:    if (!FirstMI->getOperand(0).getReg().isVirtual()) {
 // CHECK-PREDICATOR-NEXT:      if (FirstMI->getOperand(0).getReg() != FirstMI->getOperand(1).getReg()) {
@@ -213,7 +219,9 @@ def TestPostRAOnlyFusion: SimpleFusion<"test-postra-only", "HasTestPostRAOnlyFus
 // CHECK-PREDICATOR-NEXT:      const TargetInstrInfo &TII,
 // CHECK-PREDICATOR-NEXT:      const TargetSubtargetInfo &STI,
 // CHECK-PREDICATOR-NEXT:      const MachineInstr *FirstMI,
-// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI) {
+// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI, const SDep *Dep) {
+// CHECK-PREDICATOR-NEXT:    if (isNonDataDep(Dep))
+// CHECK-PREDICATOR-NEXT:      return false;
 // CHECK-PREDICATOR-NEXT:    {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo();
 // CHECK-PREDICATOR-NEXT:    {
 // CHECK-PREDICATOR-NEXT:      {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} const MachineInstr *MI = &SecondMI;
@@ -254,7 +262,9 @@ def TestPostRAOnlyFusion: SimpleFusion<"test-postra-only", "HasTestPostRAOnlyFus
 // CHECK-PREDICATOR-NEXT:      const TargetInstrInfo &TII,
 // CHECK-PREDICATOR-NEXT:      const TargetSubtargetInfo &STI,
 // CHECK-PREDICATOR-NEXT:      const MachineInstr *FirstMI,
-// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI) {
+// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI, const SDep *Dep) {
+// CHECK-PREDICATOR-NEXT:    if (isNonDataDep(Dep))
+// CHECK-PREDICATOR-NEXT:      return false;
 // CHECK-PREDICATOR-NEXT:    {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo();
 // CHECK-PREDICATOR-NEXT:    if (!SecondMI.getMF()->getProperties().hasNoVRegs())
 // CHECK-PREDICATOR-NEXT:      return false;
@@ -291,7 +301,9 @@ def TestPostRAOnlyFusion: SimpleFusion<"test-postra-only", "HasTestPostRAOnlyFus
 // CHECK-PREDICATOR-NEXT:      const TargetInstrInfo &TII,
 // CHECK-PREDICATOR-NEXT:      const TargetSubtargetInfo &STI,
 // CHECK-PREDICATOR-NEXT:      const MachineInstr *FirstMI,
-// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI) {
+// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI, const SDep *Dep) {
+// CHECK-PREDICATOR-NEXT:    if (isNonDataDep(Dep))
+// CHECK-PREDICATOR-NEXT:      return false;
 // CHECK-PREDICATOR-NEXT:    {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo();
 // CHECK-PREDICATOR-NEXT:    if (SecondMI.getMF()->getProperties().hasNoVRegs())
 // CHECK-PREDICATOR-NEXT:      return false;
@@ -329,7 +341,9 @@ def TestPostRAOnlyFusion: SimpleFusion<"test-postra-only", "HasTestPostRAOnlyFus
 // CHECK-PREDICATOR-NEXT:      const TargetInstrInfo &TII,
 // CHECK-PREDICATOR-NEXT:      const TargetSubtargetInfo &STI,
 // CHECK-PREDICATOR-NEXT:      const MachineInstr *FirstMI,
-// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI) {
+// CHECK-PREDICATOR-NEXT:      const MachineInstr &SecondMI, const SDep *Dep) {
+// CHECK-PREDICATOR-NEXT:    if (isNonDataDep(Dep))
+// CHECK-PREDICATOR-NEXT:      return false;
 // CHECK-PREDICATOR-NEXT:    {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo();
 // CHECK-PREDICATOR-NEXT:    {
 // CHECK-PREDICATOR-NEXT:      {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} const MachineInstr *MI = &SecondMI;
diff --git a/llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp b/llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp
index 44c704500e210..92b9e7de5aefb 100644
--- a/llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp
+++ b/llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp
@@ -36,7 +36,9 @@
 // bool isNAME(const TargetInstrInfo &TII,
 //             const TargetSubtargetInfo &STI,
 //             const MachineInstr *FirstMI,
-//             const MachineInstr &SecondMI) {
+//             const MachineInstr &SecondMI, const SDep *Dep) {
+//   if (isNonDataDep(Dep))
+//     return false;
 //   auto &MRI = SecondMI.getMF()->getRegInfo();
 //   /* Predicates */
 //   if (SecondMI.getMF()->getProperties().hasNoVRegs())
@@ -118,7 +120,7 @@ void MacroFusionPredicatorEmitter::emitMacroFusionDecl(
   for (const Record *Fusion : Fusions)
     OS << "bool is" << Fusion->getName() << "(const TargetInstrInfo &, "
        << "const TargetSubtargetInfo &, const MachineInstr *, "
-       << "const MachineInstr &);\n";
+       << "const MachineInstr &, const SDep *);\n";
 }
 
 void MacroFusionPredicatorEmitter::emitMacroFusionImpl(
@@ -156,7 +158,9 @@ void MacroFusionPredicatorEmitter::emitMacroFusionImpl(
     OS.indent(4) << "const TargetInstrInfo &TII,\n";
     OS.indent(4) << "const TargetSubtargetInfo &STI,\n";
     OS.indent(4) << "const MachineInstr *FirstMI,\n";
-    OS.indent(4) << "const MachineInstr &SecondMI) {\n";
+    OS.indent(4) << "const MachineInstr &SecondMI, const SDep *Dep) {\n";
+    OS.indent(2) << "if (isNonDataDep(Dep))\n";
+    OS.indent(4) << "return false;\n";
     OS.indent(2)
         << "[[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();\n";
 

>From 62667178cf76e29a5f59c81ac7973d4077bb9660 Mon Sep 17 00:00:00 2001
From: tomershafir <tomer.shafir8 at gmail.com>
Date: Wed, 29 Jul 2026 11:24:21 +0300
Subject: [PATCH 2/2] fix missing documentation

---
 llvm/include/llvm/CodeGen/MacroFusion.h              | 5 +++--
 llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp | 8 ++++++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/MacroFusion.h b/llvm/include/llvm/CodeGen/MacroFusion.h
index 1ff590d8f260f..c059122a2899d 100644
--- a/llvm/include/llvm/CodeGen/MacroFusion.h
+++ b/llvm/include/llvm/CodeGen/MacroFusion.h
@@ -29,8 +29,9 @@ class SUnit;
 class SDep;
 
 /// Check if the instr pair, FirstMI and SecondMI, should be fused
-/// together. Given SecondMI, when FirstMI is unspecified, then check if
-/// SecondMI may be part of a fused pair at all.
+/// together, based on the dependency between them, Dep. Given SecondMI, when
+/// FirstMI is unspecified, then check if SecondMI may be part of a fused pair
+/// at all.
 using MacroFusionPredTy = bool (*)(const TargetInstrInfo &TII,
                                    const TargetSubtargetInfo &STI,
                                    const MachineInstr *FirstMI,
diff --git a/llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp b/llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp
index 92b9e7de5aefb..0e5985cd694f2 100644
--- a/llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp
+++ b/llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp
@@ -36,7 +36,8 @@
 // bool isNAME(const TargetInstrInfo &TII,
 //             const TargetSubtargetInfo &STI,
 //             const MachineInstr *FirstMI,
-//             const MachineInstr &SecondMI, const SDep *Dep) {
+//             const MachineInstr &SecondMI,
+//             const SDep *Dep) {
 //   if (isNonDataDep(Dep))
 //     return false;
 //   auto &MRI = SecondMI.getMF()->getRegInfo();
@@ -56,7 +57,10 @@
 // bool isNAME(const TargetInstrInfo &TII,
 //             const TargetSubtargetInfo &STI,
 //             const MachineInstr *FirstMI,
-//             const MachineInstr &SecondMI) {
+//             const MachineInstr &SecondMI,
+//             const SDep *Dep) {
+//   if (isNonDataDep(Dep))
+//     return false;
 //   auto &MRI = SecondMI.getMF()->getRegInfo();
 //   if (SecondMI.getMF()->getProperties().hasNoVRegs())
 //     return false;



More information about the llvm-commits mailing list