[llvm] RISCV: Maintain VL/VTYPE liveness when clearing dead flags in InsertVSETVLI (PR #222862)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 11 00:02:25 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/222862
Drop the stale VL/VTYPE ranges when a dead flag is cleared.
RISCVInsertVSETVLI marks the VL and VTYPE defs of an explicit VSETVLI as live by
clearing their dead flags, but did not update LiveIntervals. When a def was
previously a dead def, its live range is a zero-length dead-def segment
ending at the def slot; clearing the flag extends the def past that slot without
extending the range leaving a segment that references no instruction.
Co-authored-by: Claude claude-opus-4.8 <noreply at anthropic.com>
>From 94b410e866600f971ef0dfa9852dca77d347f8b8 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 10 Sep 2026 22:25:39 +0200
Subject: [PATCH] RISCV: Maintain VL/VTYPE liveness when clearing dead flags in
InsertVSETVLI
Drop the stale VL/VTYPE ranges when a dead flag is cleared.
RISCVInsertVSETVLI marks the VL and VTYPE defs of an explicit VSETVLI as live by
clearing their dead flags, but did not update LiveIntervals. When a def was
previously a dead def, its live range is a zero-length dead-def segment
ending at the def slot; clearing the flag extends the def past that slot without
extending the range leaving a segment that references no instruction.
Co-authored-by: Claude claude-opus-4.8 <noreply at anthropic.com>
---
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 10 ++++++
.../rvv/vsetvli-dead-vl-vtype-liveness.mir | 33 +++++++++++++++++++
2 files changed, 43 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/rvv/vsetvli-dead-vl-vtype-liveness.mir
diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index 2333ede15f50d..62b8e9f1e0ef4 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -543,6 +543,16 @@ void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) {
assert(MI.getOperand(3).getReg() == RISCV::VL &&
MI.getOperand(4).getReg() == RISCV::VTYPE &&
"Unexpected operands where VL and VTYPE should be");
+
+ if (LIS) {
+ // Clearing a dead flag extends that def past its previous dead-def
+ // slot, so the stale VL/VTYPE range must be dropped.
+ if (MI.getOperand(3).isDead())
+ LIS->removeAllRegUnitsForPhysReg(RISCV::VL);
+ if (MI.getOperand(4).isDead())
+ LIS->removeAllRegUnitsForPhysReg(RISCV::VTYPE);
+ }
+
MI.getOperand(3).setIsDead(false);
MI.getOperand(4).setIsDead(false);
PrefixTransparent = false;
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvli-dead-vl-vtype-liveness.mir b/llvm/test/CodeGen/RISCV/rvv/vsetvli-dead-vl-vtype-liveness.mir
new file mode 100644
index 0000000000000..b8988ac10ec21
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/vsetvli-dead-vl-vtype-liveness.mir
@@ -0,0 +1,33 @@
+# REQUIRES: asserts
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -mattr=+v -run-pass=liveintervals,riscv-insert-vsetvli \
+# RUN: -precompute-phys-liveness -verify-machineinstrs -o - %s | FileCheck %s
+
+# Clearing the dead flags on an VSETVLI's VL and VTYPE defs must
+# update their physreg live ranges. Otherwise a previously-dead def
+# leaves a zero-length dead-def segment referencing the (now non-dead)
+# def slot. -precompute-phys-liveness forces the VL/VTYPE ranges to
+# exist so the stale segment is exercised.
+
+---
+name: bad_removal
+tracksRegLiveness: true
+isSSA: false
+body: |
+ bb.0:
+ liveins: $v8
+
+ ; CHECK-LABEL: name: bad_removal
+ ; CHECK: liveins: $v8
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[PseudoVSETIVLI:%[0-9]+]]:gpr = PseudoVSETIVLI 16, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: [[PseudoVMV_X_S:%[0-9]+]]:gpr = PseudoVMV_X_S renamable $v8, 6 /* e64 */, implicit $vtype
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PseudoVMV_X_S]], [[PseudoVSETIVLI]]
+ ; CHECK-NEXT: $x10 = COPY [[ADD]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ %1:gpr = PseudoVMV_X_S killed renamable $v8, 6 /* e64 */
+ %2:gpr = PseudoVSETIVLI 16, 216 /* e64, m1, ta, ma */, implicit-def dead $vl, implicit-def dead $vtype
+ %3:gpr = ADD %1, %2
+ $x10 = COPY %3
+ PseudoRET implicit $x10
+...
More information about the llvm-commits
mailing list