diff options
author | Bill Wendling <morbo@google.com> | 2020-01-07 12:53:44 -0800 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2020-01-07 13:40:26 -0800 |
commit | 52366088a8e42c2f1e96e8430b84b8b65ec3f7bc (patch) | |
tree | e8a2e167aa496592c70af28529ba313de1642575 /llvm/lib/CodeGen/MachineVerifier.cpp | |
parent | 6652cc0cf7c0373b8af12f9e5b1a7065577a78da (diff) | |
download | llvm-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.cpp | 50 |
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; + } } } |