Skip to content

[LiveVariables] Mark use as implicit-def if defined at instr #119446

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
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
37 changes: 4 additions & 33 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,27 +249,11 @@ 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));
}
LastPartialDef->addOperand(
MachineOperand::CreateReg(Reg, true /*IsDef*/, true /*IsImp*/));
}
} else if (LastDef && !PhysRegUse[Reg.id()] &&
!LastDef->findRegisterDefOperand(Reg, /*TRI=*/nullptr))
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 s0, 0
; CHECK-NEXT: s_mov_b32 s1, 0
; CHECK-NEXT: s_mov_b32 s2, 0
; 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: v_mov_b32_e32 v0, 0
; CHECK-NEXT: s_mov_b32 s3, 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