aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineVerifier.cpp
diff options
context:
space:
mode:
authorBill Wendling <morbo@google.com>2020-01-07 12:53:44 -0800
committerBill Wendling <isanbard@gmail.com>2020-01-07 13:40:26 -0800
commit52366088a8e42c2f1e96e8430b84b8b65ec3f7bc (patch)
treee8a2e167aa496592c70af28529ba313de1642575 /llvm/lib/CodeGen/MachineVerifier.cpp
parent6652cc0cf7c0373b8af12f9e5b1a7065577a78da (diff)
downloadllvm-52366088a8e42c2f1e96e8430b84b8b65ec3f7bc.zip
llvm-52366088a8e42c2f1e96e8430b84b8b65ec3f7bc.tar.gz
llvm-52366088a8e42c2f1e96e8430b84b8b65ec3f7bc.tar.bz2
Allow output constraints on "asm goto"
Summary: Remove the restrictions that preventing "asm goto" from returning non-void values. The values returned by "asm goto" are only valid on the "fallthrough" path. Reviewers: jyknight, nickdesaulniers, hfinkel Reviewed By: jyknight, nickdesaulniers Subscribers: rsmith, hiraditya, llvm-commits, cfe-commits, craig.topper, rnk Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D69876
Diffstat (limited to 'llvm/lib/CodeGen/MachineVerifier.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineVerifier.cpp50
1 files changed, 37 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index ca57e51..cbafd38 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;
+ }
}
}