[llvm-branch-commits] [llvm] RegisterPressure: Detect dead physreg defs from LiveIntervals with lane masks (PR #233215)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Oct 18 02:43:47 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

Extend the fix from #<!-- -->225079 to the lane mask tracking path used by
targets with subregister liveness. adjustLaneLiveness also needs to
force the physreg unit ranges to be computed to identify dead defs,
rather than taking the conservative default when they are not cached.

Without this, an overlapping physreg def missing a dead flag is
counted as a live def. Conservatively assuming it is live doesn't work
because PressureDiff disagrees with the tracker and fails the
EXPENSIVE_CHECKS consistency assert.

This avoids an ll asm test failing when LiveVariables removed; #<!-- -->233202
fixes the missing dead flag for that case. I had additional patches
which nearly eliminate all missing dead flags. Unless the verifier
enforces accurate dead flags, we still need to handle this edge case.

Co-authored-by: Claude Opus 5.5 <noreply@<!-- -->anthropic.com>

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


3 Files Affected:

- (modified) llvm/lib/CodeGen/RegisterPressure.cpp (+6-4) 
- (modified) llvm/test/CodeGen/AMDGPU/debug-value-scheduler-crash.mir (+1-1) 
- (added) llvm/test/CodeGen/AMDGPU/schedule-pressure-unflagged-dead-physreg-def.mir (+30) 


``````````diff
diff --git a/llvm/lib/CodeGen/RegisterPressure.cpp b/llvm/lib/CodeGen/RegisterPressure.cpp
index f6fac16b01b64..b935b4c29ea69 100644
--- a/llvm/lib/CodeGen/RegisterPressure.cpp
+++ b/llvm/lib/CodeGen/RegisterPressure.cpp
@@ -593,8 +593,9 @@ void RegisterOperands::adjustLaneLiveness(LiveIntervals &LIS,
                                           const MachineRegisterInfo &MRI,
                                           SlotIndex Pos) {
   for (auto *I = Defs.begin(); I != Defs.end(); /*empty*/) {
-    LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, /*TrackLaneMasks=*/true,
-                                           I->VRegOrUnit, Pos.getDeadSlot());
+    LaneBitmask LiveAfter =
+        getLiveLanesAt(LIS, MRI, /*TrackLaneMasks=*/true, I->VRegOrUnit,
+                       Pos.getDeadSlot(), /*ComputePhysRegs=*/true);
     I = adjustDef(*I, LiveAfter);
   }
   adjustUses(LIS, MRI, Pos.getBaseIndex());
@@ -605,8 +606,9 @@ void RegisterOperands::adjustLaneLiveness(LiveIntervals &LIS,
                                           MachineInstr &MI) {
   SlotIndex Pos = LIS.getInstructionIndex(MI);
   for (auto *I = Defs.begin(); I != Defs.end(); /*empty*/) {
-    LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, /*TrackLaneMasks=*/true,
-                                           I->VRegOrUnit, Pos.getDeadSlot());
+    LaneBitmask LiveAfter =
+        getLiveLanesAt(LIS, MRI, /*TrackLaneMasks=*/true, I->VRegOrUnit,
+                       Pos.getDeadSlot(), /*ComputePhysRegs=*/true);
     // If the def is all that is live after the instruction, then in case
     // of a subregister def we need a read-undef flag.
     VirtRegOrUnit VRegOrUnit = I->VRegOrUnit;
diff --git a/llvm/test/CodeGen/AMDGPU/debug-value-scheduler-crash.mir b/llvm/test/CodeGen/AMDGPU/debug-value-scheduler-crash.mir
index 1120d125a05e4..04d17bd456b25 100644
--- a/llvm/test/CodeGen/AMDGPU/debug-value-scheduler-crash.mir
+++ b/llvm/test/CodeGen/AMDGPU/debug-value-scheduler-crash.mir
@@ -71,7 +71,7 @@ body:             |
   ; CHECK-NEXT:   $vgpr0 = COPY [[V_MUL_F32_e32_1]]
   ; CHECK-NEXT:   $vgpr1 = COPY [[V_MUL_F32_e32_2]]
   ; CHECK-NEXT:   $vgpr2 = COPY [[V_MUL_F32_e32_3]]
-  ; CHECK-NEXT:   dead $sgpr30_sgpr31 = SI_CALL [[DEF13]], @foo, csr_amdgpu, implicit undef $sgpr0_sgpr1_sgpr2_sgpr3, implicit killed $sgpr4, implicit $vgpr0, implicit $vgpr1, implicit $vgpr2, implicit-def $vgpr0
+  ; CHECK-NEXT:   dead $sgpr30_sgpr31 = SI_CALL [[DEF13]], @foo, csr_amdgpu, implicit undef $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr4, implicit $vgpr0, implicit $vgpr1, implicit $vgpr2, implicit-def $vgpr0
   ; CHECK-NEXT:   [[V_ADD_F32_e32_1:%[0-9]+]]:vgpr_32 = nofpexcept V_ADD_F32_e32 [[V_MUL_F32_e32_]], [[DEF7]], implicit $mode, implicit $exec
   ; CHECK-NEXT:   [[V_ADD_F32_e32_1:%[0-9]+]]:vgpr_32 = nofpexcept V_MAC_F32_e32 [[DEF11]], [[DEF8]], [[V_ADD_F32_e32_1]], implicit $mode, implicit $exec
   ; CHECK-NEXT:   dead [[V_MAD_F32_e64_:%[0-9]+]]:vgpr_32 = nofpexcept V_MAD_F32_e64 0, [[V_ADD_F32_e32_1]], 0, [[DEF3]], 0, [[DEF]], 0, 0, implicit $mode, implicit $exec
diff --git a/llvm/test/CodeGen/AMDGPU/schedule-pressure-unflagged-dead-physreg-def.mir b/llvm/test/CodeGen/AMDGPU/schedule-pressure-unflagged-dead-physreg-def.mir
new file mode 100644
index 0000000000000..a1158c53302b8
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/schedule-pressure-unflagged-dead-physreg-def.mir
@@ -0,0 +1,30 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# REQUIRES: expensive_checks
+# RUN: llc -mtriple=amdgpu9.00-amd-amdhsa -passes=machine-scheduler %s -o - | FileCheck %s
+
+# The clobber is dead except for $vgpr1 but has no dead flag. Its dead
+# lanes must be found from LiveIntervals with lane mask tracking.
+
+---
+name:            unflagged_dead_clobber
+tracksRegLiveness: true
+machineFunctionInfo:
+  occupancy:       6
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name: unflagged_dead_clobber
+    ; CHECK: [[DEF:%[0-9]+]]:vreg_128 = IMPLICIT_DEF
+    ; CHECK-NEXT: [[DEF1:%[0-9]+]]:vreg_128 = IMPLICIT_DEF
+    ; CHECK-NEXT: INLINEASM &"; copy", sideeffect attdialect, regdef, implicit-def $vgpr1, reguse:VReg_128, [[DEF]], clobber, implicit-def early-clobber $vgpr0_vgpr1_vgpr2_vgpr3
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr1
+    ; CHECK-NEXT: $vgpr0_vgpr1_vgpr2_vgpr3 = COPY [[DEF1]]
+    ; CHECK-NEXT: INLINEASM &"; use", sideeffect attdialect, reguse:VGPR_32, [[COPY]], reguse, $vgpr0_vgpr1_vgpr2_vgpr3
+    ; CHECK-NEXT: SI_RETURN
+    %0:vreg_128 = IMPLICIT_DEF
+    %1:vreg_128 = IMPLICIT_DEF
+    INLINEASM &"; copy", sideeffect attdialect, regdef, implicit-def $vgpr1, reguse:VReg_128, %0, clobber, implicit-def early-clobber $vgpr0_vgpr1_vgpr2_vgpr3
+    %2:vgpr_32 = COPY killed $vgpr1
+    $vgpr0_vgpr1_vgpr2_vgpr3 = COPY %1
+    INLINEASM &"; use", sideeffect attdialect, reguse:VGPR_32, %2, reguse, $vgpr0_vgpr1_vgpr2_vgpr3
+    SI_RETURN
+...

``````````

</details>


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


More information about the llvm-branch-commits mailing list