diff --git a/llvm/lib/Target/EVM/EVMAsmPrinter.cpp b/llvm/lib/Target/EVM/EVMAsmPrinter.cpp index 168dcf273ed7..d6ee075df3cc 100644 --- a/llvm/lib/Target/EVM/EVMAsmPrinter.cpp +++ b/llvm/lib/Target/EVM/EVMAsmPrinter.cpp @@ -42,6 +42,12 @@ class EVMAsmPrinter : public AsmPrinter { void emitInstruction(const MachineInstr *MI) override; void emitFunctionEntryLabel() override; + + /// Return true if the basic block has exactly one predecessor and the control + /// transfer mechanism between the predecessor and this block is a + /// fall-through. + bool isBlockOnlyReachableByFallthrough( + const MachineBasicBlock *MBB) const override; }; } // end of anonymous namespace @@ -70,12 +76,43 @@ void EVMAsmPrinter::emitFunctionEntryLabel() { void EVMAsmPrinter::emitInstruction(const MachineInstr *MI) { EVMMCInstLower MCInstLowering(OutContext, *this, VRegMapping, MF->getRegInfo()); - MCInst TmpInst; MCInstLowering.Lower(MI, TmpInst); EmitToStreamer(*OutStreamer, TmpInst); } +bool EVMAsmPrinter::isBlockOnlyReachableByFallthrough( + const MachineBasicBlock *MBB) const { + if (!AsmPrinter::isBlockOnlyReachableByFallthrough(MBB)) + return false; + + // Check terminators in more details. After the stackification we may have the + // following case: + + // PUSH_LABEL %bb.11 + // JUMPI %bb.11, %27:gpr.. + // PUSH_LABEL %bb.9 + // JUMP %bb.9 + // bb.11: + // + // The default implementation checks only the first terminator, JUMP %bb.9 + // and mistakenly concludes MBB is only reachable by fallthrough. + // There should be only one predecessor, otherwise + // AsmPrinter::isBlockOnlyReachableByFallthrough() should have returned false. + assert(MBB->pred_size() == 1); + MachineBasicBlock *Pred = *MBB->pred_begin(); + MachineBasicBlock::const_reverse_iterator I = Pred->rbegin(), + E = Pred->rend(); + while (I != E) { + if (I->isUnconditionalBranch() || I->isConditionalBranch()) + for (const auto &MO : I->explicit_uses()) + if (MO.isMBB() && MO.getMBB() == MBB) + return false; + ++I; + } + return true; +} + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeEVMAsmPrinter() { const RegisterAsmPrinter X(getTheEVMTarget()); } diff --git a/llvm/lib/Target/EVM/MCTargetDesc/EVMAsmBackend.cpp b/llvm/lib/Target/EVM/MCTargetDesc/EVMAsmBackend.cpp index e2d4cbfd10af..ac0dfd03ccce 100644 --- a/llvm/lib/Target/EVM/MCTargetDesc/EVMAsmBackend.cpp +++ b/llvm/lib/Target/EVM/MCTargetDesc/EVMAsmBackend.cpp @@ -138,7 +138,9 @@ bool EVMAsmBackend::evaluateTargetFixup(const MCAssembler &Asm, Value = Target.getConstant(); if (const MCSymbolRefExpr *A = Target.getSymA()) { const MCSymbol &Sym = A->getSymbol(); - assert(Sym.isDefined()); + if (!Sym.isDefined()) + report_fatal_error("Undef symbol: " + Sym.getName()); + Value += Layout.getSymbolOffset(Sym); return true; }