Index: lib/Target/AMDGPU/SIInsertSkips.cpp =================================================================== --- lib/Target/AMDGPU/SIInsertSkips.cpp +++ lib/Target/AMDGPU/SIInsertSkips.cpp @@ -476,7 +476,7 @@ kill(MI); if (ExecBranchStack.empty()) { - if (skipIfDead(MI, *NextBB)) { + if (NextBB != BE && skipIfDead(MI, *NextBB)) { HaveSkipBlock = true; NextBB = std::next(BI); BE = MF.end(); Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -1632,7 +1632,34 @@ SmallVectorImpl &Cond, bool AllowModify) const { MachineBasicBlock::iterator I = MBB.getFirstTerminator(); - if (I == MBB.end()) + auto E = MBB.end(); + if (I == E) + return false; + + // Skip over the instructions that are artificially terminators for special + // exec management. + while (I != E && !I->isBranch() && !I->isReturn() && + I->getOpcode() != AMDGPU::SI_MASK_BRANCH) { + switch (I->getOpcode()) { + case AMDGPU::SI_MASK_BRANCH: + case AMDGPU::S_MOV_B64_term: + case AMDGPU::S_XOR_B64_term: + case AMDGPU::S_ANDN2_B64_term: + break; + case AMDGPU::SI_IF: + case AMDGPU::SI_ELSE: + case AMDGPU::SI_KILL_I1_TERMINATOR: + case AMDGPU::SI_KILL_F32_COND_IMM_TERMINATOR: + // FIXME: It's messy that these need to be considered here at all. + return true; + default: + llvm_unreachable("unexpected non-branch terminator inst"); + } + + ++I; + } + + if (I == E) return false; if (I->getOpcode() != AMDGPU::SI_MASK_BRANCH) Index: lib/Target/AMDGPU/SIInstructions.td =================================================================== --- lib/Target/AMDGPU/SIInstructions.td +++ lib/Target/AMDGPU/SIInstructions.td @@ -247,7 +247,7 @@ (outs), (ins SReg_64:$saved, brtarget:$target), [(AMDGPUloop i64:$saved, bb:$target)], 1, 1> { let Size = 8; - let isBranch = 0; + let isBranch = 1; let hasSideEffects = 1; } @@ -307,6 +307,7 @@ def SI_BR_UNDEF : SPseudoInstSI <(outs), (ins sopp_brtarget:$simm16)> { let isTerminator = 1; let usesCustomInserter = 1; + let isBranch = 1; } def SI_PS_LIVE : PseudoInstSI < Index: test/CodeGen/AMDGPU/verifier-pseudo-terminators.mir =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/verifier-pseudo-terminators.mir @@ -0,0 +1,23 @@ +# RUN: not llc -march=amdgcn -run-pass=verify %s 2>&1 | FileCheck %s +# Make sure that mismatched successors are caught when a _term +# instruction is used + +# CHECK: *** Bad machine code: MBB exits via unconditional branch but the CFG successor doesn't match the actual successor! *** + +--- +name: verifier_pseudo_terminators +body: | + bb.0: + successors: %bb.1 + + %0:sreg_64 = S_XOR_B64_term undef %1:sreg_64, undef %2:sreg_64, implicit-def $scc + $exec = S_MOV_B64_term %0 + S_BRANCH %bb.2 + + bb.1: + S_SETPC_B64_return undef $sgpr30_sgpr31 + + bb.2: + S_SETPC_B64_return undef $sgpr30_sgpr31 + +...