[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