summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/CodeGen/MachineFunction.h22
-rw-r--r--llvm/include/llvm/IR/IntrinsicsWebAssembly.td3
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp3
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt1
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp10
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/EHStreamer.h11
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/WasmException.cpp81
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/WasmException.h42
-rw-r--r--llvm/lib/CodeGen/MachineFunction.cpp45
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp10
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp83
-rw-r--r--llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp4
-rw-r--r--llvm/lib/CodeGen/WasmEHPrepare.cpp2
-rw-r--r--llvm/lib/MC/MCObjectFileInfo.cpp6
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp4
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp15
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td2
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp7
-rw-r--r--llvm/test/CodeGen/WebAssembly/eh-lsda.ll239
-rw-r--r--llvm/test/CodeGen/WebAssembly/wasmehprepare.ll6
20 files changed, 529 insertions, 67 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index 7471b314846..bc81e485a80 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -316,6 +316,9 @@ class MachineFunction {
/// Map a landing pad's EH symbol to the call site indexes.
DenseMap<MCSymbol*, SmallVector<unsigned, 4>> LPadToCallSiteMap;
+ /// Map a landing pad to its index.
+ DenseMap<const MachineBasicBlock *, unsigned> WasmLPadToIndexMap;
+
/// Map of invoke call site index values to associated begin EH_LABEL.
DenseMap<MCSymbol*, unsigned> CallSiteMap;
@@ -810,7 +813,8 @@ public:
LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);
/// Remap landing pad labels and remove any deleted landing pads.
- void tidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap = nullptr);
+ void tidyLandingPads(DenseMap<MCSymbol *, uintptr_t> *LPMap = nullptr,
+ bool TidyIfNoBeginLabels = true);
/// Return a reference to the landing pad info for the current function.
const std::vector<LandingPadInfo> &getLandingPads() const {
@@ -853,6 +857,22 @@ public:
/// Map the landing pad's EH symbol to the call site indexes.
void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);
+ /// Map the landing pad to its index. Used for Wasm exception handling.
+ void setWasmLandingPadIndex(const MachineBasicBlock *LPad, unsigned Index) {
+ WasmLPadToIndexMap[LPad] = Index;
+ }
+
+ /// Returns true if the landing pad has an associate index in wasm EH.
+ bool hasWasmLandingPadIndex(const MachineBasicBlock *LPad) const {
+ return WasmLPadToIndexMap.count(LPad);
+ }
+
+ /// Get the index in wasm EH for a given landing pad.
+ unsigned getWasmLandingPadIndex(const MachineBasicBlock *LPad) const {
+ assert(hasWasmLandingPadIndex(LPad));
+ return WasmLPadToIndexMap.lookup(LPad);
+ }
+
/// Get the call site indexes for a landing pad EH symbol.
SmallVectorImpl<unsigned> &getCallSiteLandingPad(MCSymbol *Sym) {
assert(hasCallSiteLandingPad(Sym) &&
diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
index 897d3525b4c..ff5964c3aab 100644
--- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -71,7 +71,8 @@ def int_wasm_catch : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty],
// WebAssembly EH must maintain the landingpads in the order assigned to them
// by WasmEHPrepare pass to generate landingpad table in EHStreamer. This is
// used in order to give them the indices in WasmEHPrepare.
-def int_wasm_landingpad_index: Intrinsic<[], [llvm_i32_ty], [IntrNoMem]>;
+def int_wasm_landingpad_index: Intrinsic<[], [llvm_token_ty, llvm_i32_ty],
+ [IntrNoMem]>;
// Returns LSDA address of the current function.
def int_wasm_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 63c5b262edc..526f7ce3083 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -16,6 +16,7 @@
#include "CodeViewDebug.h"
#include "DwarfDebug.h"
#include "DwarfException.h"
+#include "WasmException.h"
#include "WinCFGuard.h"
#include "WinException.h"
#include "llvm/ADT/APFloat.h"
@@ -356,7 +357,7 @@ bool AsmPrinter::doInitialization(Module &M) {
}
break;
case ExceptionHandling::Wasm:
- // TODO to prevent warning
+ ES = new WasmException(this);
break;
}
if (ES)
diff --git a/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt b/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
index 6cba4a0d4b8..3fb088ab6f0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
+++ b/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
@@ -23,6 +23,7 @@ add_llvm_library(LLVMAsmPrinter
WinCFGuard.cpp
WinException.cpp
CodeViewDebug.cpp
+ WasmException.cpp
DEPENDS
intrinsics_gen
diff --git a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
index be04b9a6e8c..7599121de2b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
@@ -345,7 +345,9 @@ computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
/// unwound and handling continues.
/// 3. Type ID table contains references to all the C++ typeinfo for all
/// catches in the function. This tables is reverse indexed base 1.
-void EHStreamer::emitExceptionTable() {
+///
+/// Returns the starting symbol of an exception table.
+MCSymbol *EHStreamer::emitExceptionTable() {
const MachineFunction *MF = Asm->MF;
const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
const std::vector<unsigned> &FilterIds = MF->getFilterIds();
@@ -375,6 +377,7 @@ void EHStreamer::emitExceptionTable() {
computeCallSiteTable(CallSites, LandingPads, FirstActions);
bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
+ bool IsWasm = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Wasm;
unsigned CallSiteEncoding =
IsSJLJ ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_uleb128;
bool HaveTTData = !TypeInfos.empty() || !FilterIds.empty();
@@ -457,8 +460,8 @@ void EHStreamer::emitExceptionTable() {
Asm->EmitLabelDifferenceAsULEB128(CstEndLabel, CstBeginLabel);
Asm->OutStreamer->EmitLabel(CstBeginLabel);
- // SjLj Exception handling
- if (IsSJLJ) {
+ // SjLj / Wasm Exception handling
+ if (IsSJLJ || IsWasm) {
unsigned idx = 0;
for (SmallVectorImpl<CallSiteEntry>::const_iterator
I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) {
@@ -604,6 +607,7 @@ void EHStreamer::emitExceptionTable() {
}
Asm->EmitAlignment(2);
+ return GCCETSym;
}
void EHStreamer::emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h
index b89421a1e06..e3a6f8e9d58 100644
--- a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h
+++ b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h
@@ -85,9 +85,10 @@ protected:
/// zero for the landing pad and the action. Calls marked 'nounwind' have
/// no entry and must not be contained in the try-range of any entry - they
/// form gaps in the table. Entries must be ordered by try-range address.
- void computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
- const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
- const SmallVectorImpl<unsigned> &FirstActions);
+ virtual void computeCallSiteTable(
+ SmallVectorImpl<CallSiteEntry> &CallSites,
+ const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
+ const SmallVectorImpl<unsigned> &FirstActions);
/// Emit landing pads and actions.
///
@@ -108,7 +109,9 @@ protected:
/// found the frame is unwound and handling continues.
/// 3. Type id table contains references to all the C++ typeinfo for all
/// catches in the function. This tables is reversed indexed base 1.
- void emitExceptionTable();
+ ///
+ /// Returns the starting symbol of an exception table.
+ MCSymbol *emitExceptionTable();
virtual void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel);
diff --git a/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp b/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
new file mode 100644
index 00000000000..46745d08c9f
--- /dev/null
+++ b/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
@@ -0,0 +1,81 @@
+//===-- CodeGen/AsmPrinter/WasmException.cpp - Wasm Exception Impl --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for writing WebAssembly exception info into asm
+// files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "WasmException.h"
+#include "llvm/MC/MCStreamer.h"
+using namespace llvm;
+
+void WasmException::markFunctionEnd() {
+ // Get rid of any dead landing pads.
+ if (!Asm->MF->getLandingPads().empty()) {
+ auto *NonConstMF = const_cast<MachineFunction *>(Asm->MF);
+ // Wasm does not set BeginLabel and EndLabel information for landing pads,
+ // so we should set the second argument false.
+ NonConstMF->tidyLandingPads(nullptr, /* TidyIfNoBeginLabels */ false);
+ }
+}
+
+void WasmException::endFunction(const MachineFunction *MF) {
+ bool ShouldEmitExceptionTable = false;
+ for (const LandingPadInfo &Info : MF->getLandingPads()) {
+ if (MF->hasWasmLandingPadIndex(Info.LandingPadBlock)) {
+ ShouldEmitExceptionTable = true;
+ break;
+ }
+ }
+ if (!ShouldEmitExceptionTable)
+ return;
+ MCSymbol *LSDALabel = emitExceptionTable();
+ assert(LSDALabel && ".GCC_exception_table has not been emitted!");
+
+ // Wasm requires every data section symbol to have a .size set. So we emit an
+ // end marker and set the size as the difference between the start end the end
+ // marker.
+ MCSymbol *LSDAEndLabel = Asm->createTempSymbol("GCC_except_table_end");
+ Asm->OutStreamer->EmitLabel(LSDAEndLabel);
+ MCContext &OutContext = Asm->OutStreamer->getContext();
+ const MCExpr *SizeExp = MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(LSDAEndLabel, OutContext),
+ MCSymbolRefExpr::create(LSDALabel, OutContext), OutContext);
+ Asm->OutStreamer->emitELFSize(LSDALabel, SizeExp);
+}
+
+// Compute the call-site table for wasm EH. Even though we use the same function
+// name to share the common routines, a call site entry in the table corresponds
+// to not a call site for possibly-throwing functions but a landing pad. In wasm
+// EH the VM is responsible for stack unwinding. After an exception occurs and
+// the stack is unwound, the control flow is transferred to wasm 'catch'
+// instruction by the VM, after which the personality function is called from
+// the compiler-generated code. Refer to WasmEHPrepare pass for more
+// information.
+void WasmException::computeCallSiteTable(
+ SmallVectorImpl<CallSiteEntry> &CallSites,
+ const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
+ const SmallVectorImpl<unsigned> &FirstActions) {
+ MachineFunction &MF = *Asm->MF;
+ for (unsigned I = 0, N = LandingPads.size(); I < N; ++I) {
+ const LandingPadInfo *Info = LandingPads[I];
+ MachineBasicBlock *LPad = Info->LandingPadBlock;
+ // We don't emit LSDA for single catch (...).
+ if (!MF.hasWasmLandingPadIndex(LPad))
+ continue;
+ // Wasm EH must maintain the EH pads in the order assigned to them by the
+ // WasmEHPrepare pass.
+ unsigned LPadIndex = MF.getWasmLandingPadIndex(LPad);
+ CallSiteEntry Site = {nullptr, nullptr, Info, FirstActions[I]};
+ if (CallSites.size() < LPadIndex + 1)
+ CallSites.resize(LPadIndex + 1);
+ CallSites[LPadIndex] = Site;
+ }
+}
diff --git a/llvm/lib/CodeGen/AsmPrinter/WasmException.h b/llvm/lib/CodeGen/AsmPrinter/WasmException.h
new file mode 100644
index 00000000000..09a9a25ce8d
--- /dev/null
+++ b/llvm/lib/CodeGen/AsmPrinter/WasmException.h
@@ -0,0 +1,42 @@
+//===-- WasmException.h - Wasm Exception Framework -------------*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for writing WebAssembly exception info into asm
+// files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_WASMEXCEPTION_H
+#define LLVM_LIB_CODEGEN_ASMPRINTER_WASMEXCEPTION_H
+
+#include "EHStreamer.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+
+namespace llvm {
+
+class LLVM_LIBRARY_VISIBILITY WasmException : public EHStreamer {
+public:
+ WasmException(AsmPrinter *A) : EHStreamer(A) {}
+
+ void endModule() override {}
+ void beginFunction(const MachineFunction *MF) override {}
+ virtual void markFunctionEnd() override;
+ void endFunction(const MachineFunction *MF) override;
+
+protected:
+ // Compute the call site table for wasm EH.
+ void computeCallSiteTable(
+ SmallVectorImpl<CallSiteEntry> &CallSites,
+ const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
+ const SmallVectorImpl<unsigned> &FirstActions) override;
+};
+
+} // End of namespace llvm
+
+#endif
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index 431484f078b..9e4963c4bdb 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -661,8 +661,11 @@ MCSymbol *MachineFunction::addLandingPad(MachineBasicBlock *LandingPad) {
}
}
- } else if (isa<CatchPadInst>(FirstI)) {
- // TODO
+ } else if (const auto *CPI = dyn_cast<CatchPadInst>(FirstI)) {
+ for (unsigned I = CPI->getNumArgOperands(); I != 0; --I) {
+ Value *TypeInfo = CPI->getArgOperand(I - 1)->stripPointerCasts();
+ addCatchTypeInfo(LandingPad, dyn_cast<GlobalValue>(TypeInfo));
+ }
} else {
assert(isa<CleanupPadInst>(FirstI) && "Invalid landingpad!");
@@ -687,7 +690,8 @@ void MachineFunction::addFilterTypeInfo(MachineBasicBlock *LandingPad,
LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
}
-void MachineFunction::tidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap) {
+void MachineFunction::tidyLandingPads(DenseMap<MCSymbol *, uintptr_t> *LPMap,
+ bool TidyIfNoBeginLabels) {
for (unsigned i = 0; i != LandingPads.size(); ) {
LandingPadInfo &LandingPad = LandingPads[i];
if (LandingPad.LandingPadLabel &&
@@ -702,24 +706,25 @@ void MachineFunction::tidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap) {
continue;
}
- for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) {
- MCSymbol *BeginLabel = LandingPad.BeginLabels[j];
- MCSymbol *EndLabel = LandingPad.EndLabels[j];
- if ((BeginLabel->isDefined() ||
- (LPMap && (*LPMap)[BeginLabel] != 0)) &&
- (EndLabel->isDefined() ||
- (LPMap && (*LPMap)[EndLabel] != 0))) continue;
-
- LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
- LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
- --j;
- --e;
- }
+ if (TidyIfNoBeginLabels) {
+ for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) {
+ MCSymbol *BeginLabel = LandingPad.BeginLabels[j];
+ MCSymbol *EndLabel = LandingPad.EndLabels[j];
+ if ((BeginLabel->isDefined() || (LPMap && (*LPMap)[BeginLabel] != 0)) &&
+ (EndLabel->isDefined() || (LPMap && (*LPMap)[EndLabel] != 0)))
+ continue;
+
+ LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
+ LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
+ --j;
+ --e;
+ }
- // Remove landing pads with no try-ranges.
- if (LandingPads[i].BeginLabels.empty()) {
- LandingPads.erase(LandingPads.begin() + i);
- continue;
+ // Remove landing pads with no try-ranges.
+ if (LandingPads[i].BeginLabels.empty()) {
+ LandingPads.erase(LandingPads.begin() + i);
+ continue;
+ }
}
// If there is no landing pad, ensure that the list of typeids is empty.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 05eac30843f..3434f24db91 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -6294,12 +6294,12 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
return nullptr;
}
- case Intrinsic::wasm_landingpad_index: {
- // TODO store landing pad index in a map, which will be used when generating
- // LSDA information
+ case Intrinsic::wasm_landingpad_index:
+ // Information this intrinsic contained has been transferred to
+ // MachineFunction in SelectionDAGISel::PrepareEHLandingPad. We can safely
+ // delete it now.
return nullptr;
}
- }
}
void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
@@ -6456,7 +6456,7 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
WinEHFuncInfo *EHInfo = DAG.getMachineFunction().getWinEHFuncInfo();
EHInfo->addIPToStateRange(cast<InvokeInst>(CLI.CS.getInstruction()),
BeginLabel, EndLabel);
- } else {
+ } else if (!isScopedEHPersonality(Pers)) {
MF.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
}
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 2b4a590f19f..90bcaa653c3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -27,6 +27,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
@@ -1128,6 +1129,36 @@ static bool hasExceptionPointerOrCodeUser(const CatchPadInst *CPI) {
return false;
}
+// wasm.landingpad.index intrinsic is for associating a landing pad index number
+// with a catchpad instruction. Retrieve the landing pad index in the intrinsic
+// and store the mapping in the function.
+static void mapWasmLandingPadIndex(MachineBasicBlock *MBB,
+ const CatchPadInst *CPI) {
+ MachineFunction *MF = MBB->getParent();
+ // In case of single catch (...), we don't emit LSDA, so we don't need
+ // this information.
+ bool IsSingleCatchAllClause =
+ CPI->getNumArgOperands() == 1 &&
+ cast<Constant>(CPI->getArgOperand(0))->isNullValue();
+ if (!IsSingleCatchAllClause) {
+ // Create a mapping from landing pad label to landing pad index.
+ bool IntrFound = false;
+ for (const User *U : CPI->users()) {
+ if (const auto *Call = dyn_cast<IntrinsicInst>(U)) {
+ Intrinsic::ID IID = Call->getIntrinsicID();
+ if (IID == Intrinsic::wasm_landingpad_index) {
+ Value *IndexArg = Call->getArgOperand(1);
+ int Index = cast<ConstantInt>(IndexArg)->getZExtValue();
+ MF->setWasmLandingPadIndex(MBB, Index);
+ IntrFound = true;
+ break;
+ }
+ }
+ }
+ assert(IntrFound && "wasm.landingpad.index intrinsic not found!");
+ }
+}
+
/// PrepareEHLandingPad - Emit an EH_LABEL, set up live-in registers, and
/// do other setup for EH landing-pad blocks.
bool SelectionDAGISel::PrepareEHLandingPad() {
@@ -1137,44 +1168,48 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
const TargetRegisterClass *PtrRC =
TLI->getRegClassFor(TLI->getPointerTy(CurDAG->getDataLayout()));
+ auto Pers = classifyEHPersonality(PersonalityFn);
+
// Catchpads have one live-in register, which typically holds the exception
// pointer or code.
- if (const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->getFirstNonPHI())) {
- if (hasExceptionPointerOrCodeUser(CPI)) {
- // Get or create the virtual register to hold the pointer or code. Mark
- // the live in physreg and copy into the vreg.
- MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister(PersonalityFn);
- assert(EHPhysReg && "target lacks exception pointer register");
- MBB->addLiveIn(EHPhysReg);
- unsigned VReg = FuncInfo->getCatchPadExceptionPointerVReg(CPI, PtrRC);
- BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(),
- TII->get(TargetOpcode::COPY), VReg)
- .addReg(EHPhysReg, RegState::Kill);
+ if (isFuncletEHPersonality(Pers)) {
+ if (const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->getFirstNonPHI())) {
+ if (hasExceptionPointerOrCodeUser(CPI)) {
+ // Get or create the virtual register to hold the pointer or code. Mark
+ // the live in physreg and copy into the vreg.
+ MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister(PersonalityFn);
+ assert(EHPhysReg && "target lacks exception pointer register");
+ MBB->addLiveIn(EHPhysReg);
+ unsigned VReg = FuncInfo->getCatchPadExceptionPointerVReg(CPI, PtrRC);
+ BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(),
+ TII->get(TargetOpcode::COPY), VReg)
+ .addReg(EHPhysReg, RegState::Kill);
+ }
}
return true;
}
- if (!LLVMBB->isLandingPad())
- return true;
-
// Add a label to mark the beginning of the landing pad. Deletion of the
// landing pad can thus be detected via the MachineModuleInfo.
MCSymbol *Label = MF->addLandingPad(MBB);
- // Assign the call site to the landing pad's begin label.
- MF->setCallSiteLandingPad(Label, SDB->LPadToCallSiteMap[MBB]);
-
const MCInstrDesc &II = TII->get(TargetOpcode::EH_LABEL);
BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II)
.addSym(Label);
- // Mark exception register as live in.
- if (unsigned Reg = TLI->getExceptionPointerRegister(PersonalityFn))
- FuncInfo->ExceptionPointerVirtReg = MBB->addLiveIn(Reg, PtrRC);
-
- // Mark exception selector register as live in.
- if (unsigned Reg = TLI->getExceptionSelectorRegister(PersonalityFn))
- FuncInfo->ExceptionSelectorVirtReg = MBB->addLiveIn(Reg, PtrRC);
+ if (Pers == EHPersonality::Wasm_CXX) {
+ if (const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->getFirstNonPHI()))
+ mapWasmLandingPadIndex(MBB, CPI);
+ } else {
+ // Assign the call site to the landing pad's begin label.
+ MF->setCallSiteLandingPad(Label, SDB->LPadToCallSiteMap[MBB]);
+ // Mark exception register as live in.
+ if (unsigned Reg = TLI->getExceptionPointerRegister(PersonalityFn))
+ FuncInfo->ExceptionPointerVirtReg = MBB->addLiveIn(Reg, PtrRC);
+ // Mark exception selector register as live in.
+ if (unsigned Reg = TLI->getExceptionSelectorRegister(PersonalityFn))
+ FuncInfo->ExceptionSelectorVirtReg = MBB->addLiveIn(Reg, PtrRC);
+ }
return true;
}
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index b046cd81d6c..341ab927861 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -1748,6 +1748,10 @@ const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference(
void TargetLoweringObjectFileWasm::InitializeWasm() {
StaticCtorSection =
getContext().getWasmSection(".init_array", SectionKind::getData());
+
+ // We don't use PersonalityEncoding and LSDAEncoding because we don't emit
+ // .cfi directives. We use TTypeEncoding to encode typeinfo global variables.
+ TTypeEncoding = dwarf::DW_EH_PE_absptr;
}
MCSection *TargetLoweringObjectFileWasm::getStaticCtorSection(
diff --git a/llvm/lib/CodeGen/WasmEHPrepare.cpp b/llvm/lib/CodeGen/WasmEHPrepare.cpp
index 83d04da5dd0..6f02a05f561 100644
--- a/llvm/lib/CodeGen/WasmEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WasmEHPrepare.cpp
@@ -300,7 +300,7 @@ void WasmEHPrepare::prepareEHPad(BasicBlock *BB, unsigned Index) {
// This is to create a map of <landingpad EH label, landingpad index> in
// SelectionDAGISel, which is to be used in EHStreamer to emit LSDA tables.
// Pseudocode: wasm.landingpad.index(Index);
- IRB.CreateCall(LPadIndexF, IRB.getInt32(Index));
+ IRB.CreateCall(LPadIndexF, {FPI, IRB.getInt32(Index)});
// Pseudocode: __wasm_lpad_context.lpad_index = index;
IRB.CreateStore(IRB.getInt32(Index), LPadIndexField);
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 465b62ce8c9..54d8d4e5f71 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -746,6 +746,12 @@ void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
DwarfPubNamesSection = Ctx->getWasmSection(".debug_pubnames", SectionKind::getMetadata());
DwarfPubTypesSection = Ctx->getWasmSection(".debug_pubtypes", SectionKind::getMetadata());
+ // Wasm use data section for LSDA.
+ // TODO Consider putting each function's exception table in a separate
+ // section, as in -function-sections, to facilitate lld's --gc-section.
+ LSDASection = Ctx->getWasmSection(".rodata.gcc_except_table",
+ SectionKind::getReadOnlyWithRel());
+
// TODO: Define more sections.
}
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index cbbe161ae82..f9318ad5801 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -635,10 +635,12 @@ static void addData(SmallVectorImpl<char> &DataBytes,
llvm_unreachable("The fill should be an assembler constant");
DataBytes.insert(DataBytes.end(), Fill->getValueSize() * NumValues,
Fill->getValue());
+ } else if (auto *LEB = dyn_cast<MCLEBFragment>(&Frag)) {
+ const SmallVectorImpl<char> &Contents = LEB->getContents();
+ DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
} else {
const auto &DataFrag = cast<MCDataFragment>(Frag);
const SmallVectorImpl<char> &Contents = DataFrag.getContents();
-
DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
}
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index c056e1af588..06414c27318 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -21,6 +21,7 @@
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/IR/DiagnosticInfo.h"
@@ -998,9 +999,17 @@ WebAssemblyTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
default:
return {}; // Don't custom lower most intrinsics.
- case Intrinsic::wasm_lsda:
- // TODO For now, just return 0 not to crash
- return DAG.getConstant(0, DL, Op.getValueType());
+ case Intrinsic::wasm_lsda: {
+ MachineFunction &MF = DAG.getMachineFunction();
+ EVT VT = Op.getValueType();
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
+ auto &Context = MF.getMMI().getContext();
+ MCSymbol *S = Context.getOrCreateSymbol(Twine("GCC_except_table") +
+ Twine(MF.getFunctionNumber()));
+ return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
+ DAG.getMCSymbol(S, PtrVT));
+ }
}
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
index c5b41983245..8fff924265f 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
@@ -282,6 +282,8 @@ def : Pat<(i32 (WebAssemblywrapper tglobaladdr:$addr)),
(CONST_I32 tglobaladdr:$addr)>;
def : Pat<(i32 (WebAssemblywrapper texternalsym:$addr)),
(CONST_I32 texternalsym:$addr)>;
+def : Pat<(i32 (WebAssemblywrapper mcsym:$sym)), (CONST_I32 mcsym:$sym)>;
+def : Pat<(i64 (WebAssemblywrapper mcsym:$sym)), (CONST_I64 mcsym:$sym)>;
//===----------------------------------------------------------------------===//
// Additional sets of instructions.
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
index ebd374762ae..1dad7b8a289 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -230,6 +230,13 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
(MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_FUNCTION) != 0,
(MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_GLOBAL) != 0);
break;
+ case MachineOperand::MO_MCSymbol:
+ // This is currently used only for LSDA symbols (GCC_except_table),
+ // because global addresses or other external symbols are handled above.
+ assert(MO.getTargetFlags() == 0 &&
+ "WebAssembly does not use target flags on MCSymbol");
+ MCOp = LowerSymbolOperand(MO.getMCSymbol(), /*Offset=*/0, false, false);
+ break;
}
OutMI.addOperand(MCOp);
diff --git a/llvm/test/CodeGen/WebAssembly/eh-lsda.ll b/llvm/test/CodeGen/WebAssembly/eh-lsda.ll
new file mode 100644
index 00000000000..fd550938c42
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/eh-lsda.ll
@@ -0,0 +1,239 @@
+; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-keep-registers -exception-model=wasm -mattr=+exception-handling | FileCheck -allow-deprecated-dag-overlap %s
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+@_ZTIi = external constant i8*
+@_ZTIf = external constant i8*
+@_ZTId = external constant i8*
+
+; Single catch (...) does not need an exception table.
+;
+; try {
+; may_throw();
+; } catch (...) {
+; }
+; CHECK-LABEL: test0:
+; CHECK-NOT: GCC_except_table
+define void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+entry:
+ invoke void @may_throw()
+ to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %0 = catchswitch within none [label %catch.start] unwind to caller
+
+catch.start: ; preds = %catch.dispatch
+ %1 = catchpad within %0 [i8* null]
+ %2 = call i8* @llvm.wasm.get.exception(token %1)
+ %3 = call i32 @llvm.wasm.get.ehselector(token %1)
+ %4 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ]
+ call void @__cxa_end_catch() [ "funclet"(token %1) ]
+ catchret from %1 to label %try.cont
+
+try.cont: ; preds = %entry, %catch.start
+ ret void
+}
+
+; Exception table generation + shared action test.
+;
+; try {
+; may_throw();
+; } catch (int) {
+; } catch (float) {
+; } catch (double) {
+; } catch (...) {
+; }
+;
+; try {
+; may_throw();
+; } catch (double) {
+; } catch (...) {
+; }
+;
+; try {
+; may_throw();
+; } catch (int) {
+; } catch (float) {
+; }
+;
+; There are three landing pads. The second landing pad should share action table
+; entries with the first landing pad because they end with the same sequence
+; (double -> ...). But the third landing table cannot share action table entries
+; with others, so it should create its own entries.
+; CHECK-LABEL: test1:
+; CHECK: .section .rodata.gcc_except_table,"",@
+; CHECK-NEXT: .p2align 2
+; CHECK-NEXT: GCC_except_table[[START:[0-9]+]]:
+; CHECK-NEXT: .Lexception0:
+; CHECK-NEXT: .int8 255 # @LPStart Encoding = omit
+; CHECK-NEXT: .int8 0 # @TType Encoding = absptr
+; CHECK-NEXT: .uleb128 .Lttbase0-.Lttbaseref0
+; CHECK-NEXT: .Lttbaseref0:
+; CHECK-NEXT: .int8 1 # Call site Encoding = uleb128
+; CHECK-NEXT: .uleb128 .Lcst_end0-.Lcst_begin0
+; CHECK-NEXT: .Lcst_begin0:
+; CHECK-NEXT: .int8 0 # >> Call Site 0 <<
+; CHECK-NEXT: # On exception at call site 0
+; CHECK-NEXT: .int8 7 # Action: 4
+; CHECK-NEXT: .int8 1 # >> Call Site 1 <<
+; CHECK-NEXT: # On exception at call site 1
+; CHECK-NEXT: .int8 3 # Action: 2
+; CHECK-NEXT: .int8 2 # >> Call Site 2 <<
+; CHECK-NEXT: # On exception at call site 2
+; CHECK-NEXT: .int8 11 # Action: 6
+; CHECK-NEXT: .Lcst_end0:
+; CHECK-NEXT: .int8 1 # >> Action Record 1 <<
+; CHECK-NEXT: # Catch TypeInfo 1
+; CHECK-NEXT: .int8 0 # No further actions
+; CHECK-NEXT: .int8 2 # >> Action Record 2 <<
+; CHECK-NEXT: # Catch TypeInfo 2
+; CHECK-NEXT: .int8 125 # Continue to action 1
+; CHECK-NEXT: .int8 3 # >> Action Record 3 <<
+; CHECK-NEXT: # Catch TypeInfo 3
+; CHECK-NEXT: .int8 125 # Continue to action 2
+; CHECK-NEXT: .int8 4 # >> Action Record 4 <<
+; CHECK-NEXT: # Catch TypeInfo 4
+; CHECK-NEXT: .int8 125 # Continue to action 3
+; CHECK-NEXT: .int8 3 # >> Action Record 5 <<
+; CHECK-NEXT: # Catch TypeInfo 3
+; CHECK-NEXT: .int8 0 # No further actions
+; CHECK-NEXT: .int8 4 # >> Action Record 6 <<
+; CHECK-NEXT: # Catch TypeInfo 4
+; CHECK-NEXT: .int8 125 # Continue to action 5
+; CHECK-NEXT: .p2align 2
+; CHECK-NEXT: # >> Catch TypeInfos <<
+; CHECK-NEXT: .int32 _ZTIi # TypeInfo 4
+; CHECK-NEXT: .int32 _ZTIf # TypeInfo 3
+; CHECK-NEXT: .int32 _ZTId # TypeInfo 2
+; CHECK-NEXT: .int32 0 # TypeInfo 1
+; CHECK-NEXT: .Lttbase0:
+; CHECK-NEXT: .p2align 2
+; CHECK-NEXT: .LGCC_except_table_end[[END:[0-9]+]]:
+; CHECK-NEXT: .size GCC_except_table[[START]], .LGCC_except_table_end[[END]]-GCC_except_table[[START]]
+define void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+entry:
+ invoke void @may_throw()
+ to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %0 = catchswitch within none [label %catch.start] unwind to caller
+
+catch.start: ; preds = %catch.dispatch
+ %1 = catchpad within %0 [i8* bitcast (i8** @_ZTIi to i8*), i8* bitcast (i8** @_ZTIf to i8*), i8* bitcast (i8** @_ZTId to i8*), i8* null]
+ %2 = call i8* @llvm.wasm.get.exception(token %1)
+ %3 = call i32 @llvm.wasm.get.ehselector(token %1)
+ %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
+ %matches = icmp eq i32 %3, %4
+ br i1 %matches, label %catch10, label %catch.fallthrough
+
+catch10: ; preds = %catch.start
+ %5 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ]
+ %6 = bitcast i8* %5 to i32*
+ %7 = load i32, i32* %6, align 4
+ call void @__cxa_end_catch() [ "funclet"(token %1) ]
+ catchret from %1 to label %try.cont
+
+try.cont: ; preds = %entry, %catch, %catch4, %catch7, %catch10
+ invoke void @may_throw()
+ to label %try.cont23 unwind label %catch.dispatch14
+
+catch.dispatch14: ; preds = %try.cont
+ %8 = catchswitch within none [label %catch.start15] unwind to caller
+
+catch.start15: ; preds = %catch.dispatch14
+ %9 = catchpad within %8 [i8* bitcast (i8** @_ZTId to i8*), i8* null]
+ %10 = call i8* @llvm.wasm.get.exception(token %9)
+ %11 = call i32 @llvm.wasm.get.ehselector(token %9)
+ %12 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTId to i8*))
+ %matches16 = icmp eq i32 %11, %12
+ %13 = call i8* @__cxa_begin_catch(i8* %10) [ "funclet"(token %9) ]
+ br i1 %matches16, label %catch20, label %catch17
+
+catch20: ; preds = %catch.start15
+ %14 = bitcast i8* %13 to double*
+ %15 = load double, double* %14, align 8
+ call void @__cxa_end_catch() [ "funclet"(token %9) ]
+ catchret from %9 to label %try.cont23
+
+try.cont23: ; preds = %try.cont, %catch17, %catch20
+ invoke void @may_throw()
+ to label %try.cont36 unwind label %catch.dispatch25
+
+catch.dispatch25: ; preds = %try.cont23
+ %16 = catchswitch within none [label %catch.start26] unwind to caller
+
+catch.start26: ; preds = %catch.dispatch25
+ %17 = catchpad within %16 [i8* bitcast (i8** @_ZTIi to i8*), i8* bitcast (i8** @_ZTIf to i8*)]
+ %18 = call i8* @llvm.wasm.get.exception(token %17)
+ %19 = call i32 @llvm.wasm.get.ehselector(token %17)
+ %20 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
+ %matches27 = icmp eq i32 %19, %20
+ br i1 %matches27, label %catch33, label %catch.fallthrough28
+
+catch33: ; preds = %catch.start26
+ %21 = call i8* @__cxa_begin_catch(i8* %18) [ "funclet"(token %17) ]
+ %22 = bitcast i8* %21 to i32*
+ %23 = load i32, i32* %22, align 4
+ call void @__cxa_end_catch() [ "funclet"(token %17) ]
+ catchret from %17 to label %try.cont36
+
+catch.fallthrough28: ; preds = %catch.start26
+ %24 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIf to i8*))
+ %matches29 = icmp eq i32 %19, %24
+ br i1 %matches29, label %catch30, label %rethrow
+
+catch30: ; preds = %catch.fallthrough28
+ %25 = call i8* @__cxa_begin_catch(i8* %18) [ "funclet"(token %17) ]
+ %26 = bitcast i8* %25 to float*
+ %27 = load float, float* %26, align 4
+ call void @__cxa_end_catch() [ "funclet"(token %17) ]
+ catchret from %17 to label %try.cont36
+
+rethrow: ; preds = %catch.fallthrough28
+ call void @__cxa_rethrow() [ "funclet"(token %17) ]
+ unreachable
+
+try.cont36: ; preds = %try.cont23, %catch30, %catch33
+ ret void
+
+catch17: ; preds = %catch.start15
+ call void @__cxa_end_catch() [ "funclet"(token %9) ]
+ catchret from %9 to label %try.cont23
+
+catch.fallthrough: ; preds = %catch.start
+ %28 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIf to i8*))
+ %matches1 = icmp eq i32 %3, %28
+ br i1 %matches1, label %catch7, label %catch.fallthrough2
+
+catch7: ; preds = %catch.fallthrough
+ %29 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ]
+ %30 = bitcast i8* %29 to float*
+ %31 = load float, float* %30, align 4
+ call void @__cxa_end_catch() [ "funclet"(token %1) ]
+ catchret from %1 to label %try.cont
+
+catch.fallthrough2: ; preds = %catch.fallthrough
+ %32 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTId to i8*))
+ %matches3 = icmp eq i32 %3, %32
+ %33 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ]
+ br i1 %matches3, label %catch4, label %catch
+
+catch4: ; preds = %catch.fallthrough2
+ %34 = bitcast i8* %33 to double*
+ %35 = load double, double* %34, align 8
+ call void @__cxa_end_catch() [ "funclet"(token %1) ]
+ catchret from %1 to label %try.cont
+
+catch: ; preds = %catch.fallthrough2
+ call void @__cxa_end_catch() [ "funclet"(token %1) ]
+ catchret from %1 to label %try.cont
+}
+
+declare void @may_throw()
+declare i32 @llvm.eh.typeid.for(i8*)
+declare i8* @llvm.wasm.get.exception(token)
+declare i32 @llvm.wasm.get.ehselector(token)
+declare void @__cxa_rethrow()
+declare i8* @__cxa_begin_catch(i8*)
+declare void @__cxa_end_catch()
+declare i32 @__gxx_wasm_personality_v0(...)
diff --git a/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll b/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll
index e6005e34057..67e198eb058 100644
--- a/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll
+++ b/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll
@@ -30,7 +30,7 @@ catch.start: ; preds = %catch.dispatch
; CHECK: catch.start:
; CHECK-NEXT: %[[CATCHPAD:.*]] = catchpad
; CHECK-NEXT: %[[EXN:.*]] = call i8* @llvm.wasm.catch(i32 0)
-; CHECK-NEXT: call void @llvm.wasm.landingpad.index(i32 0)
+; CHECK-NEXT: call void @llvm.wasm.landingpad.index(token %[[CATCHPAD]], i32 0)
; CHECK-NEXT: store i32 0, i32* getelementptr inbounds ({ i32, i8*, i32 }, { i32, i8*, i32 }* @__wasm_lpad_context, i32 0, i32 0)
; CHECK-NEXT: %[[LSDA:.*]] = call i8* @llvm.wasm.lsda()
; CHECK-NEXT: store i8* %[[LSDA]], i8** getelementptr inbounds ({ i32, i8*, i32 }, { i32, i8*, i32 }* @__wasm_lpad_context, i32 0, i32 1)
@@ -98,7 +98,7 @@ catch.start3: ; preds = %catch.dispatch2
%matches = icmp eq i32 %8, %9
br i1 %matches, label %catch4, label %rethrow
; CHECK: catch.start3:
-; CHECK: call void @llvm.wasm.landingpad.index(i32 0)
+; CHECK: call void @llvm.wasm.landingpad.index(token %{{.+}}, i32 0)
catch4: ; preds = %catch.start3
%10 = call i8* @__cxa_begin_catch(i8* %7) [ "funclet"(token %6) ]
@@ -311,7 +311,7 @@ declare void @__cxa_rethrow()
declare void @__clang_call_terminate(i8*)
; CHECK-DAG: declare i8* @llvm.wasm.catch(i32)
-; CHECK-DAG: declare void @llvm.wasm.landingpad.index(i32)
+; CHECK-DAG: declare void @llvm.wasm.landingpad.index(token, i32)
; CHECK-DAG: declare i8* @llvm.wasm.lsda()
; CHECK-DAG: declare i32 @_Unwind_CallPersonality(i8*)
OpenPOWER on IntegriCloud