[llvm] [CodeGen][ARM] Keep undef REG_SEQUENCE operands live for full-register uses without LIS (PR #203178)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 10 23:02:21 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-arm

Author: hsnaveen2u

<details>
<summary>Changes</summary>

When eliminating a REG_SEQUENCE in TwoAddressInstruction, undef source operands were unconditionally skipped when LiveIntervals were available even when the REG_SEQUENCE result had a full-register (non-subregister) use. This caused the RegisterCoalescer to assert because the resulting live interval was missing a defining value for the lane.

The patch makes the no-LIS path conservative by treating a non-undef full-register use as using all lanes preserving the required undef operand.

Fixes: https://github.com/llvm/llvm-project/issues/202263

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


2 Files Affected:

- (modified) llvm/lib/CodeGen/TwoAddressInstructionPass.cpp (+4-1) 
- (added) llvm/test/CodeGen/ARM/regsequence-undef-fullreg-use.ll (+22) 


``````````diff
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index fb3014d87f40a..673a0827c0489 100644
--- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -2058,7 +2058,10 @@ void TwoAddressInstructionImpl::eliminateRegSequence(
   // If there are no live intervals information, we scan the use list once
   // in order to find which subregisters are used.
   LaneBitmask UsedLanes = LaneBitmask::getNone();
-  if (!LIS) {
+  // Only do this when the target tracks subregister liveness. Otherwise
+  // liveness is tracked per whole register so a used undef lane is already
+  // covered by the register's liveness and does not need its own def.
+  if (!LIS && MRI->shouldTrackSubRegLiveness(DstReg)) {
     for (MachineOperand &Use : MRI->use_nodbg_operands(DstReg)) {
       if (unsigned SubReg = Use.getSubReg())
         UsedLanes |= TRI->getSubRegIndexLaneMask(SubReg);
diff --git a/llvm/test/CodeGen/ARM/regsequence-undef-fullreg-use.ll b/llvm/test/CodeGen/ARM/regsequence-undef-fullreg-use.ll
new file mode 100644
index 0000000000000..bffa5f90249d6
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/regsequence-undef-fullreg-use.ll
@@ -0,0 +1,22 @@
+; REQUIRES: arm-registered-target
+; RUN: llc -mtriple=armv8a-unknown-linux-gnueabi -verify-machineinstrs < %s -o /dev/null
+
+; This used to assert in RegisterCoalescer after REG_SEQUENCE lowering skipped
+; an undef lane even though the REG_SEQUENCE result had a full-register use.
+
+target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv8a-unknown-linux-gnueabi"
+
+define void @init(i64 %0, i1 %min.iters.check, ptr %1) {
+entry:
+  %2 = insertelement <2 x i64> poison, i64 %0, i64 1
+  br i1 %min.iters.check, label %common.ret, label %vector.body
+
+common.ret:
+  ret void
+
+vector.body:
+  %3 = insertelement <2 x i64> %2, i64 1, i64 0
+  store <2 x i64> %3, ptr %1, align 8
+  br label %common.ret
+}

``````````

</details>


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


More information about the llvm-commits mailing list