Skip to content
Merged
6 changes: 2 additions & 4 deletions llvm/include/llvm/CodeGen/LiveVariables.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,8 @@ class LiveVariables {
MachineInstr *FindLastRefOrPartRef(Register Reg);

/// FindLastPartialDef - Return the last partial def of the specified
/// register. Also returns the sub-registers that're defined by the
/// instruction.
MachineInstr *FindLastPartialDef(Register Reg,
SmallSet<Register, 4> &PartDefRegs);
/// register.
MachineInstr *FindLastPartialDef(Register Reg);

/// analyzePHINodes - Gather information about the PHI nodes in here. In
/// particular, we want to map the variable information of a virtual
Expand Down
41 changes: 6 additions & 35 deletions llvm/lib/CodeGen/LiveVariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,7 @@ void LiveVariables::HandleVirtRegDef(Register Reg, MachineInstr &MI) {
}

/// FindLastPartialDef - Return the last partial def of the specified register.
/// Also returns the sub-registers that're defined by the instruction.
MachineInstr *
LiveVariables::FindLastPartialDef(Register Reg,
SmallSet<Register, 4> &PartDefRegs) {
Register LastDefReg = 0;
MachineInstr *LiveVariables::FindLastPartialDef(Register Reg) {
unsigned LastDefDist = 0;
MachineInstr *LastDef = nullptr;
for (MCPhysReg SubReg : TRI->subregs(Reg)) {
Expand All @@ -227,7 +223,6 @@ LiveVariables::FindLastPartialDef(Register Reg,
continue;
unsigned Dist = DistanceMap[Def];
if (Dist > LastDefDist) {
LastDefReg = SubReg;
LastDef = Def;
LastDefDist = Dist;
}
Expand All @@ -236,14 +231,6 @@ LiveVariables::FindLastPartialDef(Register Reg,
if (!LastDef)
return nullptr;

PartDefRegs.insert(LastDefReg);
for (MachineOperand &MO : LastDef->all_defs()) {
if (MO.getReg() == 0)
continue;
Register DefReg = MO.getReg();
if (TRI->isSubRegister(Reg, DefReg))
PartDefRegs.insert_range(TRI->subregs_inclusive(DefReg));
}
return LastDef;
}

Expand All @@ -262,28 +249,12 @@ void LiveVariables::HandlePhysRegUse(Register Reg, MachineInstr &MI) {
// ...
// = EAX
// All of the sub-registers must have been defined before the use of Reg!
SmallSet<Register, 4> PartDefRegs;
MachineInstr *LastPartialDef = FindLastPartialDef(Reg, PartDefRegs);
// MachineInstr *LastPartialDef = FindLastPartialDef(Reg);
// If LastPartialDef is NULL, it must be using a livein register.
if (LastPartialDef) {
LastPartialDef->addOperand(MachineOperand::CreateReg(Reg, true/*IsDef*/,
true/*IsImp*/));
PhysRegDef[Reg.id()] = LastPartialDef;
SmallSet<MCPhysReg, 8> Processed;
for (MCPhysReg SubReg : TRI->subregs(Reg)) {
if (Processed.count(SubReg))
continue;
if (PartDefRegs.count(SubReg))
continue;
// This part of Reg was defined before the last partial def. It's killed
// here.
LastPartialDef->addOperand(MachineOperand::CreateReg(SubReg,
false/*IsDef*/,
true/*IsImp*/));
PhysRegDef[SubReg] = LastPartialDef;
Processed.insert_range(TRI->subregs(SubReg));
}
}
// if (LastPartialDef) {
// LastPartialDef->addOperand(
// MachineOperand::CreateReg(Reg, true /*IsDef*/, true /*IsImp*/));
// }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented out code

Copy link
Contributor Author

@jofrn jofrn May 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, in /llvm/test/CodeGen/AArch64/ldrpre-ldr-merge.mir, we actually lose our implicit-def of $x2, so that's why the code has not been removed entirely.

-    ; CHECK-NEXT: renamable $w2 = LDRWui renamable $x1, 1, implicit-def $x2 :: (load (s32))
+    ; CHECK-NEXT: renamable $w2 = LDRWui renamable $x1, 1 :: (load (s32))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code is needed or not, leaving it commented out doesn't improve the situation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wanted to show you the situation that's occurring.

} else if (LastDef && !PhysRegUse[Reg.id()] &&
!LastDef->findRegisterDefOperand(Reg, /*TRI=*/nullptr))
// Last def defines the super register, add an implicit def of reg.
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/AArch64/ldrpre-ldr-merge.mir
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ body: |
; CHECK: liveins: $x0, $x1, $x2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: early-clobber renamable $x1, renamable $x0 = LDRSWpre renamable $x1, 40, implicit $w1, implicit $w1_hi :: (load (s32))
; CHECK-NEXT: renamable $w2 = LDRWui renamable $x1, 1, implicit-def $x2, implicit $w2_hi :: (load (s32))
; CHECK-NEXT: renamable $w2 = LDRWui renamable $x1, 1, implicit-def $x2 :: (load (s32))
; CHECK-NEXT: STPXi renamable $x0, renamable $x2, renamable $x1, 0 :: (store (s64))
; CHECK-NEXT: RET undef $lr
early-clobber renamable $x1, renamable $x0 = LDRSWpre killed renamable $x1, 40 :: (load (s32))
Expand Down
25 changes: 25 additions & 0 deletions llvm/test/CodeGen/AMDGPU/fncall-implicitdef.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx900 -O1 %s -o - | FileCheck %s

define amdgpu_ps <4 x float> @caller(ptr %ptr) {
; CHECK-LABEL: caller:
; CHECK: ; %bb.0:
; CHECK-NEXT: flat_load_dword v1, v[0:1]
; CHECK-NEXT: s_mov_b32 s5, fn@abs32@hi
; CHECK-NEXT: s_mov_b32 s4, fn@abs32@lo
; CHECK-NEXT: s_mov_b64 s[8:9], 0
; CHECK-NEXT: s_mov_b32 s0, 0
; CHECK-NEXT: s_mov_b32 s1, 0
; CHECK-NEXT: s_mov_b32 s2, 0
; CHECK-NEXT: s_mov_b32 s3, 0
; CHECK-NEXT: v_mov_b32_e32 v0, 0
; CHECK-NEXT: v_mov_b32_e32 v2, 0
; CHECK-NEXT: s_mov_b32 s32, 0
; CHECK-NEXT: s_swappc_b64 s[30:31], s[4:5]
; CHECK-NEXT: ; return to shader part epilog
%L = load i32, ptr %ptr, align 4
%R = call <4 x float> @fn(<4 x i32> zeroinitializer, i32 0, i32 %L, i32 0)
ret <4 x float> %R
}

declare hidden <4 x float> @fn(<4 x i32> inreg, i32, i32, i32)
91 changes: 91 additions & 0 deletions llvm/test/CodeGen/AMDGPU/livevars-implicitdef.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
# RUN: llc -mtriple=amdgcn --run-pass=livevars -o - %s | FileCheck %s
---
# Check that super register is defined for an sgpr copy.
name: sgpr_copy
tracksRegLiveness: true
body: |
bb.0:

; CHECK-LABEL: name: sgpr_copy
; CHECK: %sval:sreg_32 = S_MOV_B32 0
; CHECK-NEXT: $sgpr0 = COPY %sval
; CHECK-NEXT: $sgpr1 = COPY %sval
; CHECK-NEXT: $sgpr2 = COPY %sval
; CHECK-NEXT: $sgpr3 = COPY killed %sval
; CHECK-NEXT: SI_RETURN implicit killed $sgpr0_sgpr1_sgpr2_sgpr3
%sval:sreg_32 = S_MOV_B32 0

$sgpr0 = COPY %sval
$sgpr1 = COPY %sval
$sgpr2 = COPY %sval
$sgpr3 = COPY %sval
SI_RETURN implicit $sgpr0_sgpr1_sgpr2_sgpr3

...
---
# Check that super register is defined for a vgpr vector copy.
name: vgpr_copy
tracksRegLiveness: true
body: |
bb.0:

; CHECK-LABEL: name: vgpr_copy
; CHECK: %vval:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
; CHECK-NEXT: $vgpr0 = COPY %vval
; CHECK-NEXT: $vgpr1 = COPY %vval
; CHECK-NEXT: $vgpr2 = COPY %vval
; CHECK-NEXT: $vgpr3 = COPY killed %vval
; CHECK-NEXT: dead [[COPY:%[0-9]+]]:vgpr_32 = COPY killed $vgpr0_vgpr1_vgpr2_vgpr3
%vval:vgpr_32 = V_MOV_B32_e32 0, implicit $exec

$vgpr0 = COPY %vval
$vgpr1 = COPY %vval
$vgpr2 = COPY %vval
$vgpr3 = COPY %vval
%0:vgpr_32 = COPY $vgpr0_vgpr1_vgpr2_vgpr3

...
---
# Check that super register is defined when there is a hole.
name: sgpr_copy_hole
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: name: sgpr_copy_hole
; CHECK: %sval:sreg_32 = S_MOV_B32 0
; CHECK-NEXT: $sgpr0 = COPY %sval
; CHECK-NEXT: $sgpr2 = COPY %sval
; CHECK-NEXT: $sgpr3 = COPY killed %sval
; CHECK-NEXT: SI_RETURN implicit killed $sgpr0_sgpr1_sgpr2_sgpr3
%sval:sreg_32 = S_MOV_B32 0

$sgpr0 = COPY %sval
$sgpr2 = COPY %sval
$sgpr3 = COPY %sval
SI_RETURN implicit $sgpr0_sgpr1_sgpr2_sgpr3

...
---
# Check that super register is defined when a pair interrupts the sequence.
name: vgpr_copy_pair
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: name: vgpr_copy_pair
; CHECK: %vval:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
; CHECK-NEXT: $vgpr0 = COPY %vval
; CHECK-NEXT: $vgpr1 = COPY %vval
; CHECK-NEXT: $vgpr2 = COPY %vval
; CHECK-NEXT: $vgpr3 = COPY killed %vval
; CHECK-NEXT: dead [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr1_vgpr2
; CHECK-NEXT: dead [[COPY1:%[0-9]+]]:vgpr_32 = COPY killed $vgpr0_vgpr1_vgpr2_vgpr3
%vval:vgpr_32 = V_MOV_B32_e32 0, implicit $exec

$vgpr0 = COPY %vval
$vgpr1 = COPY %vval
$vgpr2 = COPY %vval
$vgpr3 = COPY %vval
%0:vgpr_32 = COPY $vgpr1_vgpr2
%1:vgpr_32 = COPY $vgpr0_vgpr1_vgpr2_vgpr3
...
Loading