[llvm] 0eac970 - RegisterCoalescer: Remove empty subranges after merging subranges (#222050)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 13 08:40:32 PDT 2026


Author: Matt Arsenault
Date: 2026-09-13T17:40:27+02:00
New Revision: 0eac970fa7478ddf0083dc2a0a5c476ca3bb615a

URL: https://github.com/llvm/llvm-project/commit/0eac970fa7478ddf0083dc2a0a5c476ca3bb615a
DIFF: https://github.com/llvm/llvm-project/commit/0eac970fa7478ddf0083dc2a0a5c476ca3bb615a.diff

LOG: RegisterCoalescer: Remove empty subranges after merging subranges (#222050)

Merging subranges in joinVirtRegs didn't try to clear empty ranges after
refineSubRanges, manifesting in an assert in overlaps checks later.

Exposed with subregister liveness once LiveIntervals runs before
TwoAddress.

Co-authored-by: Claude (Claude-Opus-4.8)

Added: 
    llvm/test/CodeGen/AArch64/coalescer-empty-subrange-early-lis.ll

Modified: 
    llvm/lib/CodeGen/RegisterCoalescer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 87f4b25f38859..23b151ed7b981 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -3693,6 +3693,10 @@ void RegisterCoalescer::mergeSubRangeInto(LiveInterval &LI,
         }
       },
       *LIS->getSlotIndexes(), *TRI, ComposeSubRegIdx);
+
+  // Merging may leave subranges empty; drop them so the interval is left in a
+  // valid state.
+  LI.removeEmptySubRanges();
 }
 
 bool RegisterCoalescer::isHighCostLiveInterval(LiveInterval &LI) {

diff  --git a/llvm/test/CodeGen/AArch64/coalescer-empty-subrange-early-lis.ll b/llvm/test/CodeGen/AArch64/coalescer-empty-subrange-early-lis.ll
new file mode 100644
index 0000000000000..02a5b3d33261b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/coalescer-empty-subrange-early-lis.ll
@@ -0,0 +1,30 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=aarch64-unknown-linux-gnu -enable-subreg-liveness -mattr=+sve2 \
+; RUN:     -force-streaming-compatible -early-live-intervals -verify-coalescing \
+; RUN:     < %s | FileCheck %s
+
+; Merging subranges in the register coalescer can leave a value-less
+; remainder subrange behind. It must be removed; otherwise the empty
+; subrange reaches the register allocator and asserts. Only exposed
+; with subregister liveness and LiveIntervals running before
+; TwoAddress.
+
+define <8 x i8> @concat_v8i8(<4 x i8> %op1) {
+; CHECK-LABEL: concat_v8i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    fmov s1, wzr
+; CHECK-NEXT:    mov z2.h, z0.h[3]
+; CHECK-NEXT:    mov z3.h, z0.h[2]
+; CHECK-NEXT:    mov z4.h, z0.h[1]
+; CHECK-NEXT:    zip1 z2.b, z3.b, z2.b
+; CHECK-NEXT:    zip1 z0.b, z0.b, z4.b
+; CHECK-NEXT:    zip1 z1.b, z1.b, z1.b
+; CHECK-NEXT:    zip1 z0.h, z0.h, z2.h
+; CHECK-NEXT:    zip1 z1.h, z1.h, z1.h
+; CHECK-NEXT:    zip1 z0.s, z0.s, z1.s
+; CHECK-NEXT:    ret
+  %res = shufflevector <4 x i8> %op1, <4 x i8> zeroinitializer,
+                       <8 x i32> <i32 0, i32 1, i32 2, i32 3,
+                                  i32 4, i32 5, i32 6, i32 7>
+  ret <8 x i8> %res
+}


        


More information about the llvm-commits mailing list