[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