[llvm] ed389ca - [CodeGen][ARM] Add regression tests for #202263 (#202599)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 29 05:30:02 PDT 2026
Author: Aochang Liu
Date: 2026-07-29T12:29:56Z
New Revision: ed389ca093797baab0bcc95ffd2b6ca41741c40d
URL: https://github.com/llvm/llvm-project/commit/ed389ca093797baab0bcc95ffd2b6ca41741c40d
DIFF: https://github.com/llvm/llvm-project/commit/ed389ca093797baab0bcc95ffd2b6ca41741c40d.diff
LOG: [CodeGen][ARM] Add regression tests for #202263 (#202599)
The underlying issue—RegisterCoalescer eliminating an undef COPY and
leaving a partial subregister redef that reads a value that no longer
exists—was fixed in #204039.
This PR adds the regression coverage originally developed alongside the
fix attempt, so the pattern remains covered:
- an end-to-end IR test that checks the generated assembly with
FileCheck;
- a focused single-pass `-run-pass=register-coalescer` MIR test using
`-verify-coalescing`, which reproduces the "Instruction is reading
nonexistent value" verifier error from #202263 when #204039 is reverted,
and passes with the fix applied.
Fixes #202263
Added:
llvm/test/CodeGen/ARM/regcoalesce-undef-copy-subreg-redef.ll
llvm/test/CodeGen/ARM/regcoalesce-undef-copy-subreg-redef.mir
Modified:
Removed:
################################################################################
diff --git a/llvm/test/CodeGen/ARM/regcoalesce-undef-copy-subreg-redef.ll b/llvm/test/CodeGen/ARM/regcoalesce-undef-copy-subreg-redef.ll
new file mode 100644
index 0000000000000..7cb2a68a18d73
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/regcoalesce-undef-copy-subreg-redef.ll
@@ -0,0 +1,36 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=armv8a-unknown-linux < %s | FileCheck %s
+
+; Regression test for issue #202263. Lowering the REG_SEQUENCE that builds the
+; <2 x i64> keeps a COPY of an undefined value which feeds a later partial
+; subregister redef. When RegisterCoalescer eliminates that copy, the redef
+; must be turned into a read-undef def. Otherwise the coalescer asserts with
+; "Instruction is reading nonexistent value" on targets that do not track
+; subregister liveness (armv8a A-profile has no MVE).
+
+define void @init(i64 %x, i1 %c, ptr %p) {
+; CHECK-LABEL: init:
+; CHECK: @ %bb.0: @ %entry
+; CHECK-NEXT: tst r2, #1
+; CHECK-NEXT: bxne lr
+; CHECK-NEXT: .LBB0_1: @ %body
+; CHECK-NEXT: vmov.32 d17[0], r0
+; CHECK-NEXT: mov r0, #1
+; CHECK-NEXT: vmov.32 d17[1], r1
+; CHECK-NEXT: vmov.32 d16[0], r0
+; CHECK-NEXT: mov r0, #0
+; CHECK-NEXT: vmov.32 d16[1], r0
+; CHECK-NEXT: vst1.64 {d16, d17}, [r3]
+; CHECK-NEXT: bx lr
+entry:
+ %v0 = insertelement <2 x i64> poison, i64 %x, i64 1
+ br i1 %c, label %exit, label %body
+
+body:
+ %v1 = insertelement <2 x i64> %v0, i64 1, i64 0
+ store <2 x i64> %v1, ptr %p, align 8
+ br label %exit
+
+exit:
+ ret void
+}
diff --git a/llvm/test/CodeGen/ARM/regcoalesce-undef-copy-subreg-redef.mir b/llvm/test/CodeGen/ARM/regcoalesce-undef-copy-subreg-redef.mir
new file mode 100644
index 0000000000000..d13b6c6f883ce
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/regcoalesce-undef-copy-subreg-redef.mir
@@ -0,0 +1,84 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=armv8a-unknown-linux -run-pass=register-coalescer -verify-coalescing -o - %s | FileCheck %s
+
+# Regression test for issue #202263 (and the long-standing #200378). After
+# RegisterCoalescer eliminates the COPY of an undefined value, the partial
+# subregister redef that implicitly read it must become a read-undef def;
+# otherwise the coalescer asserts "Instruction is reading nonexistent value"
+# on targets that do not track subregister liveness.
+#
+# The original failures reach this pattern through REG_SEQUENCE lowering.
+# This focused test starts at the RegisterCoalescer boundary, after that
+# lowering has produced the undef COPY and partial redef sequence.
+
+---
+name: init
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: init
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK-NEXT: liveins: $r0, $r1, $r2, $r3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $r3
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $r2
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $r1
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $r0
+ ; CHECK-NEXT: TSTri [[COPY1]], 1, 14 /* CC::al */, $noreg, implicit-def $cpsr
+ ; CHECK-NEXT: Bcc %bb.2, 0 /* CC::eq */, killed $cpsr
+ ; CHECK-NEXT: B %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: BX_RET 14 /* CC::al */, $noreg
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2:
+ ; CHECK-NEXT: successors: %bb.1(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: undef [[VSETLNi32_:%[0-9]+]].dsub_1:qpr = VSETLNi32 undef [[VSETLNi32_]].dsub_1, [[COPY3]], 0, 14 /* CC::al */, $noreg
+ ; CHECK-NEXT: [[VSETLNi32_:%[0-9]+]].dsub_1:qpr = VSETLNi32 [[VSETLNi32_]].dsub_1, [[COPY2]], 1, 14 /* CC::al */, $noreg
+ ; CHECK-NEXT: [[MOVi:%[0-9]+]]:gpr = MOVi 1, 14 /* CC::al */, $noreg, $noreg
+ ; CHECK-NEXT: [[VSETLNi32_:%[0-9]+]].dsub_0:qpr = VSETLNi32 [[VSETLNi32_]].dsub_0, [[MOVi]], 0, 14 /* CC::al */, $noreg
+ ; CHECK-NEXT: [[MOVi1:%[0-9]+]]:gpr = MOVi 0, 14 /* CC::al */, $noreg, $noreg
+ ; CHECK-NEXT: [[VSETLNi32_:%[0-9]+]].dsub_0:qpr = VSETLNi32 [[VSETLNi32_]].dsub_0, [[MOVi1]], 1, 14 /* CC::al */, $noreg
+ ; CHECK-NEXT: VST1q64 [[COPY]], 0, [[VSETLNi32_]], 14 /* CC::al */, $noreg
+ ; CHECK-NEXT: B %bb.1
+ bb.0:
+ successors: %bb.1, %bb.2
+ liveins: $r0, $r1, $r2, $r3
+
+ %4:gpr = COPY killed $r3
+ %3:gpr = COPY killed $r2
+ %2:gpr = COPY killed $r1
+ %1:gpr = COPY killed $r0
+ TSTri killed %3, 1, 14 /* CC::al */, $noreg, implicit-def $cpsr
+ Bcc %bb.2, 0 /* CC::eq */, killed $cpsr
+ B %bb.1
+
+ bb.1:
+ BX_RET 14 /* CC::al */, $noreg
+
+ bb.2:
+ successors: %bb.1
+
+ ; The COPY of an undef value below feeds the dsub_1 partial redef. After the
+ ; copy is eliminated, that redef must become a read-undef def.
+ %5:dpr = VSETLNi32 undef %5, killed %1, 0, 14 /* CC::al */, $noreg
+ %7:dpr = COPY killed %5
+ %7:dpr = VSETLNi32 %7, killed %2, 1, 14 /* CC::al */, $noreg
+ undef %8.dsub_0:qpr = COPY undef %9:dpr
+ %8.dsub_1:qpr = COPY killed %7
+ %11:gpr = MOVi 1, 14 /* CC::al */, $noreg, $noreg
+ %12:dpr = COPY %8.dsub_0
+ %13:dpr = COPY killed %12
+ %13:dpr = VSETLNi32 %13, killed %11, 0, 14 /* CC::al */, $noreg
+ %14:gpr = MOVi 0, 14 /* CC::al */, $noreg, $noreg
+ %15:qpr = COPY killed %8
+ %15.dsub_0:qpr = COPY %13
+ %16:dpr = COPY killed %13
+ %17:dpr = COPY killed %16
+ %17:dpr = VSETLNi32 %17, killed %14, 1, 14 /* CC::al */, $noreg
+ %18:qpr = COPY killed %15
+ %18.dsub_0:qpr = COPY killed %17
+ VST1q64 killed %4, 0, killed %18, 14 /* CC::al */, $noreg
+ B %bb.1
+...
More information about the llvm-commits
mailing list