[llvm-branch-commits] [llvm] [AMDGPU] Raise the MachinePipeliner MII cap via a target hook (PR #212537)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jul 29 07:53:03 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: hjagasiaAMD

<details>
<summary>Changes</summary>

The pipeliner rejects any loop whose minimum initiation interval (MII)
exceeds -pipeliner-max-mii, default 27. That is far too low for real
AMDGPU loops: resource-bound GEMM/attention bodies routinely have an MII
well above 27 and are dropped before scheduling even starts.

Add a PipelinerLoopInfo::getMaxMII() hook so a target can raise the cap,
and override it to 256 for AMDGPU. The generic default is unchanged, and
an explicit -pipeliner-max-mii still takes precedence.

The cap of 256 is chosen from the II distributions of two AMDGPU
workloads.

Composable Kernels:
  II range   count    pct
    0- 24     2305   36.7%
   25- 49     1681   26.8%
   50- 99     1582   25.3%
  100-149      578    9.2%
  150-299       64    1.0%

Triton:
  II range   count    pct
   96-128       19   50.0%
  128-160       11   28.9%
  160-192        2    5.3%
  192-224        2    5.3%
  224-256        4   10.5%

256 captures the bulk of both workloads while still rejecting
pathologically large loops up front.

---
Full diff: https://github.com/llvm/llvm-project/pull/212537.diff


4 Files Affected:

- (modified) llvm/include/llvm/CodeGen/TargetInstrInfo.h (+5) 
- (modified) llvm/lib/CodeGen/MachinePipeliner.cpp (+9-4) 
- (modified) llvm/lib/Target/AMDGPU/SIInstrInfo.cpp (+4) 
- (modified) llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-max-mii.ll (+5-6) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 4749d06501cb2..50c95a2208284 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -841,6 +841,11 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
       return true;
     }
 
+    /// Return a target-specific cap on the minimum initiation interval (MII)
+    /// above which a loop is not pipelined, or nullopt to use the default cap.
+    /// An explicit -pipeliner-max-mii takes precedence over this hook.
+    virtual std::optional<unsigned> getMaxMII() const { return std::nullopt; }
+
     /// Create a condition to determine if the trip count of the loop is greater
     /// than TC, where TC is always one more than for the previous prologue or
     /// 0 if this is being called for the outermost prologue.
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index a97e0702d1911..d715e1e966998 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -813,16 +813,21 @@ void SwingSchedulerDAG::schedule() {
   }
 
   // Don't pipeline large loops.
-  if (SwpMaxMii != -1 && (int)MII > SwpMaxMii) {
-    LLVM_DEBUG(dbgs() << "MII > " << SwpMaxMii
+  int MaxMII = SwpMaxMii;
+  if (SwpMaxMii.getNumOccurrences() == 0 && LoopPipelinerInfo)
+    if (std::optional<unsigned> TargetMaxMII = LoopPipelinerInfo->getMaxMII())
+      MaxMII = (int)*TargetMaxMII;
+
+  if (MaxMII != -1 && (int)MII > MaxMII) {
+    LLVM_DEBUG(dbgs() << "MII > " << MaxMII
                       << ", we don't pipeline large loops\n");
     NumFailLargeMaxMII++;
     Pass.ORE->emit([&]() {
       return MachineOptimizationRemarkAnalysis(
                  DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
              << "Minimal Initiation Interval too large: "
-             << ore::NV("MII", (int)MII) << " > "
-             << ore::NV("SwpMaxMii", SwpMaxMii) << "."
+             << ore::NV("MII", (int)MII) << " > " << ore::NV("MaxMII", MaxMII)
+             << "."
              << "Refer to -pipeliner-max-mii.";
     });
     return;
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index 3fa0e68e62f97..fd74399ca97c5 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -3307,6 +3307,10 @@ class AMDGPUPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
     return CmpInst && MI == CmpInst;
   }
 
+  // The generic default of 27 is too low for real AMDGPU loops; use a wider
+  // cap that still rejects pathologically large ones.
+  std::optional<unsigned> getMaxMII() const override { return 256; }
+
   std::optional<bool> createTripCountGreaterCondition(
       int TC, MachineBasicBlock &MBB,
       SmallVectorImpl<MachineOperand> &CondParam) override {
diff --git a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-max-mii.ll b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-max-mii.ll
index 99e6090bb35e5..7356f2c34a6a0 100644
--- a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-max-mii.ll
+++ b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-max-mii.ll
@@ -1,12 +1,11 @@
 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx950 -amdgpu-enable-pipeliner -pass-remarks-analysis=pipeliner %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=DEFAULT
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx950 -amdgpu-enable-pipeliner -pipeliner-max-mii=64 -pass-remarks-analysis=pipeliner %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=RAISED
-
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx950 -amdgpu-enable-pipeliner -pipeliner-max-mii=27 -pass-remarks-analysis=pipeliner %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=CAPPED
 ; This loop's MII is 32: two independent accumulators each issue one MFMA per
 ; iteration, and each MFMA holds the XDL pipe for 16 cycles (res=32). That
-; exceeds the generic default cap of 27. At default, pipeliner aborts and
-; only a raised cap lets it schedule.
-; DEFAULT: Minimal Initiation Interval too large: 32 > 27
-; RAISED: Schedule found with Initiation Interval
+; exceeds the generic default cap of 27. Loop pipelines at default but an
+; explicit -pipeliner-max-mii below the MII still rejects it.
+; DEFAULT: Schedule found with Initiation Interval
+; CAPPED: Minimal Initiation Interval too large: 32 > 27
 
 declare <16 x float> @llvm.amdgcn.mfma.f32.32x32x2f32(float, float, <16 x float>, i32 immarg, i32 immarg, i32 immarg)
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/212537


More information about the llvm-branch-commits mailing list