summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp3
-rw-r--r--llvm/lib/CodeGen/MachineBasicBlock.cpp11
-rw-r--r--llvm/lib/CodeGen/MachineVerifier.cpp50
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp2
-rw-r--r--llvm/lib/IR/Verifier.cpp2
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);
OpenPOWER on IntegriCloud