[llvm] 4346303 - [MachinePipeliner] Remove cheap check in dependence analysis (#174390)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 14 18:32:50 PST 2026
Author: Ryotaro Kasuga
Date: 2026-01-15T02:32:45Z
New Revision: 434630333e52ce2a12248fee47f8a727632ce5d5
URL: https://github.com/llvm/llvm-project/commit/434630333e52ce2a12248fee47f8a727632ce5d5
DIFF: https://github.com/llvm/llvm-project/commit/434630333e52ce2a12248fee47f8a727632ce5d5.diff
LOG: [MachinePipeliner] Remove cheap check in dependence analysis (#174390)
In loop-carried dependence analysis of MachinePipeliner, there is
special handling for a specific case, referred to as a "cheap check".
This check is not sound and sometimes misses dependencies. If there is
no significant performance regression, this special logic should be
deleted.
Split off from https://github.com/llvm/llvm-project/pull/135148
Added:
Modified:
llvm/lib/CodeGen/MachinePipeliner.cpp
llvm/test/CodeGen/Hexagon/swp-carried-dep1.mir
llvm/test/CodeGen/Hexagon/swp-carried-dep2.mir
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index 59ead74da6fb6..6b022783f4bb8 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -344,15 +344,9 @@ class LoopCarriedOrderDepsTracker {
const LoadStoreChunk &To);
/// Add a loop-carried order dependency between \p Src and \p Dst if we
- /// cannot prove they are independent. When \p PerformCheapCheck is true, a
- /// lightweight dependency test (referred to as "cheap check" below) is
- /// performed at first. Note that the cheap check is retained to maintain the
- /// existing behavior and not expected to be used anymore.
- ///
- /// TODO: Remove \p PerformCheapCheck and the corresponding cheap check.
+ /// cannot prove they are independent.
void addDependenciesBetweenSUs(const SUnitWithMemInfo &Src,
- const SUnitWithMemInfo &Dst,
- bool PerformCheapCheck = false);
+ const SUnitWithMemInfo &Dst);
void computeDependenciesAux();
};
@@ -1051,11 +1045,12 @@ bool SUnitWithMemInfo::getUnderlyingObjects() {
/// Returns true if there is a loop-carried order dependency from \p Src to \p
/// Dst.
-static bool
-hasLoopCarriedMemDep(const SUnitWithMemInfo &Src, const SUnitWithMemInfo &Dst,
- BatchAAResults &BAA, const TargetInstrInfo *TII,
- const TargetRegisterInfo *TRI,
- const SwingSchedulerDAG *SSD, bool PerformCheapCheck) {
+static bool hasLoopCarriedMemDep(const SUnitWithMemInfo &Src,
+ const SUnitWithMemInfo &Dst,
+ BatchAAResults &BAA,
+ const TargetInstrInfo *TII,
+ const TargetRegisterInfo *TRI,
+ const SwingSchedulerDAG *SSD) {
if (Src.isTriviallyDisjoint(Dst))
return false;
if (isSuccOrder(Src.SU, Dst.SU))
@@ -1063,28 +1058,6 @@ hasLoopCarriedMemDep(const SUnitWithMemInfo &Src, const SUnitWithMemInfo &Dst,
MachineInstr &SrcMI = *Src.SU->getInstr();
MachineInstr &DstMI = *Dst.SU->getInstr();
- if (PerformCheapCheck) {
- // First, perform the cheaper check that compares the base register.
- // If they are the same and the load offset is less than the store
- // offset, then mark the dependence as loop carried potentially.
- //
- // TODO: This check will be removed.
- const MachineOperand *BaseOp1, *BaseOp2;
- int64_t Offset1, Offset2;
- bool Offset1IsScalable, Offset2IsScalable;
- if (TII->getMemOperandWithOffset(SrcMI, BaseOp1, Offset1, Offset1IsScalable,
- TRI) &&
- TII->getMemOperandWithOffset(DstMI, BaseOp2, Offset2, Offset2IsScalable,
- TRI)) {
- if (BaseOp1->isIdenticalTo(*BaseOp2) &&
- Offset1IsScalable == Offset2IsScalable &&
- (int)Offset1 < (int)Offset2) {
- assert(TII->areMemAccessesTriviallyDisjoint(SrcMI, DstMI) &&
- "What happened to the chain edge?");
- return true;
- }
- }
- }
if (!SSD->mayOverlapInLaterIter(&SrcMI, &DstMI))
return false;
@@ -1158,13 +1131,12 @@ LoopCarriedOrderDepsTracker::getInstrTag(SUnit *SU) const {
}
void LoopCarriedOrderDepsTracker::addDependenciesBetweenSUs(
- const SUnitWithMemInfo &Src, const SUnitWithMemInfo &Dst,
- bool PerformCheapCheck) {
+ const SUnitWithMemInfo &Src, const SUnitWithMemInfo &Dst) {
// Avoid self-dependencies.
if (Src.SU == Dst.SU)
return;
- if (hasLoopCarriedMemDep(Src, Dst, *BAA, TII, TRI, DAG, PerformCheapCheck))
+ if (hasLoopCarriedMemDep(Src, Dst, *BAA, TII, TRI, DAG))
LoopCarried[Src.SU->NodeNum].set(Dst.SU->NodeNum);
}
@@ -1173,8 +1145,7 @@ void LoopCarriedOrderDepsTracker::addLoopCarriedDepenenciesForChunks(
// Add load-to-store dependencies (WAR).
for (const SUnitWithMemInfo &Src : From.Loads)
for (const SUnitWithMemInfo &Dst : To.Stores)
- // Perform a cheap check first if this is a forward dependency.
- addDependenciesBetweenSUs(Src, Dst, Src.SU->NodeNum < Dst.SU->NodeNum);
+ addDependenciesBetweenSUs(Src, Dst);
// Add store-to-load dependencies (RAW).
for (const SUnitWithMemInfo &Src : From.Stores)
diff --git a/llvm/test/CodeGen/Hexagon/swp-carried-dep1.mir b/llvm/test/CodeGen/Hexagon/swp-carried-dep1.mir
index afc989cbc6921..8ff61fc4b11ab 100644
--- a/llvm/test/CodeGen/Hexagon/swp-carried-dep1.mir
+++ b/llvm/test/CodeGen/Hexagon/swp-carried-dep1.mir
@@ -3,7 +3,13 @@
# Test that the loop carried dependence check correctly identifies a recurrence.
-# CHECK: Overlap check:
+# CHECK: Overlap check:
+# CHECK-NEXT: BaseMI: %17:intregs = L2_loadrh_io %12:intregs, -8 :: (load (s16) from %ir.cgep10)
+# CHECK-NEXT: Base + -8 + I * 4, Len: 2
+# CHECK-NEXT: OtherMI: S2_storerh_io %12:intregs, 0, %18:intregs :: (store (s16) into %ir.lsr.iv24)
+# CHECK-NEXT: Base + 0 + I * 4, Len: 2
+# CHECK-NEXT: Result: No overlap
+# CHECK: Overlap check:
# CHECK-NEXT: BaseMI: S2_storerh_io %{{[0-9]+}}:intregs, 0, %{{[0-9]+}}:intregs :: (store (s16) into %ir.lsr.iv24)
# CHECK-NEXT: Base + 0 + I * 4, Len: 2
# CHECK-NEXT: OtherMI: %{{[0-9]+}}:intregs = L2_loadrh_io %{{[0-9]+}}:intregs, -8 :: (load (s16) from %ir.cgep10)
diff --git a/llvm/test/CodeGen/Hexagon/swp-carried-dep2.mir b/llvm/test/CodeGen/Hexagon/swp-carried-dep2.mir
index e16334ba7978f..fcab9613b6ec9 100644
--- a/llvm/test/CodeGen/Hexagon/swp-carried-dep2.mir
+++ b/llvm/test/CodeGen/Hexagon/swp-carried-dep2.mir
@@ -4,24 +4,21 @@
# Test that the loop carried dependence check correctly identifies dependences
# when the loop variable decreases and the array index offset is negative.
-# No dependence from the store to the load.
-# CHECK: Overlap check:
+# No dependence from the store to the load, but there is a dependence from the
+# load to the store.
+# CHECK: Overlap check:
+# CHECK-NEXT: BaseMI: %{{[0-9]+}}:intregs = L2_loadri_io %{{[0-9]+}}:intregs, -8 :: (load (s32) from %ir.cgep)
+# CHECK-NEXT: Base + -8 + I * -4, Len: 4
+# CHECK-NEXT: OtherMI: S2_storeri_io %{{[0-9]+}}:intregs, 0, %{{[0-9]+}}:intregs :: (store (s32) into %ir.lsr.iv1)
+# CHECK-NEXT: Base + 0 + I * -4, Len: 4
+# CHECK-NEXT: Result: Overlap
+# CHECK: Overlap check:
# CHECK-NEXT: BaseMI: S2_storeri_io %{{[0-9]+}}:intregs, 0, %{{[0-9]+}}:intregs :: (store (s32) into %ir.lsr.iv1)
# CHECK-NEXT: Base + 0 + I * -4, Len: 4
# CHECK-NEXT: OtherMI: %{{[0-9]+}}:intregs = L2_loadri_io %{{[0-9]+}}:intregs, -8 :: (load (s32) from %ir.cgep)
# CHECK-NEXT: Base + -8 + I * -4, Len: 4
# CHECK-NEXT: Result: No overlap
-# TODO: There is a loop carried dependence from the load to the store but it
-# is not recognised. addLoopCarriedDependences() should be modified to
-# recognise the dependence and enable the following checks.
-# CHECK-AFTER-FIX: Overlap check:
-# CHECK-AFTER-FIX-NEXT: BaseMI: %{{[0-9]+}}:intregs = L2_loadri_io %{{[0-9]+}}:intregs, -8 :: (load (s32) from %ir.cgep)
-# CHECK-AFTER-FIX-NEXT: Base + -8 + I * -4, Len: 4
-# CHECK-AFTER-FIX-NEXT: OtherMI: S2_storeri_io %{{[0-9]+}}:intregs, 0, %{{[0-9]+}}:intregs :: (store (s32) into %ir.lsr.iv1)
-# CHECK-AFTER-FIX-NEXT: Base + 0 + I * -4, Len: 4
-# CHECK-AFTER-FIX-NEXT: Result: Overlap!
-
--- |
define void @test() {
More information about the llvm-commits
mailing list