This is an archive of the discontinued LLVM Phabricator instance.

[AMDGPU] Handle isUndef flag in LiveVariables::recomputeForSingleDefVirtReg
ClosedPublic

Authored by vpykhtin on Aug 17 2023, 3:31 AM.

Details

Summary

A register's use with isUndef flags shouldn't be considered as a point where the register is live. LiveVariables::runOnInstr ignores such uses.

This was found when I tried to replace calls to

SIOptimizeVGPRLiveRange::updateLiveRangeInThenRegion
SIOptimizeVGPRLiveRange::updateLiveRangeInElseRegion

with LiveVariables::recomputeForSingleDefVirtReg.

In the testcase below %2 use is undef in the last REG_SEQUENCE.

CodeGen/AMDGPU/si-opt-vgpr-liverange-bug-deadlanes.mir failed:

# After SI Optimize VGPR LiveRange
# Machine code for function _amdgpu_ps_main: IsSSA, TracksLiveness
Function Live Ins: $vgpr0 in %0

bb.0:
  successors: %bb.1(0x40000000), %bb.2(0x40000000); %bb.1(50.00%), %bb.2(50.00%)
  liveins: $vgpr0
  %0:vgpr_32 = COPY killed $vgpr0
  %1:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
  %2:vgpr_32 = BUFFER_LOAD_DWORD_OFFEN killed %0:vgpr_32, undef %5:sgpr_128, 0, 0, 0, 0, implicit $exec :: (dereferenceable invariant load (s32))
  %3:sreg_64 = V_CMP_NE_U32_e64 0, %2:vgpr_32, implicit $exec
  %7:sreg_64 = SI_IF killed %3:sreg_64, %bb.2, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
  S_BRANCH %bb.1

bb.1:
; predecessors: %bb.0
  successors: %bb.2(0x80000000); %bb.2(100.00%)

  %8:vreg_128 = REG_SEQUENCE killed %1:vgpr_32, %subreg.sub0, %1:vgpr_32, %subreg.sub1, %1:vgpr_32, %subreg.sub2, undef %4.sub3:vreg_128, %subreg.sub3

bb.2:
; predecessors: %bb.0, %bb.1
  successors: %bb.3(0x40000000), %bb.4(0x40000000); %bb.3(50.00%), %bb.4(50.00%)

  %9:vreg_128 = PHI undef %10:vreg_128, %bb.0, %8:vreg_128, %bb.1
  %14:vgpr_32 = PHI %2:vgpr_32, %bb.0, undef %15:vgpr_32, %bb.1
  %11:sreg_64 = SI_ELSE killed %7:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
  S_BRANCH %bb.3

bb.3:
; predecessors: %bb.2
  successors: %bb.4(0x80000000); %bb.4(100.00%)

  %12:vreg_128 = REG_SEQUENCE killed %14:vgpr_32, %subreg.sub0, %14:vgpr_32, %subreg.sub1, %14:vgpr_32, %subreg.sub2, undef %6:vgpr_32, %subreg.sub3

bb.4:
; predecessors: %bb.2, %bb.3

  %13:vreg_128 = PHI %9:vreg_128, %bb.2, %12:vreg_128, %bb.3
  SI_END_CF killed %11:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
  dead %4:vreg_128 = REG_SEQUENCE killed %13.sub2:vreg_128, %subreg.sub0, %13.sub2:vreg_128, %subreg.sub1, %13.sub2:vreg_128, %subreg.sub2, undef %2:vgpr_32, %subreg.sub3
  S_ENDPGM 0

# End machine code for function _amdgpu_ps_main.

*** Bad machine code: LiveVariables: Block should not be in AliveBlocks ***
- function:    _amdgpu_ps_main
- basic block: %bb.1  (0x55e17ebd7100)
Virtual register %2 is not needed live through the block.

*** Bad machine code: LiveVariables: Block should not be in AliveBlocks ***
- function:    _amdgpu_ps_main
- basic block: %bb.2  (0x55e17ebd7200)
Virtual register %2 is not needed live through the block.

*** Bad machine code: LiveVariables: Block should not be in AliveBlocks ***
- function:    _amdgpu_ps_main
- basic block: %bb.3  (0x55e17ebd7300)
Virtual register %2 is not needed live through the block.

Diff Detail

Event Timeline

vpykhtin created this revision.Aug 17 2023, 3:31 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 17 2023, 3:31 AM
vpykhtin requested review of this revision.Aug 17 2023, 3:31 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 17 2023, 3:31 AM
vpykhtin retitled this revision from [AMDGPU] Handle inUndef flag in LiveVariables::recomputeForSingleDefVirtReg to [AMDGPU] Handle isUndef flag in LiveVariables::recomputeForSingleDefVirtReg.Aug 17 2023, 3:33 AM
vpykhtin edited the summary of this revision. (Show Details)
ruiling accepted this revision.Aug 21 2023, 6:53 PM

LGTM

This revision is now accepted and ready to land.Aug 21 2023, 6:53 PM
foad added a comment.Sep 5 2023, 2:00 AM

LGTM but can you come up with a test case?

vpykhtin updated this revision to Diff 555924.Sep 5 2023, 1:16 PM
  • Rebased.
  • Added tests.

Tests have revealed another bug:

MachineInstr::readsRegister doesn't check isUndef flag, I've replaced it with readsWritesVirtualRegister(Reg).

foad added inline comments.Sep 7 2023, 3:39 AM
llvm/lib/CodeGen/LiveVariables.cpp
728

This is just readsVirtualRegister

vpykhtin updated this revision to Diff 556150.Sep 7 2023, 7:33 AM

Replaced MI.readsWritesVirtualRegister(Reg).first with readsVirtualRegister.

vpykhtin marked an inline comment as done.Sep 7 2023, 7:34 AM
vpykhtin added inline comments.
llvm/lib/CodeGen/LiveVariables.cpp
728

Thanks!

foad accepted this revision.Sep 11 2023, 6:35 AM
foad added inline comments.
llvm/unittests/MI/LiveIntervalTest.cpp
1 ↗(On Diff #556150)

I don't understand this message - does clang-format want you to change something?

This revision was automatically updated to reflect the committed changes.
vpykhtin marked an inline comment as done.
vpykhtin added inline comments.Sep 12 2023, 2:02 AM
llvm/unittests/MI/LiveIntervalTest.cpp
1 ↗(On Diff #556150)

It wants me to format most of the source, I didn't include that formatting as would create a lot of unrelated changes.

Maybe it worth to format the entire source after the commit.

foad added inline comments.Sep 12 2023, 2:08 AM
llvm/unittests/MI/LiveIntervalTest.cpp
1 ↗(On Diff #556150)

It wants me to format most of the source

Generally you should run "git clang-format @^" to reformat only the parts that your patch has modified.

vpykhtin added inline comments.Sep 12 2023, 2:14 AM
llvm/unittests/MI/LiveIntervalTest.cpp
1 ↗(On Diff #556150)

Thank you, I didn't know that. I've relied on the formatting of arc diff.