[AMDGPU] Fix DomTree preservation in SILowerControlFlow when nodes are removed (#176691)

I would think the "applyUpdates" API should also take care of deleting
the nodes from the analyses objects but this does not seem to be the
case. https://godbolt.org/z/38a7rfzjd shows an example where
SILowerControlFlow removes a basic block which is not removed in the
Post dominator tree.
This commit is contained in:
Vikram Hegde 2026-01-25 09:45:44 +05:30 committed by GitHub
parent cf9adf58fd
commit 402ee51532
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 70 additions and 0 deletions

View File

@ -744,6 +744,11 @@ bool SILowerControlFlow::removeMBBifRedundant(MachineBasicBlock &MBB) {
if (PDT)
PDT->applyUpdates(DTUpdates);
if (MDT && MDT->getNode(&MBB))
MDT->eraseNode(&MBB);
if (PDT && PDT->getNode(&MBB))
PDT->eraseNode(&MBB);
MBB.clear();
MBB.eraseFromParent();
if (FallThrough && !FallThrough->isLayoutSuccessor(Succ)) {

View File

@ -0,0 +1,65 @@
# RUN: llc -mcpu=gfx1201 -mtriple=amdgcn-amd-amdhsa -passes="require<machine-post-dom-tree>,require<machine-dom-tree>,si-lower-control-flow,print<machine-post-dom-tree>,print<machine-dom-tree>" -filetype=null %s 2>&1 | FileCheck %s
# CHECK: Inorder PostDominator Tree:
# CHECK-NEXT: [1] <<exit node>> {4294967295,4294967295} [0]
# CHECK-NEXT: [2] %bb.4 {4294967295,4294967295} [1]
# CHECK-NEXT: [3] %bb.0 {4294967295,4294967295} [2]
# CHECK-NEXT: [3] %bb.1 {4294967295,4294967295} [2]
# CHECK-NEXT: [3] %bb.2 {4294967295,4294967295} [2]
# CHECK: Inorder Dominator Tree:
# CHECK-NEXT: [1] %bb.0 {4294967295,4294967295} [0]
# CHECK-NEXT: [2] %bb.1 {4294967295,4294967295} [1]
# CHECK-NEXT: [3] %bb.2 {4294967295,4294967295} [2]
# CHECK-NEXT: [2] %bb.4 {4294967295,4294967295} [1]
---
name: preserve_dom_tree
body: |
bb.0.entry:
successors: %bb.1(0x40000000), %bb.4(0x40000000)
liveins: $vgpr0, $sgpr0_sgpr1, $ttmp9
%0:sreg_32 = COPY $ttmp9
%1:sgpr_64 = COPY killed $sgpr0_sgpr1
%2:vgpr_32 = COPY killed $vgpr0
%3:sgpr_128 = S_LOAD_DWORDX4_IMM %1, 0, 0
%4:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM killed %1, 28, 0
%5:sreg_64_xexec_xnull = REG_SEQUENCE %3.sub2, %subreg.sub0, %3.sub3, %subreg.sub1
%6:sreg_32 = S_AND_B32 killed %4, 65535, implicit-def dead $scc
%7:vreg_64 = REG_SEQUENCE killed %2(s32), %subreg.sub0, undef %8:vgpr_32, %subreg.sub1
%9:vreg_64, $sgpr_null = V_MAD_U64_U32_e64 killed %0, killed %6, killed %7, 0, implicit $exec
%10:vgpr_32 = GLOBAL_LOAD_UBYTE_SADDR killed %5, killed %9.sub0, 0, 0, implicit $exec
%11:vgpr_32 = V_AND_B32_e64 1, killed %10, implicit $exec
%12:sreg_32 = V_CMP_EQ_U32_e64 1, killed %11, implicit $exec
%13:sreg_32 = SI_IF killed %12, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
S_BRANCH %bb.1
bb.1:
successors: %bb.2(0x40000000), %bb.3(0x40000000)
%14:sreg_32 = COPY $exec_lo
%15:vgpr_32 = V_MBCNT_LO_U32_B32_e64 %14, 0, implicit $exec
%16:sreg_32 = V_CMP_EQ_U32_e64 0, killed %15, implicit $exec
%17:sreg_32 = SI_IF killed %16, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
S_BRANCH %bb.2
bb.2:
successors: %bb.3(0x80000000)
%18:sreg_32 = S_BCNT1_I32_B32 killed %14, implicit-def dead $scc
%19:vgpr_32 = V_CVT_F32_UBYTE0_e64 killed %18, 0, 0, implicit $exec
%20:vgpr_32 = nofpexcept V_MUL_F32_e64 0, 1092616192, 0, killed %19, 0, 0, implicit $mode, implicit $exec
%21:sreg_64_xexec_xnull = REG_SEQUENCE killed %3.sub0, %subreg.sub0, %3.sub1, %subreg.sub1
%22:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
GLOBAL_ATOMIC_ADD_F32_SADDR killed %22, killed %20, killed %21, 0, 0, implicit $exec
bb.3:
successors: %bb.4(0x80000000)
SI_END_CF killed %17, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
bb.4:
SI_END_CF killed %13, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
S_ENDPGM 0
...