llvm-project/llvm/test/CodeGen/AMDGPU/collapse-endcf.mir
alex-t 2480a31e5d [AMDGPU] SILowerControlFlow::optimizeEndCF should remove empty basic block
optimizeEndCF removes EXEC restoring instruction case this instruction is the only one except the branch to the single successor and that successor contains EXEC mask restoring instruction that was lowered from END_CF belonging to IF_ELSE.
As a result of such optimization we get the basic block with the only one instruction that is a branch to the single successor.
In case the control flow can reach such an empty block from S_CBRANCH_EXEZ/EXECNZ it might happen that spill/reload instructions that were inserted later by register allocator are placed under exec == 0 condition and never execute.
Removing empty block solves the problem.

This change require further work to re-implement LIS updates. Recently, LIS is always nullptr in this pass. To enable it we need another patch to fix many places across the codegen.

Reviewed By: rampitec

Differential Revision: https://reviews.llvm.org/D86634
2020-09-07 19:37:27 +03:00

585 lines
20 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: successors: %bb.1(0x40000000), %bb.4(0x40000000)
; GCN: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
; GCN: S_CBRANCH_EXECZ %bb.4, implicit $exec
; GCN: bb.1:
; GCN: successors: %bb.2(0x40000000), %bb.4(0x40000000)
; GCN: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
; GCN: S_CBRANCH_EXECZ %bb.4, implicit $exec
; GCN: bb.2:
; GCN: successors: %bb.4(0x80000000)
; GCN: bb.4:
; GCN: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
; GCN: DBG_VALUE
; GCN: 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: successors: %bb.5(0x40000000), %bb.1(0x40000000)
; GCN: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
; GCN: S_CBRANCH_EXECZ %bb.5, implicit $exec
; GCN: bb.1:
; GCN: successors: %bb.2(0x40000000), %bb.4(0x40000000)
; GCN: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
; GCN: S_CBRANCH_EXECZ %bb.4, implicit $exec
; GCN: bb.2:
; GCN: successors: %bb.4(0x80000000)
; GCN: bb.4:
; GCN: successors: %bb.5(0x80000000)
; GCN: bb.5:
; GCN: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
; GCN: 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: successors: %bb.1(0x40000000), %bb.5(0x40000000)
; GCN: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
; GCN: S_CBRANCH_EXECZ %bb.5, implicit $exec
; GCN: bb.1:
; GCN: successors: %bb.2(0x40000000), %bb.4(0x40000000)
; GCN: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
; GCN: S_CBRANCH_EXECZ %bb.4, implicit $exec
; GCN: bb.2:
; GCN: successors: %bb.4(0x80000000)
; GCN: bb.4:
; GCN: successors: %bb.5(0x80000000)
; GCN: DBG_VALUE
; GCN: bb.5:
; GCN: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
; GCN: 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: successors: %bb.1(0x40000000), %bb.4(0x40000000)
; GCN: liveins: $vgpr0, $sgpr0_sgpr1
; GCN: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
; GCN: S_CBRANCH_EXECZ %bb.4, implicit $exec
; GCN: bb.1:
; GCN: successors: %bb.2(0x40000000), %bb.3(0x40000000)
; GCN: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
; GCN: S_CBRANCH_EXECZ %bb.3, implicit $exec
; GCN: bb.2:
; GCN: successors: %bb.3(0x80000000)
; GCN: bb.3:
; GCN: successors: %bb.4(0x80000000)
; GCN: [[DEF:%[0-9]+]]:sgpr_32 = IMPLICIT_DEF
; GCN: [[S_BREV_B32_:%[0-9]+]]:sgpr_32 = S_BREV_B32 [[DEF]]
; GCN: KILL [[DEF]]
; GCN: bb.4:
; GCN: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
; GCN: 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: successors: %bb.1(0x40000000), %bb.4(0x40000000)
; GCN: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
; GCN: S_CBRANCH_EXECZ %bb.4, implicit $exec
; GCN: bb.1:
; GCN: successors: %bb.2(0x40000000), %bb.3(0x40000000)
; GCN: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
; GCN: S_CBRANCH_EXECZ %bb.3, implicit $exec
; GCN: bb.2:
; GCN: successors: %bb.3(0x80000000)
; GCN: bb.3:
; GCN: successors: %bb.4(0x80000000)
; GCN: [[DEF:%[0-9]+]]:sgpr_32 = IMPLICIT_DEF
; GCN: [[S_BREV_B32_:%[0-9]+]]:sgpr_32 = S_BREV_B32 [[DEF]]
; GCN: KILL [[DEF]]
; GCN: [[COPY2:%[0-9]+]]:sgpr_32 = COPY [[S_BREV_B32_]]
; GCN: bb.4:
; GCN: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
; GCN: 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: successors: %bb.1(0x40000000), %bb.4(0x40000000)
; GCN: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
; GCN: S_CBRANCH_EXECZ %bb.4, implicit $exec
; GCN: bb.1:
; GCN: successors: %bb.2(0x40000000), %bb.3(0x40000000)
; GCN: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
; GCN: S_CBRANCH_EXECZ %bb.3, implicit $exec
; GCN: bb.2:
; GCN: successors: %bb.3(0x80000000)
; GCN: bb.3:
; GCN: successors: %bb.4(0x80000000)
; GCN: $exec = S_OR_B64 $exec, [[COPY1]], implicit-def $scc
; GCN: [[S_BREV_B64_:%[0-9]+]]:sreg_64 = S_BREV_B64 $exec
; GCN: bb.4:
; GCN: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
; GCN: 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: successors: %bb.1(0x40000000), %bb.4(0x40000000)
; GCN: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
; GCN: S_CBRANCH_EXECZ %bb.4, implicit $exec
; GCN: bb.1:
; GCN: successors: %bb.2(0x40000000), %bb.3(0x40000000)
; GCN: [[DEF:%[0-9]+]]:vreg_128 = IMPLICIT_DEF
; GCN: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %4:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
; GCN: S_CBRANCH_EXECZ %bb.3, implicit $exec
; GCN: bb.2:
; GCN: successors: %bb.3(0x80000000)
; GCN: bb.3:
; GCN: successors: %bb.4(0x80000000)
; GCN: $exec = S_OR_B64 $exec, [[COPY1]], implicit-def $scc
; GCN: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[DEF]].sub2
; GCN: bb.4:
; GCN: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
; GCN: 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: successors: %bb.1(0x40000000), %bb.4(0x40000000)
; GCN: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
; GCN: S_CBRANCH_EXECZ %bb.4, implicit $exec
; GCN: bb.1:
; GCN: successors: %bb.2(0x40000000), %bb.5(0x40000000)
; GCN: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
; GCN: S_CBRANCH_EXECZ %bb.5, implicit $exec
; GCN: bb.2:
; GCN: successors: %bb.5(0x80000000)
; GCN: bb.5:
; GCN: successors: %bb.4(0x80000000)
; GCN: S_BRANCH %bb.4
; GCN: bb.4:
; GCN: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
; GCN: 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: successors: %bb.1(0x80000000)
; GCN: liveins: $vgpr0
; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
; GCN: [[V_CMP_LT_U32_e64_:%[0-9]+]]:sreg_64 = V_CMP_LT_U32_e64 1, [[COPY]], implicit $exec
; GCN: bb.1:
; GCN: successors: %bb.1(0x80000000)
; GCN: $exec = S_OR_B64 $exec, [[V_CMP_LT_U32_e64_]], implicit-def $scc
; GCN: 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: successors: %bb.1(0x40000000), %bb.2(0x40000000)
; GCN: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
; GCN: [[S_XOR_B64_:%[0-9]+]]:sreg_64 = S_XOR_B64 [[S_AND_B64_]], [[COPY]], implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
; GCN: S_CBRANCH_EXECZ %bb.2, implicit $exec
; GCN: bb.1:
; GCN: successors: %bb.2(0x80000000)
; GCN: S_BRANCH %bb.2
; GCN: bb.2:
; GCN: successors: %bb.3(0x40000000), %bb.6(0x40000000)
; GCN: [[S_OR_SAVEEXEC_B64_:%[0-9]+]]:sreg_64 = S_OR_SAVEEXEC_B64 [[S_XOR_B64_]], implicit-def $exec, implicit-def $scc, implicit $exec
; GCN: $exec = S_XOR_B64_term $exec, [[S_OR_SAVEEXEC_B64_]], implicit-def $scc
; GCN: S_CBRANCH_EXECZ %bb.6, implicit $exec
; GCN: bb.3:
; GCN: successors: %bb.3(0x40000000), %bb.4(0x40000000)
; GCN: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %4:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
; GCN: S_CBRANCH_EXECZ %bb.3, implicit $exec
; GCN: bb.4:
; GCN: successors: %bb.5(0x80000000)
; GCN: bb.5:
; GCN: successors: %bb.6(0x80000000)
; GCN: $exec = S_OR_B64 $exec, [[COPY1]], implicit-def $scc
; GCN: bb.6:
; GCN: $exec = S_OR_B64 $exec, [[S_OR_SAVEEXEC_B64_]], implicit-def $scc
; GCN: 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, 0, 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: successors: %bb.6(0x80000000)
; GCN: S_BRANCH %bb.6
; GCN: bb.1:
; GCN: successors: %bb.3(0x40000000), %bb.2(0x40000000)
; GCN: [[COPY:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY]], undef %1:sreg_64, implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_]]
; GCN: S_CBRANCH_EXECZ %bb.3, implicit $exec
; GCN: bb.2:
; GCN: successors: %bb.6(0x80000000)
; GCN: S_BRANCH %bb.6
; GCN: bb.3:
; GCN: successors: %bb.4(0x80000000)
; GCN: $exec = S_OR_B64 $exec, [[COPY]], implicit-def $scc
; GCN: bb.4:
; GCN: successors: %bb.5(0x80000000)
; GCN: $exec = S_OR_B64 $exec, %2, implicit-def $scc
; GCN: bb.5:
; GCN: successors: %bb.6(0x80000000)
; GCN: bb.6:
; GCN: successors: %bb.4(0x40000000), %bb.0(0x40000000)
; GCN: [[COPY1:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
; GCN: [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY1]], undef %3:sreg_64, implicit-def dead $scc
; GCN: [[S_XOR_B64_:%[0-9]+]]:sreg_64 = S_XOR_B64 [[S_AND_B64_1]], [[COPY1]], implicit-def dead $scc
; GCN: $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
; GCN: S_CBRANCH_EXECZ %bb.4, implicit $exec
; GCN: S_BRANCH %bb.0
; GCN: 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
...