[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