From eabb8dd01547c6fcccb7dcbba7a4a3b8ba67694c Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 16 Nov 2018 05:03:02 +0000 Subject: [PATCH] AMDGPU: Fix analyzeBranch failing with pseudoterminators If a block had one of the _term instructions used for gluing exec modifying instructions to the end of the block, analyzeBranch would fail, preventing the verifier from catching a broken successor list. llvm-svn: 347027 --- llvm/lib/Target/AMDGPU/SIInsertSkips.cpp | 2 +- llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 29 +++++++++++++++++++++- llvm/lib/Target/AMDGPU/SIInstructions.td | 3 ++- .../CodeGen/AMDGPU/verifier-pseudo-terminators.mir | 23 +++++++++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/verifier-pseudo-terminators.mir diff --git a/llvm/lib/Target/AMDGPU/SIInsertSkips.cpp b/llvm/lib/Target/AMDGPU/SIInsertSkips.cpp index f23fa02..ba21a5c 100644 --- a/llvm/lib/Target/AMDGPU/SIInsertSkips.cpp +++ b/llvm/lib/Target/AMDGPU/SIInsertSkips.cpp @@ -476,7 +476,7 @@ bool SIInsertSkips::runOnMachineFunction(MachineFunction &MF) { kill(MI); if (ExecBranchStack.empty()) { - if (skipIfDead(MI, *NextBB)) { + if (NextBB != BE && skipIfDead(MI, *NextBB)) { HaveSkipBlock = true; NextBB = std::next(BI); BE = MF.end(); diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp index eb04338..7aef9fd 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -1632,7 +1632,34 @@ bool SIInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 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) diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td index 11136e0..9b0edf4 100644 --- a/llvm/lib/Target/AMDGPU/SIInstructions.td +++ b/llvm/lib/Target/AMDGPU/SIInstructions.td @@ -247,7 +247,7 @@ def SI_LOOP : CFPseudoInstSI < (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_ILLEGAL_COPY : SPseudoInstSI < def SI_BR_UNDEF : SPseudoInstSI <(outs), (ins sopp_brtarget:$simm16)> { let isTerminator = 1; let usesCustomInserter = 1; + let isBranch = 1; } def SI_PS_LIVE : PseudoInstSI < diff --git a/llvm/test/CodeGen/AMDGPU/verifier-pseudo-terminators.mir b/llvm/test/CodeGen/AMDGPU/verifier-pseudo-terminators.mir new file mode 100644 index 0000000..d9e8aa7 --- /dev/null +++ b/llvm/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 + +... -- 2.7.4