diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MachineBasicBlock.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MachineVerifier.cpp | 50 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 2 |
5 files changed, 50 insertions, 18 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 1a17f633ae1..731c1cea0dc 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -6419,9 +6419,6 @@ bool LLParser::ParseCallBr(Instruction *&Inst, PerFunctionState &PFS) { /*IsCall=*/true)) return true; - if (isa<InlineAsm>(Callee) && !Ty->getReturnType()->isVoidTy()) - return Error(RetTypeLoc, "asm-goto outputs not supported"); - // Set up the Attribute for the function. SmallVector<Value *, 8> Args; SmallVector<AttributeSet, 8> ArgAttrs; diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp index f433c4b6c90..8928dc858d5 100644 --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -1109,6 +1109,17 @@ bool MachineBasicBlock::canSplitCriticalEdge( if (Succ->isEHPad()) return false; + // Splitting the critical edge to a callbr's indirect block isn't advised. + // Don't do it in this generic function. + if (Succ->hasAddressTaken()) + if (auto *cbr = dyn_cast<CallBrInst>(getBasicBlock()->getTerminator())) + if (auto *bb = Succ->getBasicBlock()) + if (cbr->getDefaultDest() != bb) + if (llvm::any_of(cbr->getIndirectDests(), [&](const BasicBlock *succ){ + return succ == bb; + })) + return false; + const MachineFunction *MF = getParent(); // Performance might be harmed on HW that implements branching using exec mask diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index ca57e51268e..cbafd387a62 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -633,17 +633,30 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { } // Count the number of landing pad successors. - SmallPtrSet<MachineBasicBlock*, 4> LandingPadSuccs; - for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(), - E = MBB->succ_end(); I != E; ++I) { - if ((*I)->isEHPad()) - LandingPadSuccs.insert(*I); - if (!FunctionBlocks.count(*I)) + SmallPtrSet<const MachineBasicBlock*, 4> LandingPadSuccs; + for (const auto *succ : MBB->successors()) { + if (succ->isEHPad()) + LandingPadSuccs.insert(succ); + if (!FunctionBlocks.count(succ)) report("MBB has successor that isn't part of the function.", MBB); - if (!MBBInfoMap[*I].Preds.count(MBB)) { + if (!MBBInfoMap[succ].Preds.count(MBB)) { report("Inconsistent CFG", MBB); errs() << "MBB is not in the predecessor list of the successor " - << printMBBReference(*(*I)) << ".\n"; + << printMBBReference(*succ) << ".\n"; + } + } + + // Count the number of INLINEASM_BR indirect pad successors. + SmallPtrSet<const MachineBasicBlock*, 4> IndirectPadSuccs; + for (const auto *succ : MBB->successors()) { + if (succ->isInlineAsmBrIndirectPad()) + IndirectPadSuccs.insert(succ); + if (!FunctionBlocks.count(succ)) + report("MBB has successor that isn't part of the function.", MBB); + if (!MBBInfoMap[succ].Preds.count(MBB)) { + report("Inconsistent CFG", MBB); + errs() << "MBB is not in the predecessor list of the successor " + << printMBBReference(*succ) << ".\n"; } } @@ -684,11 +697,13 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { // It's possible that the block legitimately ends with a noreturn // call or an unreachable, in which case it won't actually fall // out the bottom of the function. - } else if (MBB->succ_size() == LandingPadSuccs.size()) { + } else if (MBB->succ_size() == LandingPadSuccs.size() || + MBB->succ_size() == IndirectPadSuccs.size()) { // It's possible that the block legitimately ends with a noreturn // call or an unreachable, in which case it won't actually fall // out of the block. - } else if (MBB->succ_size() != 1+LandingPadSuccs.size()) { + } else if (MBB->succ_size() != 1 + LandingPadSuccs.size() && + MBB->succ_size() != 1 + IndirectPadSuccs.size()) { report("MBB exits via unconditional fall-through but doesn't have " "exactly one CFG successor!", MBB); } else if (!MBB->isSuccessor(&*MBBI)) { @@ -710,7 +725,10 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { // landingpad, accept it as valid control flow. if (MBB->succ_size() != 1+LandingPadSuccs.size() && (MBB->succ_size() != 1 || LandingPadSuccs.size() != 1 || - *MBB->succ_begin() != *LandingPadSuccs.begin())) { + *MBB->succ_begin() != *LandingPadSuccs.begin()) && + MBB->succ_size() != 1 + IndirectPadSuccs.size() && + (MBB->succ_size() != 1 || IndirectPadSuccs.size() != 1 || + *MBB->succ_begin() != *IndirectPadSuccs.begin())) { report("MBB exits via unconditional branch but doesn't have " "exactly one CFG successor!", MBB); } else if (!MBB->isSuccessor(TBB)) { @@ -840,8 +858,14 @@ void MachineVerifier::visitMachineBundleBefore(const MachineInstr *MI) { if (!FirstTerminator) FirstTerminator = MI; } else if (FirstTerminator && !MI->isDebugEntryValue()) { - report("Non-terminator instruction after the first terminator", MI); - errs() << "First terminator was:\t" << *FirstTerminator; + // An "INLINEASM_BR" will fallthrough to the successor block executing any + // "COPY" instructions that exist so that they can be assigned in the + // fallthrough block.. + if (FirstTerminator->getOpcode() != TargetOpcode::INLINEASM_BR || + MI->getOpcode() != TargetOpcode::COPY) { + report("Non-terminator instruction after the first terminator", MI); + errs() << "First terminator was:\t" << *FirstTerminator; + } } } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 00b05c5db2f..1505506dbf0 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2847,6 +2847,7 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) { assert(isa<InlineAsm>(I.getCalledValue()) && "Only know how to handle inlineasm callbr"); visitInlineAsm(&I); + CopyToExportRegsIfNeeded(&I); // Retrieve successors. MachineBasicBlock *Return = FuncInfo.MBBMap[I.getDefaultDest()]; @@ -2856,6 +2857,7 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) { for (unsigned i = 0, e = I.getNumIndirectDests(); i < e; ++i) { MachineBasicBlock *Target = FuncInfo.MBBMap[I.getIndirectDest(i)]; addSuccessorWithProb(CallBrMBB, Target); + Target->setIsInlineAsmBrIndirectPad(); } CallBrMBB->normalizeSuccProbs(); diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index e3a3d91b455..184a9a0569b 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -2501,8 +2501,6 @@ void Verifier::visitIndirectBrInst(IndirectBrInst &BI) { void Verifier::visitCallBrInst(CallBrInst &CBI) { Assert(CBI.isInlineAsm(), "Callbr is currently only used for asm-goto!", &CBI); - Assert(CBI.getType()->isVoidTy(), "Callbr return value is not supported!", - &CBI); for (unsigned i = 0, e = CBI.getNumSuccessors(); i != e; ++i) Assert(CBI.getSuccessor(i)->getType()->isLabelTy(), "Callbr successors must all have pointer type!", &CBI); |