The function that optimally inserts the exec mask restore operations by combining the blocks currently visits the lowered END_CF pseudos in the forward direction as it iterates the setvector in the order the entries are inserted in it. Due to the absence of BranchFolding at -O0, the irregularly placed BBs cause the forward traversal to incorrectly place two unconditional branches in certain BBs while combining them, especially when an intervening block later gets optimized away in subsequent iterations. It is avoided by reverse iterating the setvector. The blocks at the bottom of a function will get optimized first before processing those at the top. Fixes: SWDEV-315215 Reviewed By: rampitec Differential Revision: https://reviews.llvm.org/D116273
1027 lines
36 KiB
YAML
1027 lines
36 KiB
YAML
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
|
# RUN: llc -march=amdgcn -verify-machineinstrs -run-pass=si-lower-control-flow -amdgpu-remove-redundant-endcf %s -o - | FileCheck -check-prefix=GCN %s
|
|
|
|
# Make sure dbg_value doesn't change codeegn when collapsing end_cf
|
|
---
|
|
name: simple_nested_if_dbg_value
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: simple_nested_if_dbg_value
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: DBG_VALUE
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
successors: %bb.1, %bb.4
|
|
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2, %bb.3
|
|
|
|
%2:sreg_64 = SI_IF undef %3:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
|
|
bb.3:
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
DBG_VALUE
|
|
|
|
bb.4:
|
|
DBG_VALUE
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_ENDPGM 0
|
|
|
|
...
|
|
|
|
# Empty block separates the collapsable s_or_b64
|
|
---
|
|
name: simple_nested_if_empty_block_between
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: simple_nested_if_empty_block_between
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.5(0x40000000), %bb.1(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.5, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: successors: %bb.5(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.5:
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2, %bb.3
|
|
|
|
%2:sreg_64 = SI_IF undef %3:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
|
|
bb.3:
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.5:
|
|
|
|
bb.4:
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_ENDPGM 0
|
|
|
|
...
|
|
|
|
# Effectively empty block separates the collapsable s_or_b64
|
|
---
|
|
name: simple_nested_if_empty_block_dbg_between
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: simple_nested_if_empty_block_dbg_between
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.5(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.5, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: successors: %bb.5(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: DBG_VALUE
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.5:
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
successors: %bb.1, %bb.4
|
|
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2, %bb.3
|
|
|
|
%2:sreg_64 = SI_IF undef %3:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
|
|
bb.3:
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.5:
|
|
DBG_VALUE
|
|
|
|
bb.4:
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_ENDPGM 0
|
|
|
|
...
|
|
|
|
---
|
|
name: skip_salu_and_meta_insts_find_first
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: skip_salu_and_meta_insts_find_first
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: liveins: $vgpr0, $sgpr0_sgpr1
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.3, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.3(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.3:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[DEF:%[0-9]+]]:sgpr_32 = IMPLICIT_DEF
|
|
; GCN-NEXT: [[S_BREV_B32_:%[0-9]+]]:sgpr_32 = S_BREV_B32 [[DEF]]
|
|
; GCN-NEXT: KILL [[DEF]]
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
successors: %bb.1, %bb.4
|
|
liveins: $vgpr0, $sgpr0_sgpr1
|
|
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2, %bb.3
|
|
|
|
%2:sreg_64 = SI_IF undef %3:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
|
|
bb.3:
|
|
%4:sgpr_32 = IMPLICIT_DEF
|
|
%5:sgpr_32 = S_BREV_B32 %4
|
|
KILL %4
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.4:
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_ENDPGM 0
|
|
|
|
...
|
|
|
|
# Make sure SALU instructions, meta instructions, and SGPR->SGPR
|
|
# copies are skipped.
|
|
---
|
|
name: skip_salu_and_meta_insts_after
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: skip_salu_and_meta_insts_after
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.3, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.3(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.3:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[DEF:%[0-9]+]]:sgpr_32 = IMPLICIT_DEF
|
|
; GCN-NEXT: [[S_BREV_B32_:%[0-9]+]]:sgpr_32 = S_BREV_B32 [[DEF]]
|
|
; GCN-NEXT: KILL [[DEF]]
|
|
; GCN-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY [[S_BREV_B32_]]
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
successors: %bb.1, %bb.4
|
|
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2, %bb.3
|
|
|
|
%2:sreg_64 = SI_IF undef %3:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
|
|
bb.3:
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
%4:sgpr_32 = IMPLICIT_DEF
|
|
%5:sgpr_32 = S_BREV_B32 %4
|
|
KILL %4
|
|
%6:sgpr_32 = COPY %5
|
|
|
|
bb.4:
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_ENDPGM 0
|
|
|
|
...
|
|
|
|
# SALU instruction depends on exec through a normal operand.
|
|
---
|
|
name: salu_exec_dependency
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: salu_exec_dependency
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.3, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.3(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.3:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY1]], implicit-def $scc
|
|
; GCN-NEXT: [[S_BREV_B64_:%[0-9]+]]:sreg_64 = S_BREV_B64 $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
successors: %bb.1, %bb.4
|
|
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2, %bb.3
|
|
|
|
%2:sreg_64 = SI_IF undef %3:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
|
|
bb.3:
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
%4:sreg_64 = S_BREV_B64 $exec
|
|
|
|
bb.4:
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_ENDPGM 0
|
|
|
|
...
|
|
|
|
# Copy to / from VGPR should be assumed to read exec
|
|
---
|
|
name: copy_no_explicit_exec_dependency
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: copy_no_explicit_exec_dependency
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[DEF:%[0-9]+]]:vreg_128 = IMPLICIT_DEF
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %4:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.3, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.3(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.3:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY1]], implicit-def $scc
|
|
; GCN-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[DEF]].sub2
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
successors: %bb.1, %bb.4
|
|
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2, %bb.3
|
|
|
|
%2:vreg_128 = IMPLICIT_DEF
|
|
%3:sreg_64 = SI_IF undef %4:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
|
|
bb.3:
|
|
SI_END_CF %3:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
%5:vgpr_32 = COPY %2.sub2
|
|
|
|
bb.4:
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_ENDPGM 0
|
|
|
|
...
|
|
|
|
---
|
|
name: simple_nested_if_not_layout_successor
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: simple_nested_if_not_layout_successor
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.5(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.5, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.5(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.5:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: S_BRANCH %bb.4
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
successors: %bb.1, %bb.4
|
|
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2, %bb.3
|
|
|
|
%2:sreg_64 = SI_IF undef %3:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
|
|
bb.3:
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.5
|
|
|
|
bb.4:
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_ENDPGM 0
|
|
|
|
bb.5:
|
|
S_BRANCH %bb.4
|
|
|
|
...
|
|
|
|
# This should never happen, but check that we do not hang anyway
|
|
|
|
---
|
|
name: resursive_endcf
|
|
tracksRegLiveness: true
|
|
liveins:
|
|
- { reg: '$vgpr0', virtual-reg: '%0' }
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: resursive_endcf
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x80000000)
|
|
; GCN-NEXT: liveins: $vgpr0
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
|
|
; GCN-NEXT: [[V_CMP_LT_U32_e64_:%[0-9]+]]:sreg_64 = V_CMP_LT_U32_e64 1, [[COPY]], implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.1(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[V_CMP_LT_U32_e64_]], implicit-def $scc
|
|
; GCN-NEXT: S_BRANCH %bb.1
|
|
bb.0:
|
|
successors: %bb.1
|
|
liveins: $vgpr0
|
|
|
|
%0:vgpr_32 = COPY $vgpr0
|
|
%2:sreg_64 = V_CMP_LT_U32_e64 1, %0, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.1
|
|
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.1
|
|
|
|
...
|
|
|
|
# Both s_or_b64 shall be preserved since the outer SI_END_CF belongs to SI_ELSE.
|
|
|
|
---
|
|
name: simple_outer_if_else
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: simple_outer_if_else
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: [[S_XOR_B64_:%[0-9]+]]:sreg_64 = S_XOR_B64 [[S_AND_B64_]], [[COPY]], implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.2, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: S_BRANCH %bb.2
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.3(0x40000000), %bb.6(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[S_OR_SAVEEXEC_B64_:%[0-9]+]]:sreg_64 = S_OR_SAVEEXEC_B64 [[S_XOR_B64_]], implicit-def $exec, implicit-def $scc, implicit $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 $exec, [[S_OR_SAVEEXEC_B64_]], implicit-def $scc
|
|
; GCN-NEXT: $exec = S_XOR_B64_term $exec, [[S_AND_B64_1]], implicit-def $scc
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.6, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.3:
|
|
; GCN-NEXT: successors: %bb.3(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_2:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %4:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_2]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.3, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: successors: %bb.5(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.5:
|
|
; GCN-NEXT: successors: %bb.6(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY1]], implicit-def $scc
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.6:
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[S_AND_B64_1]], implicit-def $scc
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
successors: %bb.1, %bb.2
|
|
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.2, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2
|
|
S_BRANCH %bb.2
|
|
|
|
bb.2:
|
|
successors: %bb.3, %bb.6
|
|
%2:sreg_64 = SI_ELSE %0:sreg_64, %bb.6, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.3:
|
|
successors: %bb.3, %bb.4
|
|
|
|
%3:sreg_64 = SI_IF undef %4:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.4:
|
|
successors: %bb.5
|
|
|
|
bb.5:
|
|
successors: %bb.6
|
|
|
|
SI_END_CF %3:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.6:
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_ENDPGM 0
|
|
|
|
...
|
|
|
|
---
|
|
name: if_inside_loop
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: if_inside_loop
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.6(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: S_BRANCH %bb.6
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.3(0x40000000), %bb.2(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.3, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.6(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: S_BRANCH %bb.6
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.3:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: successors: %bb.5(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, %2, implicit-def $scc
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.5:
|
|
; GCN-NEXT: successors: %bb.6(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.6:
|
|
; GCN-NEXT: successors: %bb.4(0x40000000), %bb.0(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: [[S_XOR_B64_:%[0-9]+]]:sreg_64 = S_XOR_B64 [[S_AND_B64_1]], [[COPY1]], implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: S_BRANCH %bb.0
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
S_BRANCH %bb.6
|
|
|
|
bb.1:
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
S_BRANCH %bb.6
|
|
|
|
bb.3:
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.4:
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.5:
|
|
|
|
bb.6:
|
|
%2:sreg_64 = SI_IF undef %3:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.0
|
|
S_ENDPGM 0
|
|
|
|
...
|
|
|
|
---
|
|
# redundant MBB removal correctness test:
|
|
# we can keep bb.2 fallthrough to the new succ because after bb.3 gets removed
|
|
# new succ (bb.4) becomes bb.2's layout successor
|
|
name: removed_succ_fallthrough_but_layout_successor
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: removed_succ_fallthrough_but_layout_successor
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: successors: %bb.5(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.5:
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
successors: %bb.1, %bb.4
|
|
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2, %bb.3
|
|
|
|
%2:sreg_64 = SI_IF undef %3:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
|
|
bb.3:
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
|
|
bb.4:
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.5:
|
|
S_ENDPGM 0
|
|
|
|
...
|
|
|
|
---
|
|
# redundant MBB removal correctness test:
|
|
# If one of the remdundant block preds has a fallthrough path, but the only redundant block succ is not
|
|
# going to be a layout successor to that pred after redundant block removal, we should not rearrange
|
|
# blocks to keep pred's fallthrough path, if the succ has fallthrough path to one of it's succ too.
|
|
|
|
name: deleted_succ_fallthrough_not_layout_successor
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
; GCN-LABEL: name: deleted_succ_fallthrough_not_layout_successor
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.4, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.5(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.5, implicit $exec
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.5(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: S_BRANCH %bb.5
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.5:
|
|
; GCN-NEXT: successors: %bb.6(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.6:
|
|
; GCN-NEXT: successors: %bb.4(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: S_BRANCH %bb.4
|
|
bb.0:
|
|
successors: %bb.1, %bb.4
|
|
|
|
%0:sreg_64 = SI_IF undef %1:sreg_64, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.1:
|
|
successors: %bb.2, %bb.3
|
|
|
|
%2:sreg_64 = SI_IF undef %3:sreg_64, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.2:
|
|
|
|
bb.3:
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.5
|
|
|
|
bb.4:
|
|
S_ENDPGM 0
|
|
|
|
|
|
bb.5:
|
|
SI_END_CF %0:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
|
|
bb.6:
|
|
S_BRANCH %bb.4
|
|
...
|
|
|
|
---
|
|
# While collapsing inner endcf, certain blocks ended up getting two S_BRANCH instructions.
|
|
# It happens in the absence of BranchFolding (mostly at -O0) when the irregularly placed BBs are traversed
|
|
# in the forward direction and the intervening block between a predecessor and its successor gets optimized
|
|
# away in subsequent iterations, leaving 2 S_BRANCH instructions in the predecessor block.
|
|
# The issue was fixed by iterating the blocks from bottom-up to ensure all endcf pseudos at the bottom of the
|
|
# function are processed first.
|
|
# This test ensures there are no multiple S_BRANCH instructions inserted in any block.
|
|
|
|
name: no_multiple_unconditional_branches
|
|
tracksRegLiveness: true
|
|
body: |
|
|
; GCN-LABEL: name: no_multiple_unconditional_branches
|
|
; GCN: bb.0:
|
|
; GCN-NEXT: successors: %bb.1(0x40000000), %bb.14(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[DEF:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
|
|
; GCN-NEXT: [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_64 = V_CMP_EQ_U32_e64 0, killed [[DEF]], implicit $exec
|
|
; GCN-NEXT: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], [[V_CMP_EQ_U32_e64_]], implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.14, implicit $exec
|
|
; GCN-NEXT: S_BRANCH %bb.1
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.1:
|
|
; GCN-NEXT: successors: %bb.2(0x40000000), %bb.14(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[DEF1:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
|
|
; GCN-NEXT: [[V_CMP_EQ_U32_e64_1:%[0-9]+]]:sreg_64 = V_CMP_EQ_U32_e64 0, killed [[DEF1]], implicit $exec
|
|
; GCN-NEXT: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], killed [[V_CMP_EQ_U32_e64_1]], implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.14, implicit $exec
|
|
; GCN-NEXT: S_BRANCH %bb.2
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.2:
|
|
; GCN-NEXT: successors: %bb.3(0x40000000), %bb.7(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[DEF2:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
|
|
; GCN-NEXT: [[V_CMP_EQ_U32_e64_2:%[0-9]+]]:sreg_64 = V_CMP_EQ_U32_e64 0, killed [[DEF2]], implicit $exec
|
|
; GCN-NEXT: [[COPY2:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_2:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY2]], killed [[V_CMP_EQ_U32_e64_2]], implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_2]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.7, implicit $exec
|
|
; GCN-NEXT: S_BRANCH %bb.3
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.3:
|
|
; GCN-NEXT: successors: %bb.4(0x40000000), %bb.7(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[DEF3:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
|
|
; GCN-NEXT: [[V_CMP_EQ_U32_e64_3:%[0-9]+]]:sreg_64 = V_CMP_EQ_U32_e64 0, killed [[DEF3]], implicit $exec
|
|
; GCN-NEXT: [[COPY3:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_3:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY3]], killed [[V_CMP_EQ_U32_e64_3]], implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_3]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.7, implicit $exec
|
|
; GCN-NEXT: S_BRANCH %bb.4
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.4:
|
|
; GCN-NEXT: successors: %bb.7(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: S_BRANCH %bb.7
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.7:
|
|
; GCN-NEXT: successors: %bb.8(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY2]], implicit-def $scc
|
|
; GCN-NEXT: S_BRANCH %bb.8
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.8:
|
|
; GCN-NEXT: successors: %bb.9(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: S_BRANCH %bb.9
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.9:
|
|
; GCN-NEXT: successors: %bb.11(0x40000000), %bb.12(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[DEF4:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
|
|
; GCN-NEXT: [[V_CMP_EQ_U32_e64_4:%[0-9]+]]:sreg_64 = V_CMP_EQ_U32_e64 0, killed [[DEF4]], implicit $exec
|
|
; GCN-NEXT: [[COPY4:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
|
|
; GCN-NEXT: [[S_AND_B64_4:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY4]], killed [[V_CMP_EQ_U32_e64_4]], implicit-def dead $scc
|
|
; GCN-NEXT: [[S_XOR_B64_:%[0-9]+]]:sreg_64 = S_XOR_B64 [[S_AND_B64_4]], [[COPY4]], implicit-def dead $scc
|
|
; GCN-NEXT: $exec = S_MOV_B64_term killed [[S_AND_B64_4]]
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.12, implicit $exec
|
|
; GCN-NEXT: S_BRANCH %bb.11
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.10:
|
|
; GCN-NEXT: successors: %bb.14(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: S_BRANCH %bb.14
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.11:
|
|
; GCN-NEXT: successors: %bb.12(0x80000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: S_BRANCH %bb.12
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.12:
|
|
; GCN-NEXT: successors: %bb.10(0x40000000), %bb.14(0x40000000)
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: [[S_OR_SAVEEXEC_B64_:%[0-9]+]]:sreg_64 = S_OR_SAVEEXEC_B64 [[S_XOR_B64_]], implicit-def $exec, implicit-def $scc, implicit $exec
|
|
; GCN-NEXT: [[S_AND_B64_5:%[0-9]+]]:sreg_64 = S_AND_B64 $exec, [[S_OR_SAVEEXEC_B64_]], implicit-def $scc
|
|
; GCN-NEXT: $exec = S_XOR_B64_term $exec, [[S_AND_B64_5]], implicit-def $scc
|
|
; GCN-NEXT: S_CBRANCH_EXECZ %bb.14, implicit $exec
|
|
; GCN-NEXT: S_BRANCH %bb.10
|
|
; GCN-NEXT: {{ $}}
|
|
; GCN-NEXT: bb.14:
|
|
; GCN-NEXT: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
|
|
; GCN-NEXT: S_ENDPGM 0
|
|
bb.0:
|
|
successors: %bb.1, %bb.14
|
|
|
|
%0:vgpr_32 = IMPLICIT_DEF
|
|
%1:sreg_64 = V_CMP_EQ_U32_e64 0, killed %0:vgpr_32, implicit $exec
|
|
%2:sreg_64 = SI_IF %1:sreg_64, %bb.14, implicit-def $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.1
|
|
|
|
bb.1:
|
|
; predecessors: %bb.0
|
|
successors: %bb.2, %bb.6
|
|
|
|
%3:vgpr_32 = IMPLICIT_DEF
|
|
%4:sreg_64 = V_CMP_EQ_U32_e64 0, killed %3:vgpr_32, implicit $exec
|
|
%5:sreg_64 = SI_IF killed %4:sreg_64, %bb.6, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.2
|
|
|
|
bb.2:
|
|
; predecessors: %bb.1
|
|
successors: %bb.3, %bb.7
|
|
|
|
%6:vgpr_32 = IMPLICIT_DEF
|
|
%7:sreg_64 = V_CMP_EQ_U32_e64 0, killed %6:vgpr_32, implicit $exec
|
|
%8:sreg_64 = SI_IF killed %7:sreg_64, %bb.7, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.3
|
|
|
|
bb.3:
|
|
; predecessors: %bb.2
|
|
successors: %bb.4, %bb.5
|
|
|
|
%9:vgpr_32 = IMPLICIT_DEF
|
|
%10:sreg_64 = V_CMP_EQ_U32_e64 0, killed %9:vgpr_32, implicit $exec
|
|
%11:sreg_64 = SI_IF killed %10:sreg_64, %bb.5, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.4
|
|
|
|
bb.4:
|
|
; predecessors: %bb.3
|
|
successors: %bb.5
|
|
|
|
S_BRANCH %bb.5
|
|
|
|
bb.5:
|
|
; predecessors: %bb.3, %bb.4
|
|
successors: %bb.7
|
|
|
|
SI_END_CF %11:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.7
|
|
|
|
bb.6:
|
|
; predecessors: %bb.1, %bb.13
|
|
successors: %bb.14
|
|
|
|
SI_END_CF %5:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.14
|
|
|
|
bb.7:
|
|
; predecessors: %bb2, %bb.5
|
|
successors: %bb.8
|
|
|
|
SI_END_CF %8:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.8
|
|
|
|
bb.8:
|
|
; predecessors: %bb.7
|
|
successors: %bb.9
|
|
|
|
S_BRANCH %bb.9
|
|
|
|
bb.9:
|
|
; predecessors: %bb.8
|
|
successors: %bb.11, %bb.12
|
|
|
|
%12:vgpr_32 = IMPLICIT_DEF
|
|
%13:sreg_64 = V_CMP_EQ_U32_e64 0, killed %12:vgpr_32, implicit $exec
|
|
%14:sreg_64 = SI_IF killed %13:sreg_64, %bb.12, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.11
|
|
|
|
bb.10:
|
|
; predecessors: %bb.12
|
|
successors: %bb.13
|
|
|
|
S_BRANCH %bb.13
|
|
|
|
bb.11:
|
|
; predecessors: %bb.9
|
|
successors: %bb.12
|
|
|
|
S_BRANCH %bb.12
|
|
|
|
bb.12:
|
|
; predecessors: %bb.9, %bb.11
|
|
successors: %bb.10, %bb.13
|
|
|
|
%15:sreg_64 = SI_ELSE %14:sreg_64, %bb.13, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.10
|
|
|
|
bb.13:
|
|
; predecessors: %bb.10, %bb.12
|
|
successors: %bb.6
|
|
|
|
SI_END_CF %15:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_BRANCH %bb.6
|
|
|
|
bb.14:
|
|
; predecessors: %bb.0, %bb.6
|
|
|
|
SI_END_CF %2:sreg_64, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
|
|
S_ENDPGM 0
|
|
|
|
...
|