https://github.com/lucas-rami updated
https://github.com/llvm/llvm-project/pull/196098
>From c35c4499a80bc97cd36e8fb1ecca282dc5bdfa9f Mon Sep 17 00:00:00 2001
From: Lucas Ramirez
Date: Wed, 6 May 2026 15:15:30 +
Subject: [PATCH] [AMDGPU] Pre-commit unit test for RP tracking reset/advance
behavior
This adds a new AMDGPU unit test file for testing the behavior of
`GCNRPTracker` and its related classes. The two test showcase confusing
return value and behavioral semantics for variants of the advance and
reset functions, which will be clarified in a follow up commit.
This also moves some common test helpers from other AMDGPU unit tests to
the `AMDGPUUnitTests` TU to avoid repetition between unit tests.
---
llvm/unittests/Target/AMDGPU/CMakeLists.txt | 1 +
.../Target/AMDGPU/GCNRegPressureTest.cpp | 156 ++
2 files changed, 157 insertions(+)
create mode 100644 llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp
diff --git a/llvm/unittests/Target/AMDGPU/CMakeLists.txt
b/llvm/unittests/Target/AMDGPU/CMakeLists.txt
index 2425556ebe33f..6dfd635065dfe 100644
--- a/llvm/unittests/Target/AMDGPU/CMakeLists.txt
+++ b/llvm/unittests/Target/AMDGPU/CMakeLists.txt
@@ -26,6 +26,7 @@ add_llvm_target_unittest(AMDGPUTests
CSETest.cpp
DwarfRegMappings.cpp
ExecMayBeModifiedBeforeAnyUse.cpp
+ GCNRegPressureTest.cpp
LiveRegUnits.cpp
PALMetadata.cpp
UniformityAnalysisTest.cpp
diff --git a/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp
b/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp
new file mode 100644
index 0..ad84f4df65288
--- /dev/null
+++ b/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp
@@ -0,0 +1,156 @@
+//===- GCNRegPressureTest.cpp ---*- C++
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "GCNRegPressure.h"
+#include "AMDGPUUnitTests.h"
+#include "llvm/CodeGen/LiveIntervals.h"
+#include "llvm/CodeGen/MIRParser/MIRParser.h"
+#include "llvm/CodeGen/MachineFunctionAnalysis.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineScheduler.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+class GCNRegPressureTest : public llvm::CodeGenTestBase {
+public:
+ void SetUp() override { setUpImpl("amdgcn--", "gfx908", ""); }
+};
+
+TEST_F(GCNRegPressureTest, DownwardTrackerEndOnDbgVal) {
+ StringRef MIR = R"(
+name:DownwardTrackerEndOnDbgVal
+tracksRegLiveness: true
+machineFunctionInfo:
+ isEntryFunction: true
+body: |
+ bb.0:
+%0:vgpr_32 = IMPLICIT_DEF
+%1:vgpr_32 = IMPLICIT_DEF
+
+ bb.1:
+DBG_VALUE %0
+DBG_VALUE %1
+%2:vgpr_32 = IMPLICIT_DEF
+
+ bb.3:
+S_NOP 0, implicit %0, implicit %1, implicit %2
+S_ENDPGM 0
+...
+)";
+ EXPECT_TRUE(parseMIR(MIR));
+ MachineFunction &MF = getMF("DownwardTrackerEndOnDbgVal");
+ const LiveIntervals &LIS = MFAM.getResult(MF);
+
+ // MBB1 live-in pressure is equivalent to MBB0 live-out pressure.
+ MachineBasicBlock &MBB0 = *MF.getBlockNumbered(0);
+ MachineBasicBlock &MBB1 = *MF.getBlockNumbered(1);
+ GCNRPTracker::LiveRegSet MBB1LiveIns =
+ getLiveRegs(LIS.getInstructionIndex(*MBB0.rbegin()).getDeadSlot(), LIS,
+ MF.getRegInfo());
+
+ // Track pressure across MBB1.
+ {
+GCNDownwardRPTracker RPTracker(LIS), RPTrackerNoLiveIns(LIS);
+
+// There is a non-debug instruction in bb.1 (%2's def), so advance should
+// return true.
+EXPECT_TRUE(RPTracker.advance(MBB1.begin(), MBB1.end(), &MBB1LiveIns));
+EXPECT_TRUE(RPTrackerNoLiveIns.advance(MBB1.begin(), MBB1.end(), nullptr));
+
+// When advance returns true, maximum pressure should be the pressured
+// induced by the block's live-ins plus %2's def i.e., 3 VGPRs.
+EXPECT_EQ(RPTracker.moveMaxPressure().getVGPRNum(false), 3U);
+EXPECT_EQ(RPTrackerNoLiveIns.moveMaxPressure().getVGPRNum(false), 3U);
+ }
+
+ // Track pressure just across the first debug value of bb.1.
+ {
+MachineBasicBlock::iterator Dbg1 = std::next(MBB1.begin());
+GCNDownwardRPTracker RPTracker(LIS), RPTrackerNoLiveIns(LIS);
+
+// The following unpacks a call to
+// advance(*MBB1.begin(), Dbg1, [MBB1LiveIns|nullptr])
+// which would return false in this case.
+//
+// There aren't any non-debug instruction between the beginning of bb1 and
+// Dbg1 (exclusive). However, the call to reset takes the end of the MBB as
+// the limit, so it pushes the beginning of the block up to %2's def and
+// considers the reset successful.
+EXPECT_TRUE(RPTracker.reset(*MBB1.begin(), &MBB1LiveIns));
+EXPECT_TRU