[llvm] [CodeGen] Delete empty sub-ranges after refinement of rematerializations (PR #215632)
Lucas Ramirez via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 11 12:47:20 PDT 2026
https://github.com/lucas-rami updated https://github.com/llvm/llvm-project/pull/215632
>From 256c2f4e61fa9223d36a7582861dca7a0da9b6da Mon Sep 17 00:00:00 2001
From: Lucas Ramirez <lucas.rami at proton.me>
Date: Tue, 11 Aug 2026 17:53:48 +0000
Subject: [PATCH 1/2] [CodeGen] Delete empty sub-ranges after refinement of
rematerializations
Rematerializing registers which have uses of undefined lanes can yield
empty sub-ranges during refinement of the rematerialized register's
live interval. These are only allowed to temporarily exist and should
be removed before extending the interval to new indices.
---
llvm/lib/CodeGen/Rematerializer.cpp | 2 ++
llvm/unittests/CodeGen/RematerializerTest.cpp | 32 +++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/llvm/lib/CodeGen/Rematerializer.cpp b/llvm/lib/CodeGen/Rematerializer.cpp
index 088ab6af402ba..bf21a755083e8 100644
--- a/llvm/lib/CodeGen/Rematerializer.cpp
+++ b/llvm/lib/CodeGen/Rematerializer.cpp
@@ -844,6 +844,8 @@ void Rematerializer::extendToNewUsers(RegisterIdx RegIdx,
LI.refineSubRanges(
LIS.getVNInfoAllocator(), RegMask, [](LiveInterval::SubRange &SR) {},
*LIS.getSlotIndexes(), TRI);
+ // Refining may have introduced empty sub-ranges, which are illegal.
+ LI.removeEmptySubRanges();
}
extendInterval(LI, RegMask, UseIdx);
}
diff --git a/llvm/unittests/CodeGen/RematerializerTest.cpp b/llvm/unittests/CodeGen/RematerializerTest.cpp
index e0d4f261b70b9..410e239187124 100644
--- a/llvm/unittests/CodeGen/RematerializerTest.cpp
+++ b/llvm/unittests/CodeGen/RematerializerTest.cpp
@@ -825,6 +825,38 @@ TEST_F(RematerializerTest, SplitSubRegDeadDef) {
PreRemat);
}
+/// The rematerializer had a bug where rematerializing a register which has uses
+/// of undefined lanes could create empty sub-ranges during live-interval
+/// refinement. Empty sub-ranges are illegal and are only allowed to exist
+/// temporarily, so we would hit an assert when extending the live interval of
+/// the rematerialized register. The rematerializer now automatically deletes
+/// empty sub-ranges.
+TEST_F(RematerializerTest, RemoveEmptySubRanges) {
+ StringRef MIRBody = R"MIR(
+ bb.0:
+ undef %fullUndefUse.sub0:vreg_64 = IMPLICIT_DEF
+ undef %partialUndefUse.sub0_sub1_sub2:vreg_128 = IMPLICIT_DEF
+
+ bb.1:
+ S_NOP 0, implicit %fullUndefUse.sub1
+ S_NOP 0, implicit %partialUndefUse.sub2_sub3
+ S_ENDPGM 0
+)MIR";
+ rematerializerTest(MIRBody, [](RematerializerWrapper &RW) {
+ // Both registers in bb.0 should be rematerializable.
+ ASSERT_EQ(RW->getNumRegs(), 2U);
+
+ // Rematerialize both registers to bb.1. When the new registers intervals
+ // are created and extended to their users in bb.1, an empty sub-range will
+ // be temporarily created then removed immediately.
+ Rematerializer::DependencyReuseInfo DRI;
+ const unsigned MBB1 = 1;
+ const RegisterIdx FullUndefUse = 0, PartialUndefUse = 1;
+ RW->rematerializeToRegion(FullUndefUse, MBB1, DRI);
+ RW->rematerializeToRegion(PartialUndefUse, MBB1, DRI.clear());
+ });
+}
+
/// Checks that dead-def elimination successfully deletes all unrematerializable
/// MIs and rematerializable registers that become dead after shrinking the
/// interval of an unrematerializable register reveals a dead definition.
>From e635b7ccf7e81aea99d4a5653e7fbfe882f16c6f Mon Sep 17 00:00:00 2001
From: Lucas Ramirez <11032120+lucas-rami at users.noreply.github.com>
Date: Tue, 11 Aug 2026 21:47:10 +0200
Subject: [PATCH 2/2] Update llvm/unittests/CodeGen/RematerializerTest.cpp
Co-authored-by: Zach Goldthorpe <Zach.Goldthorpe at amd.com>
---
llvm/unittests/CodeGen/RematerializerTest.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/llvm/unittests/CodeGen/RematerializerTest.cpp b/llvm/unittests/CodeGen/RematerializerTest.cpp
index 410e239187124..3d164dfd51d98 100644
--- a/llvm/unittests/CodeGen/RematerializerTest.cpp
+++ b/llvm/unittests/CodeGen/RematerializerTest.cpp
@@ -825,12 +825,10 @@ TEST_F(RematerializerTest, SplitSubRegDeadDef) {
PreRemat);
}
-/// The rematerializer had a bug where rematerializing a register which has uses
-/// of undefined lanes could create empty sub-ranges during live-interval
+/// Uses of undefined lanes may create empty sub-ranges during live-interval
/// refinement. Empty sub-ranges are illegal and are only allowed to exist
-/// temporarily, so we would hit an assert when extending the live interval of
-/// the rematerialized register. The rematerializer now automatically deletes
-/// empty sub-ranges.
+/// temporarily. The rematerializer now automatically deletes these empty
+/// sub-ranges.
TEST_F(RematerializerTest, RemoveEmptySubRanges) {
StringRef MIRBody = R"MIR(
bb.0:
More information about the llvm-commits
mailing list