//=== WebAssemblyLowerEmscriptenEHSjLj.cpp - Lower exceptions for Emscripten =//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file lowers exception-related instructions and setjmp/longjmp function
/// calls to use Emscripten's library functions. The pass uses JavaScript's try
/// and catch mechanism in case of Emscripten EH/SjLj and Wasm EH intrinsics in
/// case of Emscripten SjLJ.
///
/// * Emscripten exception handling
/// This pass lowers invokes and landingpads into library functions in JS glue
/// code. Invokes are lowered into function wrappers called invoke wrappers that
/// exist in JS side, which wraps the original function call with JS try-catch.
/// If an exception occurred, cxa_throw() function in JS side sets some
/// variables (see below) so we can check whether an exception occurred from
/// wasm code and handle it appropriately.
///
/// * Emscripten setjmp-longjmp handling
/// This pass lowers setjmp to a reasonably-performant approach for emscripten.
/// The idea is that each block with a setjmp is broken up into two parts: the
/// part containing setjmp and the part right after the setjmp. The latter part
/// is either reached from the setjmp, or later from a longjmp. To handle the
/// longjmp, all calls that might longjmp are also called using invoke wrappers
/// and thus JS / try-catch. JS longjmp() function also sets some variables so
/// we can check / whether a longjmp occurred from wasm code. Each block with a
/// function call that might longjmp is also split up after the longjmp call.
/// After the longjmp call, we check whether a longjmp occurred, and if it did,
/// which setjmp it corresponds to, and jump to the right post-setjmp block.
/// We assume setjmp-longjmp handling always run after EH handling, which means
/// we don't expect any exception-related instructions when SjLj runs.
/// FIXME Currently this scheme does not support indirect call of setjmp,
/// because of the limitation of the scheme itself. fastcomp does not support it
/// either.
///
/// In detail, this pass does following things:
///
/// 1) Assumes the existence of global variables: __THREW__, __threwValue
///    __THREW__ and __threwValue are defined in compiler-rt in Emscripten.
///    These variables are used for both exceptions and setjmp/longjmps.
///    __THREW__ indicates whether an exception or a longjmp occurred or not. 0
///    means nothing occurred, 1 means an exception occurred, and other numbers
///    mean a longjmp occurred. In the case of longjmp, __THREW__ variable
///    indicates the corresponding setjmp buffer the longjmp corresponds to.
///    __threwValue is 0 for exceptions, and the argument to longjmp in case of
///    longjmp.
///
/// * Emscripten exception handling
///
/// 2) We assume the existence of setThrew and setTempRet0/getTempRet0 functions
///    at link time. setThrew exists in Emscripten's compiler-rt:
///
///    void setThrew(uintptr_t threw, int value) {
///      if (__THREW__ == 0) {
///        __THREW__ = threw;
///        __threwValue = value;
///      }
///    }
//
///    setTempRet0 is called from __cxa_find_matching_catch() in JS glue code.
///    In exception handling, getTempRet0 indicates the type of an exception
///    caught, and in setjmp/longjmp, it means the second argument to longjmp
///    function.
///
/// 3) Lower
///      invoke @func(arg1, arg2) to label %invoke.cont unwind label %lpad
///    into
///      __THREW__ = 0;
///      call @__invoke_SIG(func, arg1, arg2)
///      %__THREW__.val = __THREW__;
///      __THREW__ = 0;
///      if (%__THREW__.val == 1)
///        goto %lpad
///      else
///         goto %invoke.cont
///    SIG is a mangled string generated based on the LLVM IR-level function
///    signature. After LLVM IR types are lowered to the target wasm types,
///    the names for these wrappers will change based on wasm types as well,
///    as in invoke_vi (function takes an int and returns void). The bodies of
///    these wrappers will be generated in JS glue code, and inside those
///    wrappers we use JS try-catch to generate actual exception effects. It
///    also calls the original callee function. An example wrapper in JS code
///    would look like this:
///      function invoke_vi(index,a1) {
///        try {
///          Module["dynCall_vi"](index,a1); // This calls original callee
///        } catch(e) {
///          if (typeof e !== 'number' && e !== 'longjmp') throw e;
///          _setThrew(1, 0); // setThrew is called here
///        }
///      }
///    If an exception is thrown, __THREW__ will be set to true in a wrapper,
///    so we can jump to the right BB based on this value.
///
/// 4) Lower
///      %val = landingpad catch c1 catch c2 catch c3 ...
///      ... use %val ...
///    into
///      %fmc = call @__cxa_find_matching_catch_N(c1, c2, c3, ...)
///      %val = {%fmc, getTempRet0()}
///      ... use %val ...
///    Here N is a number calculated based on the number of clauses.
///    setTempRet0 is called from __cxa_find_matching_catch() in JS glue code.
///
/// 5) Lower
///      resume {%a, %b}
///    into
///      call @__resumeException(%a)
///    where __resumeException() is a function in JS glue code.
///
/// 6) Lower
///      call @llvm.eh.typeid.for(type) (intrinsic)
///    into
///      call @llvm_eh_typeid_for(type)
///    llvm_eh_typeid_for function will be generated in JS glue code.
///
/// * Emscripten setjmp / longjmp handling
///
/// If there are calls to longjmp()
///
/// 1) Lower
///      longjmp(env, val)
///    into
///      emscripten_longjmp(env, val)
///
/// If there are calls to setjmp()
///
/// 2) In the function entry that calls setjmp, initialize setjmpTable and
///    sejmpTableSize as follows:
///      setjmpTableSize = 4;
///      setjmpTable = (int *) malloc(40);
///      setjmpTable[0] = 0;
///    setjmpTable and setjmpTableSize are used to call saveSetjmp() function in
///    Emscripten compiler-rt.
///
/// 3) Lower
///      setjmp(env)
///    into
///      setjmpTable = saveSetjmp(env, label, setjmpTable, setjmpTableSize);
///      setjmpTableSize = getTempRet0();
///    For each dynamic setjmp call, setjmpTable stores its ID (a number which
///    is incrementally assigned from 0) and its label (a unique number that
///    represents each callsite of setjmp). When we need more entries in
///    setjmpTable, it is reallocated in saveSetjmp() in Emscripten's
///    compiler-rt and it will return the new table address, and assign the new
///    table size in setTempRet0(). saveSetjmp also stores the setjmp's ID into
///    the buffer 'env'. A BB with setjmp is split into two after setjmp call in
///    order to make the post-setjmp BB the possible destination of longjmp BB.
///
/// 4) Lower every call that might longjmp into
///      __THREW__ = 0;
///      call @__invoke_SIG(func, arg1, arg2)
///      %__THREW__.val = __THREW__;
///      __THREW__ = 0;
///      %__threwValue.val = __threwValue;
///      if (%__THREW__.val != 0 & %__threwValue.val != 0) {
///        %label = testSetjmp(mem[%__THREW__.val], setjmpTable,
///                            setjmpTableSize);
///        if (%label == 0)
///          emscripten_longjmp(%__THREW__.val, %__threwValue.val);
///        setTempRet0(%__threwValue.val);
///      } else {
///        %label = -1;
///      }
///      longjmp_result = getTempRet0();
///      switch %label {
///        label 1: goto post-setjmp BB 1
///        label 2: goto post-setjmp BB 2
///        ...
///        default: goto splitted next BB
///      }
///    testSetjmp examines setjmpTable to see if there is a matching setjmp
///    call. After calling an invoke wrapper, if a longjmp occurred, __THREW__
///    will be the address of matching jmp_buf buffer and __threwValue be the
///    second argument to longjmp. mem[%__THREW__.val] is a setjmp ID that is
///    stored in saveSetjmp. testSetjmp returns a setjmp label, a unique ID to
///    each setjmp callsite. Label 0 means this longjmp buffer does not
///    correspond to one of the setjmp callsites in this function, so in this
///    case we just chain the longjmp to the caller. Label -1 means no longjmp
///    occurred. Otherwise we jump to the right post-setjmp BB based on the
///    label.
///
/// * Wasm setjmp / longjmp handling
/// This mode still uses some Emscripten library functions but not JavaScript's
/// try-catch mechanism. It instead uses Wasm exception handling intrinsics,
/// which will be lowered to exception handling instructions.
///
/// If there are calls to longjmp()
///
/// 1) Lower
///      longjmp(env, val)
///    into
///      __wasm_longjmp(env, val)
///
/// If there are calls to setjmp()
///
/// 2) and 3): The same as 2) and 3) in Emscripten SjLj.
/// (setjmpTable/setjmpTableSize initialization + setjmp callsite
/// transformation)
///
/// 4) Create a catchpad with a wasm.catch() intrinsic, which returns the value
/// thrown by __wasm_longjmp function. In Emscripten library, we have this
/// struct:
///
/// struct __WasmLongjmpArgs {
///   void *env;
///   int val;
/// };
/// struct __WasmLongjmpArgs __wasm_longjmp_args;
///
/// The thrown value here is a pointer to __wasm_longjmp_args struct object. We
/// use this struct to transfer two values by throwing a single value. Wasm
/// throw and catch instructions are capable of throwing and catching multiple
/// values, but it also requires multivalue support that is currently not very
/// reliable.
/// TODO Switch to throwing and catching two values without using the struct
///
/// All longjmpable function calls will be converted to an invoke that will
/// unwind to this catchpad in case a longjmp occurs. Within the catchpad, we
/// test the thrown values using testSetjmp function as we do for Emscripten
/// SjLj. The main difference is, in Emscripten SjLj, we need to transform every
/// longjmpable callsite into a sequence of code including testSetjmp() call; in
/// Wasm SjLj we do the testing in only one place, in this catchpad.
///
/// After testing calling testSetjmp(), if the longjmp does not correspond to
/// one of the setjmps within the current function, it rethrows the longjmp
/// by calling __wasm_longjmp(). If it corresponds to one of setjmps in the
/// function, we jump to the beginning of the function, which contains a switch
/// to each post-setjmp BB. Again, in Emscripten SjLj, this switch is added for
/// every longjmpable callsite; in Wasm SjLj we do this only once at the top of
/// the function. (after setjmpTable/setjmpTableSize initialization)
///
/// The below is the pseudocode for what we have described
///
/// entry:
///   Initialize setjmpTable and setjmpTableSize
///
/// setjmp.dispatch:
///    switch %label {
///      label 1: goto post-setjmp BB 1
///      label 2: goto post-setjmp BB 2
///      ...
///      default: goto splitted next BB
///    }
/// ...
///
/// bb:
///   invoke void @foo() ;; foo is a longjmpable function
///     to label %next unwind label %catch.dispatch.longjmp
/// ...
///
/// catch.dispatch.longjmp:
///   %0 = catchswitch within none [label %catch.longjmp] unwind to caller
///
/// catch.longjmp:
///   %longjmp.args = wasm.catch() ;; struct __WasmLongjmpArgs
///   %env = load 'env' field from __WasmLongjmpArgs
///   %val = load 'val' field from __WasmLongjmpArgs
///   %label = testSetjmp(mem[%env], setjmpTable, setjmpTableSize);
///   if (%label == 0)
///     __wasm_longjmp(%env, %val)
///   catchret to %setjmp.dispatch
///
///===----------------------------------------------------------------------===//

#include "WebAssembly.h"
#include "WebAssemblyTargetMachine.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/WasmEHFuncInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
#include "llvm/Transforms/Utils/SSAUpdaterBulk.h"

using namespace llvm;

#define DEBUG_TYPE "wasm-lower-em-ehsjlj"

// Emscripten's asm.js-style exception handling
extern cl::opt<bool> WasmEnableEmEH;
// Emscripten's asm.js-style setjmp/longjmp handling
extern cl::opt<bool> WasmEnableEmSjLj;
// Wasm setjmp/longjmp handling using wasm EH instructions
extern cl::opt<bool> WasmEnableSjLj;

static cl::list<std::string>
    EHAllowlist("emscripten-cxx-exceptions-allowed",
                cl::desc("The list of function names in which Emscripten-style "
                         "exception handling is enabled (see emscripten "
                         "EMSCRIPTEN_CATCHING_ALLOWED options)"),
                cl::CommaSeparated);

namespace {
class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
  bool EnableEmEH;     // Enable Emscripten exception handling
  bool EnableEmSjLj;   // Enable Emscripten setjmp/longjmp handling
  bool EnableWasmSjLj; // Enable Wasm setjmp/longjmp handling
  bool DoSjLj;         // Whether we actually perform setjmp/longjmp handling

  GlobalVariable *ThrewGV = nullptr;      // __THREW__ (Emscripten)
  GlobalVariable *ThrewValueGV = nullptr; // __threwValue (Emscripten)
  Function *GetTempRet0F = nullptr;       // getTempRet0() (Emscripten)
  Function *SetTempRet0F = nullptr;       // setTempRet0() (Emscripten)
  Function *ResumeF = nullptr;            // __resumeException() (Emscripten)
  Function *EHTypeIDF = nullptr;          // llvm.eh.typeid.for() (intrinsic)
  Function *EmLongjmpF = nullptr;         // emscripten_longjmp() (Emscripten)
  Function *SaveSetjmpF = nullptr;        // saveSetjmp() (Emscripten)
  Function *TestSetjmpF = nullptr;        // testSetjmp() (Emscripten)
  Function *WasmLongjmpF = nullptr;       // __wasm_longjmp() (Emscripten)
  Function *CatchF = nullptr;             // wasm.catch() (intrinsic)

  // type of 'struct __WasmLongjmpArgs' defined in emscripten
  Type *LongjmpArgsTy = nullptr;

  // __cxa_find_matching_catch_N functions.
  // Indexed by the number of clauses in an original landingpad instruction.
  DenseMap<int, Function *> FindMatchingCatches;
  // Map of <function signature string, invoke_ wrappers>
  StringMap<Function *> InvokeWrappers;
  // Set of allowed function names for exception handling
  std::set<std::string> EHAllowlistSet;
  // Functions that contains calls to setjmp
  SmallPtrSet<Function *, 8> SetjmpUsers;

  StringRef getPassName() const override {
    return "WebAssembly Lower Emscripten Exceptions";
  }

  using InstVector = SmallVectorImpl<Instruction *>;
  bool runEHOnFunction(Function &F);
  bool runSjLjOnFunction(Function &F);
  void handleLongjmpableCallsForEmscriptenSjLj(
      Function &F, InstVector &SetjmpTableInsts,
      InstVector &SetjmpTableSizeInsts,
      SmallVectorImpl<PHINode *> &SetjmpRetPHIs);
  void
  handleLongjmpableCallsForWasmSjLj(Function &F, InstVector &SetjmpTableInsts,
                                    InstVector &SetjmpTableSizeInsts,
                                    SmallVectorImpl<PHINode *> &SetjmpRetPHIs);
  Function *getFindMatchingCatch(Module &M, unsigned NumClauses);

  Value *wrapInvoke(CallBase *CI);
  void wrapTestSetjmp(BasicBlock *BB, DebugLoc DL, Value *Threw,
                      Value *SetjmpTable, Value *SetjmpTableSize, Value *&Label,
                      Value *&LongjmpResult, BasicBlock *&CallEmLongjmpBB,
                      PHINode *&CallEmLongjmpBBThrewPHI,
                      PHINode *&CallEmLongjmpBBThrewValuePHI,
                      BasicBlock *&EndBB);
  Function *getInvokeWrapper(CallBase *CI);

  bool areAllExceptionsAllowed() const { return EHAllowlistSet.empty(); }
  bool supportsException(const Function *F) const {
    return EnableEmEH && (areAllExceptionsAllowed() ||
                          EHAllowlistSet.count(std::string(F->getName())));
  }
  void replaceLongjmpWith(Function *LongjmpF, Function *NewF);

  void rebuildSSA(Function &F);

public:
  static char ID;

  WebAssemblyLowerEmscriptenEHSjLj()
      : ModulePass(ID), EnableEmEH(WasmEnableEmEH),
        EnableEmSjLj(WasmEnableEmSjLj), EnableWasmSjLj(WasmEnableSjLj) {
    assert(!(EnableEmSjLj && EnableWasmSjLj) &&
           "Two SjLj modes cannot be turned on at the same time");
    assert(!(EnableEmEH && EnableWasmSjLj) &&
           "Wasm SjLj should be only used with Wasm EH");
    EHAllowlistSet.insert(EHAllowlist.begin(), EHAllowlist.end());
  }
  bool runOnModule(Module &M) override;

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<DominatorTreeWrapperPass>();
  }
};
} // End anonymous namespace

char WebAssemblyLowerEmscriptenEHSjLj::ID = 0;
INITIALIZE_PASS(WebAssemblyLowerEmscriptenEHSjLj, DEBUG_TYPE,
                "WebAssembly Lower Emscripten Exceptions / Setjmp / Longjmp",
                false, false)

ModulePass *llvm::createWebAssemblyLowerEmscriptenEHSjLj() {
  return new WebAssemblyLowerEmscriptenEHSjLj();
}

static bool canThrow(const Value *V) {
  if (const auto *F = dyn_cast<const Function>(V)) {
    // Intrinsics cannot throw
    if (F->isIntrinsic())
      return false;
    StringRef Name = F->getName();
    // leave setjmp and longjmp (mostly) alone, we process them properly later
    if (Name == "setjmp" || Name == "longjmp" || Name == "emscripten_longjmp")
      return false;
    return !F->doesNotThrow();
  }
  // not a function, so an indirect call - can throw, we can't tell
  return true;
}

// Get a global variable with the given name. If it doesn't exist declare it,
// which will generate an import and assume that it will exist at link time.
static GlobalVariable *getGlobalVariable(Module &M, Type *Ty,
                                         WebAssemblyTargetMachine &TM,
                                         const char *Name) {
  auto *GV = dyn_cast<GlobalVariable>(M.getOrInsertGlobal(Name, Ty));
  if (!GV)
    report_fatal_error(Twine("unable to create global: ") + Name);

  // If the target supports TLS, make this variable thread-local. We can't just
  // unconditionally make it thread-local and depend on
  // CoalesceFeaturesAndStripAtomics to downgrade it, because stripping TLS has
  // the side effect of disallowing the object from being linked into a
  // shared-memory module, which we don't want to be responsible for.
  auto *Subtarget = TM.getSubtargetImpl();
  auto TLS = Subtarget->hasAtomics() && Subtarget->hasBulkMemory()
                 ? GlobalValue::LocalExecTLSModel
                 : GlobalValue::NotThreadLocal;
  GV->setThreadLocalMode(TLS);
  return GV;
}

// Simple function name mangler.
// This function simply takes LLVM's string representation of parameter types
// and concatenate them with '_'. There are non-alphanumeric characters but llc
// is ok with it, and we need to postprocess these names after the lowering
// phase anyway.
static std::string getSignature(FunctionType *FTy) {
  std::string Sig;
  raw_string_ostream OS(Sig);
  OS << *FTy->getReturnType();
  for (Type *ParamTy : FTy->params())
    OS << "_" << *ParamTy;
  if (FTy->isVarArg())
    OS << "_...";
  Sig = OS.str();
  erase_if(Sig, isSpace);
  // When s2wasm parses .s file, a comma means the end of an argument. So a
  // mangled function name can contain any character but a comma.
  std::replace(Sig.begin(), Sig.end(), ',', '.');
  return Sig;
}

static Function *getEmscriptenFunction(FunctionType *Ty, const Twine &Name,
                                       Module *M) {
  Function* F = Function::Create(Ty, GlobalValue::ExternalLinkage, Name, M);
  // Tell the linker that this function is expected to be imported from the
  // 'env' module.
  if (!F->hasFnAttribute("wasm-import-module")) {
    llvm::AttrBuilder B;
    B.addAttribute("wasm-import-module", "env");
    F->addFnAttrs(B);
  }
  if (!F->hasFnAttribute("wasm-import-name")) {
    llvm::AttrBuilder B;
    B.addAttribute("wasm-import-name", F->getName());
    F->addFnAttrs(B);
  }
  return F;
}

// Returns an integer type for the target architecture's address space.
// i32 for wasm32 and i64 for wasm64.
static Type *getAddrIntType(Module *M) {
  IRBuilder<> IRB(M->getContext());
  return IRB.getIntNTy(M->getDataLayout().getPointerSizeInBits());
}

// Returns an integer pointer type for the target architecture's address space.
// i32* for wasm32 and i64* for wasm64.
static Type *getAddrPtrType(Module *M) {
  return Type::getIntNPtrTy(M->getContext(),
                            M->getDataLayout().getPointerSizeInBits());
}

// Returns an integer whose type is the integer type for the target's address
// space. Returns (i32 C) for wasm32 and (i64 C) for wasm64, when C is the
// integer.
static Value *getAddrSizeInt(Module *M, uint64_t C) {
  IRBuilder<> IRB(M->getContext());
  return IRB.getIntN(M->getDataLayout().getPointerSizeInBits(), C);
}

// Returns __cxa_find_matching_catch_N function, where N = NumClauses + 2.
// This is because a landingpad instruction contains two more arguments, a
// personality function and a cleanup bit, and __cxa_find_matching_catch_N
// functions are named after the number of arguments in the original landingpad
// instruction.
Function *
WebAssemblyLowerEmscriptenEHSjLj::getFindMatchingCatch(Module &M,
                                                       unsigned NumClauses) {
  if (FindMatchingCatches.count(NumClauses))
    return FindMatchingCatches[NumClauses];
  PointerType *Int8PtrTy = Type::getInt8PtrTy(M.getContext());
  SmallVector<Type *, 16> Args(NumClauses, Int8PtrTy);
  FunctionType *FTy = FunctionType::get(Int8PtrTy, Args, false);
  Function *F = getEmscriptenFunction(
      FTy, "__cxa_find_matching_catch_" + Twine(NumClauses + 2), &M);
  FindMatchingCatches[NumClauses] = F;
  return F;
}

// Generate invoke wrapper seqence with preamble and postamble
// Preamble:
// __THREW__ = 0;
// Postamble:
// %__THREW__.val = __THREW__; __THREW__ = 0;
// Returns %__THREW__.val, which indicates whether an exception is thrown (or
// whether longjmp occurred), for future use.
Value *WebAssemblyLowerEmscriptenEHSjLj::wrapInvoke(CallBase *CI) {
  Module *M = CI->getModule();
  LLVMContext &C = M->getContext();

  IRBuilder<> IRB(C);
  IRB.SetInsertPoint(CI);

  // Pre-invoke
  // __THREW__ = 0;
  IRB.CreateStore(getAddrSizeInt(M, 0), ThrewGV);

  // Invoke function wrapper in JavaScript
  SmallVector<Value *, 16> Args;
  // Put the pointer to the callee as first argument, so it can be called
  // within the invoke wrapper later
  Args.push_back(CI->getCalledOperand());
  Args.append(CI->arg_begin(), CI->arg_end());
  CallInst *NewCall = IRB.CreateCall(getInvokeWrapper(CI), Args);
  NewCall->takeName(CI);
  NewCall->setCallingConv(CallingConv::WASM_EmscriptenInvoke);
  NewCall->setDebugLoc(CI->getDebugLoc());

  // Because we added the pointer to the callee as first argument, all
  // argument attribute indices have to be incremented by one.
  SmallVector<AttributeSet, 8> ArgAttributes;
  const AttributeList &InvokeAL = CI->getAttributes();

  // No attributes for the callee pointer.
  ArgAttributes.push_back(AttributeSet());
  // Copy the argument attributes from the original
  for (unsigned I = 0, E = CI->arg_size(); I < E; ++I)
    ArgAttributes.push_back(InvokeAL.getParamAttrs(I));

  AttrBuilder FnAttrs(InvokeAL.getFnAttrs());
  if (FnAttrs.contains(Attribute::AllocSize)) {
    // The allocsize attribute (if any) referes to parameters by index and needs
    // to be adjusted.
    unsigned SizeArg;
    Optional<unsigned> NEltArg;
    std::tie(SizeArg, NEltArg) = FnAttrs.getAllocSizeArgs();
    SizeArg += 1;
    if (NEltArg.hasValue())
      NEltArg = NEltArg.getValue() + 1;
    FnAttrs.addAllocSizeAttr(SizeArg, NEltArg);
  }

  // Reconstruct the AttributesList based on the vector we constructed.
  AttributeList NewCallAL = AttributeList::get(
      C, AttributeSet::get(C, FnAttrs), InvokeAL.getRetAttrs(), ArgAttributes);
  NewCall->setAttributes(NewCallAL);

  CI->replaceAllUsesWith(NewCall);

  // Post-invoke
  // %__THREW__.val = __THREW__; __THREW__ = 0;
  Value *Threw =
      IRB.CreateLoad(getAddrIntType(M), ThrewGV, ThrewGV->getName() + ".val");
  IRB.CreateStore(getAddrSizeInt(M, 0), ThrewGV);
  return Threw;
}

// Get matching invoke wrapper based on callee signature
Function *WebAssemblyLowerEmscriptenEHSjLj::getInvokeWrapper(CallBase *CI) {
  Module *M = CI->getModule();
  SmallVector<Type *, 16> ArgTys;
  FunctionType *CalleeFTy = CI->getFunctionType();

  std::string Sig = getSignature(CalleeFTy);
  if (InvokeWrappers.find(Sig) != InvokeWrappers.end())
    return InvokeWrappers[Sig];

  // Put the pointer to the callee as first argument
  ArgTys.push_back(PointerType::getUnqual(CalleeFTy));
  // Add argument types
  ArgTys.append(CalleeFTy->param_begin(), CalleeFTy->param_end());

  FunctionType *FTy = FunctionType::get(CalleeFTy->getReturnType(), ArgTys,
                                        CalleeFTy->isVarArg());
  Function *F = getEmscriptenFunction(FTy, "__invoke_" + Sig, M);
  InvokeWrappers[Sig] = F;
  return F;
}

static bool canLongjmp(const Value *Callee) {
  if (auto *CalleeF = dyn_cast<Function>(Callee))
    if (CalleeF->isIntrinsic())
      return false;

  // Attempting to transform inline assembly will result in something like:
  //     call void @__invoke_void(void ()* asm ...)
  // which is invalid because inline assembly blocks do not have addresses
  // and can't be passed by pointer. The result is a crash with illegal IR.
  if (isa<InlineAsm>(Callee))
    return false;
  StringRef CalleeName = Callee->getName();

  // The reason we include malloc/free here is to exclude the malloc/free
  // calls generated in setjmp prep / cleanup routines.
  if (CalleeName == "setjmp" || CalleeName == "malloc" || CalleeName == "free")
    return false;

  // There are functions in Emscripten's JS glue code or compiler-rt
  if (CalleeName == "__resumeException" || CalleeName == "llvm_eh_typeid_for" ||
      CalleeName == "saveSetjmp" || CalleeName == "testSetjmp" ||
      CalleeName == "getTempRet0" || CalleeName == "setTempRet0")
    return false;

  // __cxa_find_matching_catch_N functions cannot longjmp
  if (Callee->getName().startswith("__cxa_find_matching_catch_"))
    return false;

  // Exception-catching related functions
  if (CalleeName == "__cxa_begin_catch" || CalleeName == "__cxa_end_catch" ||
      CalleeName == "__cxa_allocate_exception" || CalleeName == "__cxa_throw" ||
      CalleeName == "__clang_call_terminate")
    return false;

  // Otherwise we don't know
  return true;
}

static bool isEmAsmCall(const Value *Callee) {
  StringRef CalleeName = Callee->getName();
  // This is an exhaustive list from Emscripten's <emscripten/em_asm.h>.
  return CalleeName == "emscripten_asm_const_int" ||
         CalleeName == "emscripten_asm_const_double" ||
         CalleeName == "emscripten_asm_const_int_sync_on_main_thread" ||
         CalleeName == "emscripten_asm_const_double_sync_on_main_thread" ||
         CalleeName == "emscripten_asm_const_async_on_main_thread";
}

// Generate testSetjmp function call seqence with preamble and postamble.
// The code this generates is equivalent to the following JavaScript code:
// %__threwValue.val = __threwValue;
// if (%__THREW__.val != 0 & %__threwValue.val != 0) {
//   %label = testSetjmp(mem[%__THREW__.val], setjmpTable, setjmpTableSize);
//   if (%label == 0)
//     emscripten_longjmp(%__THREW__.val, %__threwValue.val);
//   setTempRet0(%__threwValue.val);
// } else {
//   %label = -1;
// }
// %longjmp_result = getTempRet0();
//
// As output parameters. returns %label, %longjmp_result, and the BB the last
// instruction (%longjmp_result = ...) is in.
void WebAssemblyLowerEmscriptenEHSjLj::wrapTestSetjmp(
    BasicBlock *BB, DebugLoc DL, Value *Threw, Value *SetjmpTable,
    Value *SetjmpTableSize, Value *&Label, Value *&LongjmpResult,
    BasicBlock *&CallEmLongjmpBB, PHINode *&CallEmLongjmpBBThrewPHI,
    PHINode *&CallEmLongjmpBBThrewValuePHI, BasicBlock *&EndBB) {
  Function *F = BB->getParent();
  Module *M = F->getParent();
  LLVMContext &C = M->getContext();
  IRBuilder<> IRB(C);
  IRB.SetCurrentDebugLocation(DL);

  // if (%__THREW__.val != 0 & %__threwValue.val != 0)
  IRB.SetInsertPoint(BB);
  BasicBlock *ThenBB1 = BasicBlock::Create(C, "if.then1", F);
  BasicBlock *ElseBB1 = BasicBlock::Create(C, "if.else1", F);
  BasicBlock *EndBB1 = BasicBlock::Create(C, "if.end", F);
  Value *ThrewCmp = IRB.CreateICmpNE(Threw, getAddrSizeInt(M, 0));
  Value *ThrewValue = IRB.CreateLoad(IRB.getInt32Ty(), ThrewValueGV,
                                     ThrewValueGV->getName() + ".val");
  Value *ThrewValueCmp = IRB.CreateICmpNE(ThrewValue, IRB.getInt32(0));
  Value *Cmp1 = IRB.CreateAnd(ThrewCmp, ThrewValueCmp, "cmp1");
  IRB.CreateCondBr(Cmp1, ThenBB1, ElseBB1);

  // Generate call.em.longjmp BB once and share it within the function
  if (!CallEmLongjmpBB) {
    // emscripten_longjmp(%__THREW__.val, %__threwValue.val);
    CallEmLongjmpBB = BasicBlock::Create(C, "call.em.longjmp", F);
    IRB.SetInsertPoint(CallEmLongjmpBB);
    CallEmLongjmpBBThrewPHI = IRB.CreatePHI(getAddrIntType(M), 4, "threw.phi");
    CallEmLongjmpBBThrewValuePHI =
        IRB.CreatePHI(IRB.getInt32Ty(), 4, "threwvalue.phi");
    CallEmLongjmpBBThrewPHI->addIncoming(Threw, ThenBB1);
    CallEmLongjmpBBThrewValuePHI->addIncoming(ThrewValue, ThenBB1);
    IRB.CreateCall(EmLongjmpF,
                   {CallEmLongjmpBBThrewPHI, CallEmLongjmpBBThrewValuePHI});
    IRB.CreateUnreachable();
  } else {
    CallEmLongjmpBBThrewPHI->addIncoming(Threw, ThenBB1);
    CallEmLongjmpBBThrewValuePHI->addIncoming(ThrewValue, ThenBB1);
  }

  // %label = testSetjmp(mem[%__THREW__.val], setjmpTable, setjmpTableSize);
  // if (%label == 0)
  IRB.SetInsertPoint(ThenBB1);
  BasicBlock *EndBB2 = BasicBlock::Create(C, "if.end2", F);
  Value *ThrewPtr =
      IRB.CreateIntToPtr(Threw, getAddrPtrType(M), Threw->getName() + ".p");
  Value *LoadedThrew = IRB.CreateLoad(getAddrIntType(M), ThrewPtr,
                                      ThrewPtr->getName() + ".loaded");
  Value *ThenLabel = IRB.CreateCall(
      TestSetjmpF, {LoadedThrew, SetjmpTable, SetjmpTableSize}, "label");
  Value *Cmp2 = IRB.CreateICmpEQ(ThenLabel, IRB.getInt32(0));
  IRB.CreateCondBr(Cmp2, CallEmLongjmpBB, EndBB2);

  // setTempRet0(%__threwValue.val);
  IRB.SetInsertPoint(EndBB2);
  IRB.CreateCall(SetTempRet0F, ThrewValue);
  IRB.CreateBr(EndBB1);

  IRB.SetInsertPoint(ElseBB1);
  IRB.CreateBr(EndBB1);

  // longjmp_result = getTempRet0();
  IRB.SetInsertPoint(EndBB1);
  PHINode *LabelPHI = IRB.CreatePHI(IRB.getInt32Ty(), 2, "label");
  LabelPHI->addIncoming(ThenLabel, EndBB2);

  LabelPHI->addIncoming(IRB.getInt32(-1), ElseBB1);

  // Output parameter assignment
  Label = LabelPHI;
  EndBB = EndBB1;
  LongjmpResult = IRB.CreateCall(GetTempRet0F, None, "longjmp_result");
}

void WebAssemblyLowerEmscriptenEHSjLj::rebuildSSA(Function &F) {
  DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
  DT.recalculate(F); // CFG has been changed

  SSAUpdaterBulk SSA;
  for (BasicBlock &BB : F) {
    for (Instruction &I : BB) {
      unsigned VarID = SSA.AddVariable(I.getName(), I.getType());
      // If a value is defined by an invoke instruction, it is only available in
      // its normal destination and not in its unwind destination.
      if (auto *II = dyn_cast<InvokeInst>(&I))
        SSA.AddAvailableValue(VarID, II->getNormalDest(), II);
      else
        SSA.AddAvailableValue(VarID, &BB, &I);
      for (auto &U : I.uses()) {
        auto *User = cast<Instruction>(U.getUser());
        if (auto *UserPN = dyn_cast<PHINode>(User))
          if (UserPN->getIncomingBlock(U) == &BB)
            continue;
        if (DT.dominates(&I, User))
          continue;
        SSA.AddUse(VarID, &U);
      }
    }
  }
  SSA.RewriteAllUses(&DT);
}

// Replace uses of longjmp with a new longjmp function in Emscripten library.
// In Emscripten SjLj, the new function is
//   void emscripten_longjmp(uintptr_t, i32)
// In Wasm SjLj, the new function is
//   void __wasm_longjmp(i8*, i32)
// Because the original libc longjmp function takes (jmp_buf*, i32), we need a
// ptrtoint/bitcast instruction here to make the type match. jmp_buf* will
// eventually be lowered to i32/i64 in the wasm backend.
void WebAssemblyLowerEmscriptenEHSjLj::replaceLongjmpWith(Function *LongjmpF,
                                                          Function *NewF) {
  assert(NewF == EmLongjmpF || NewF == WasmLongjmpF);
  Module *M = LongjmpF->getParent();
  SmallVector<CallInst *, 8> ToErase;
  LLVMContext &C = LongjmpF->getParent()->getContext();
  IRBuilder<> IRB(C);

  // For calls to longjmp, replace it with emscripten_longjmp/__wasm_longjmp and
  // cast its first argument (jmp_buf*) appropriately
  for (User *U : LongjmpF->users()) {
    auto *CI = dyn_cast<CallInst>(U);
    if (CI && CI->getCalledFunction() == LongjmpF) {
      IRB.SetInsertPoint(CI);
      Value *Env = nullptr;
      if (NewF == EmLongjmpF)
        Env =
            IRB.CreatePtrToInt(CI->getArgOperand(0), getAddrIntType(M), "env");
      else // WasmLongjmpF
        Env =
            IRB.CreateBitCast(CI->getArgOperand(0), IRB.getInt8PtrTy(), "env");
      IRB.CreateCall(NewF, {Env, CI->getArgOperand(1)});
      ToErase.push_back(CI);
    }
  }
  for (auto *I : ToErase)
    I->eraseFromParent();

  // If we have any remaining uses of longjmp's function pointer, replace it
  // with (void(*)(jmp_buf*, int))emscripten_longjmp / __wasm_longjmp.
  if (!LongjmpF->uses().empty()) {
    Value *NewLongjmp =
        IRB.CreateBitCast(NewF, LongjmpF->getType(), "longjmp.cast");
    LongjmpF->replaceAllUsesWith(NewLongjmp);
  }
}

static bool containsLongjmpableCalls(const Function *F) {
  for (const auto &BB : *F)
    for (const auto &I : BB)
      if (const auto *CB = dyn_cast<CallBase>(&I))
        if (canLongjmp(CB->getCalledOperand()))
          return true;
  return false;
}

bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
  LLVM_DEBUG(dbgs() << "********** Lower Emscripten EH & SjLj **********\n");

  LLVMContext &C = M.getContext();
  IRBuilder<> IRB(C);

  Function *SetjmpF = M.getFunction("setjmp");
  Function *LongjmpF = M.getFunction("longjmp");

  // In some platforms _setjmp and _longjmp are used instead. Change these to
  // use setjmp/longjmp instead, because we later detect these functions by
  // their names.
  Function *SetjmpF2 = M.getFunction("_setjmp");
  Function *LongjmpF2 = M.getFunction("_longjmp");
  if (SetjmpF2) {
    if (SetjmpF) {
      if (SetjmpF->getFunctionType() != SetjmpF2->getFunctionType())
        report_fatal_error("setjmp and _setjmp have different function types");
    } else {
      SetjmpF = Function::Create(SetjmpF2->getFunctionType(),
                                 GlobalValue::ExternalLinkage, "setjmp", M);
    }
    SetjmpF2->replaceAllUsesWith(SetjmpF);
  }
  if (LongjmpF2) {
    if (LongjmpF) {
      if (LongjmpF->getFunctionType() != LongjmpF2->getFunctionType())
        report_fatal_error(
            "longjmp and _longjmp have different function types");
    } else {
      LongjmpF = Function::Create(LongjmpF2->getFunctionType(),
                                  GlobalValue::ExternalLinkage, "setjmp", M);
    }
    LongjmpF2->replaceAllUsesWith(LongjmpF);
  }

  auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
  assert(TPC && "Expected a TargetPassConfig");
  auto &TM = TPC->getTM<WebAssemblyTargetMachine>();

  // Declare (or get) global variables __THREW__, __threwValue, and
  // getTempRet0/setTempRet0 function which are used in common for both
  // exception handling and setjmp/longjmp handling
  ThrewGV = getGlobalVariable(M, getAddrIntType(&M), TM, "__THREW__");
  ThrewValueGV = getGlobalVariable(M, IRB.getInt32Ty(), TM, "__threwValue");
  GetTempRet0F = getEmscriptenFunction(
      FunctionType::get(IRB.getInt32Ty(), false), "getTempRet0", &M);
  SetTempRet0F = getEmscriptenFunction(
      FunctionType::get(IRB.getVoidTy(), IRB.getInt32Ty(), false),
      "setTempRet0", &M);
  GetTempRet0F->setDoesNotThrow();
  SetTempRet0F->setDoesNotThrow();

  bool Changed = false;

  // Function registration for exception handling
  if (EnableEmEH) {
    // Register __resumeException function
    FunctionType *ResumeFTy =
        FunctionType::get(IRB.getVoidTy(), IRB.getInt8PtrTy(), false);
    ResumeF = getEmscriptenFunction(ResumeFTy, "__resumeException", &M);
    ResumeF->addFnAttr(Attribute::NoReturn);

    // Register llvm_eh_typeid_for function
    FunctionType *EHTypeIDTy =
        FunctionType::get(IRB.getInt32Ty(), IRB.getInt8PtrTy(), false);
    EHTypeIDF = getEmscriptenFunction(EHTypeIDTy, "llvm_eh_typeid_for", &M);
  }

  if ((EnableEmSjLj || EnableWasmSjLj) && SetjmpF) {
    // Precompute setjmp users
    for (User *U : SetjmpF->users()) {
      if (auto *CB = dyn_cast<CallBase>(U)) {
        auto *UserF = CB->getFunction();
        // If a function that calls setjmp does not contain any other calls that
        // can longjmp, we don't need to do any transformation on that function,
        // so can ignore it
        if (containsLongjmpableCalls(UserF))
          SetjmpUsers.insert(UserF);
      } else {
        std::string S;
        raw_string_ostream SS(S);
        SS << *U;
        report_fatal_error(Twine("Indirect use of setjmp is not supported: ") +
                           SS.str());
      }
    }
  }

  bool SetjmpUsed = SetjmpF && !SetjmpUsers.empty();
  bool LongjmpUsed = LongjmpF && !LongjmpF->use_empty();
  DoSjLj = (EnableEmSjLj | EnableWasmSjLj) && (SetjmpUsed || LongjmpUsed);

  // Function registration and data pre-gathering for setjmp/longjmp handling
  if (DoSjLj) {
    assert(EnableEmSjLj || EnableWasmSjLj);
    if (EnableEmSjLj) {
      // Register emscripten_longjmp function
      FunctionType *FTy = FunctionType::get(
          IRB.getVoidTy(), {getAddrIntType(&M), IRB.getInt32Ty()}, false);
      EmLongjmpF = getEmscriptenFunction(FTy, "emscripten_longjmp", &M);
      EmLongjmpF->addFnAttr(Attribute::NoReturn);
    } else { // EnableWasmSjLj
      // Register __wasm_longjmp function, which calls __builtin_wasm_longjmp.
      FunctionType *FTy = FunctionType::get(
          IRB.getVoidTy(), {IRB.getInt8PtrTy(), IRB.getInt32Ty()}, false);
      WasmLongjmpF = getEmscriptenFunction(FTy, "__wasm_longjmp", &M);
      WasmLongjmpF->addFnAttr(Attribute::NoReturn);
    }

    if (SetjmpF) {
      // Register saveSetjmp function
      FunctionType *SetjmpFTy = SetjmpF->getFunctionType();
      FunctionType *FTy =
          FunctionType::get(Type::getInt32PtrTy(C),
                            {SetjmpFTy->getParamType(0), IRB.getInt32Ty(),
                             Type::getInt32PtrTy(C), IRB.getInt32Ty()},
                            false);
      SaveSetjmpF = getEmscriptenFunction(FTy, "saveSetjmp", &M);

      // Register testSetjmp function
      FTy = FunctionType::get(
          IRB.getInt32Ty(),
          {getAddrIntType(&M), Type::getInt32PtrTy(C), IRB.getInt32Ty()},
          false);
      TestSetjmpF = getEmscriptenFunction(FTy, "testSetjmp", &M);

      // wasm.catch() will be lowered down to wasm 'catch' instruction in
      // instruction selection.
      CatchF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_catch);
      // Type for struct __WasmLongjmpArgs
      LongjmpArgsTy = StructType::get(IRB.getInt8PtrTy(), // env
                                      IRB.getInt32Ty()    // val
      );
    }
  }

  // Exception handling transformation
  if (EnableEmEH) {
    for (Function &F : M) {
      if (F.isDeclaration())
        continue;
      Changed |= runEHOnFunction(F);
    }
  }

  // Setjmp/longjmp handling transformation
  if (DoSjLj) {
    Changed = true; // We have setjmp or longjmp somewhere
    if (LongjmpF)
      replaceLongjmpWith(LongjmpF, EnableEmSjLj ? EmLongjmpF : WasmLongjmpF);
    // Only traverse functions that uses setjmp in order not to insert
    // unnecessary prep / cleanup code in every function
    if (SetjmpF)
      for (Function *F : SetjmpUsers)
        runSjLjOnFunction(*F);
  }

  if (!Changed) {
    // Delete unused global variables and functions
    if (ResumeF)
      ResumeF->eraseFromParent();
    if (EHTypeIDF)
      EHTypeIDF->eraseFromParent();
    if (EmLongjmpF)
      EmLongjmpF->eraseFromParent();
    if (SaveSetjmpF)
      SaveSetjmpF->eraseFromParent();
    if (TestSetjmpF)
      TestSetjmpF->eraseFromParent();
    return false;
  }

  return true;
}

bool WebAssemblyLowerEmscriptenEHSjLj::runEHOnFunction(Function &F) {
  Module &M = *F.getParent();
  LLVMContext &C = F.getContext();
  IRBuilder<> IRB(C);
  bool Changed = false;
  SmallVector<Instruction *, 64> ToErase;
  SmallPtrSet<LandingPadInst *, 32> LandingPads;

  // rethrow.longjmp BB that will be shared within the function.
  BasicBlock *RethrowLongjmpBB = nullptr;
  // PHI node for the loaded value of __THREW__ global variable in
  // rethrow.longjmp BB
  PHINode *RethrowLongjmpBBThrewPHI = nullptr;

  for (BasicBlock &BB : F) {
    auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
    if (!II)
      continue;
    Changed = true;
    LandingPads.insert(II->getLandingPadInst());
    IRB.SetInsertPoint(II);

    const Value *Callee = II->getCalledOperand();
    bool NeedInvoke = supportsException(&F) && canThrow(Callee);
    if (NeedInvoke) {
      // Wrap invoke with invoke wrapper and generate preamble/postamble
      Value *Threw = wrapInvoke(II);
      ToErase.push_back(II);

      // If setjmp/longjmp handling is enabled, the thrown value can be not an
      // exception but a longjmp. If the current function contains calls to
      // setjmp, it will be appropriately handled in runSjLjOnFunction. But even
      // if the function does not contain setjmp calls, we shouldn't silently
      // ignore longjmps; we should rethrow them so they can be correctly
      // handled in somewhere up the call chain where setjmp is. __THREW__'s
      // value is 0 when nothing happened, 1 when an exception is thrown, and
      // other values when longjmp is thrown.
      //
      // if (%__THREW__.val == 0 || %__THREW__.val == 1)
      //   goto %tail
      // else
      //   goto %longjmp.rethrow
      //
      // rethrow.longjmp: ;; This is longjmp. Rethrow it
      //   %__threwValue.val = __threwValue
      //   emscripten_longjmp(%__THREW__.val, %__threwValue.val);
      //
      // tail: ;; Nothing happened or an exception is thrown
      //   ... Continue exception handling ...
      if (DoSjLj && EnableEmSjLj && !SetjmpUsers.count(&F) &&
          canLongjmp(Callee)) {
        // Create longjmp.rethrow BB once and share it within the function
        if (!RethrowLongjmpBB) {
          RethrowLongjmpBB = BasicBlock::Create(C, "rethrow.longjmp", &F);
          IRB.SetInsertPoint(RethrowLongjmpBB);
          RethrowLongjmpBBThrewPHI =
              IRB.CreatePHI(getAddrIntType(&M), 4, "threw.phi");
          RethrowLongjmpBBThrewPHI->addIncoming(Threw, &BB);
          Value *ThrewValue = IRB.CreateLoad(IRB.getInt32Ty(), ThrewValueGV,
                                             ThrewValueGV->getName() + ".val");
          IRB.CreateCall(EmLongjmpF, {RethrowLongjmpBBThrewPHI, ThrewValue});
          IRB.CreateUnreachable();
        } else {
          RethrowLongjmpBBThrewPHI->addIncoming(Threw, &BB);
        }

        IRB.SetInsertPoint(II); // Restore the insert point back
        BasicBlock *Tail = BasicBlock::Create(C, "tail", &F);
        Value *CmpEqOne =
            IRB.CreateICmpEQ(Threw, getAddrSizeInt(&M, 1), "cmp.eq.one");
        Value *CmpEqZero =
            IRB.CreateICmpEQ(Threw, getAddrSizeInt(&M, 0), "cmp.eq.zero");
        Value *Or = IRB.CreateOr(CmpEqZero, CmpEqOne, "or");
        IRB.CreateCondBr(Or, Tail, RethrowLongjmpBB);
        IRB.SetInsertPoint(Tail);
        BB.replaceSuccessorsPhiUsesWith(&BB, Tail);
      }

      // Insert a branch based on __THREW__ variable
      Value *Cmp = IRB.CreateICmpEQ(Threw, getAddrSizeInt(&M, 1), "cmp");
      IRB.CreateCondBr(Cmp, II->getUnwindDest(), II->getNormalDest());

    } else {
      // This can't throw, and we don't need this invoke, just replace it with a
      // call+branch
      SmallVector<Value *, 16> Args(II->args());
      CallInst *NewCall =
          IRB.CreateCall(II->getFunctionType(), II->getCalledOperand(), Args);
      NewCall->takeName(II);
      NewCall->setCallingConv(II->getCallingConv());
      NewCall->setDebugLoc(II->getDebugLoc());
      NewCall->setAttributes(II->getAttributes());
      II->replaceAllUsesWith(NewCall);
      ToErase.push_back(II);

      IRB.CreateBr(II->getNormalDest());

      // Remove any PHI node entries from the exception destination
      II->getUnwindDest()->removePredecessor(&BB);
    }
  }

  // Process resume instructions
  for (BasicBlock &BB : F) {
    // Scan the body of the basic block for resumes
    for (Instruction &I : BB) {
      auto *RI = dyn_cast<ResumeInst>(&I);
      if (!RI)
        continue;
      Changed = true;

      // Split the input into legal values
      Value *Input = RI->getValue();
      IRB.SetInsertPoint(RI);
      Value *Low = IRB.CreateExtractValue(Input, 0, "low");
      // Create a call to __resumeException function
      IRB.CreateCall(ResumeF, {Low});
      // Add a terminator to the block
      IRB.CreateUnreachable();
      ToErase.push_back(RI);
    }
  }

  // Process llvm.eh.typeid.for intrinsics
  for (BasicBlock &BB : F) {
    for (Instruction &I : BB) {
      auto *CI = dyn_cast<CallInst>(&I);
      if (!CI)
        continue;
      const Function *Callee = CI->getCalledFunction();
      if (!Callee)
        continue;
      if (Callee->getIntrinsicID() != Intrinsic::eh_typeid_for)
        continue;
      Changed = true;

      IRB.SetInsertPoint(CI);
      CallInst *NewCI =
          IRB.CreateCall(EHTypeIDF, CI->getArgOperand(0), "typeid");
      CI->replaceAllUsesWith(NewCI);
      ToErase.push_back(CI);
    }
  }

  // Look for orphan landingpads, can occur in blocks with no predecessors
  for (BasicBlock &BB : F) {
    Instruction *I = BB.getFirstNonPHI();
    if (auto *LPI = dyn_cast<LandingPadInst>(I))
      LandingPads.insert(LPI);
  }
  Changed |= !LandingPads.empty();

  // Handle all the landingpad for this function together, as multiple invokes
  // may share a single lp
  for (LandingPadInst *LPI : LandingPads) {
    IRB.SetInsertPoint(LPI);
    SmallVector<Value *, 16> FMCArgs;
    for (unsigned I = 0, E = LPI->getNumClauses(); I < E; ++I) {
      Constant *Clause = LPI->getClause(I);
      // TODO Handle filters (= exception specifications).
      // https://bugs.llvm.org/show_bug.cgi?id=50396
      if (LPI->isCatch(I))
        FMCArgs.push_back(Clause);
    }

    // Create a call to __cxa_find_matching_catch_N function
    Function *FMCF = getFindMatchingCatch(M, FMCArgs.size());
    CallInst *FMCI = IRB.CreateCall(FMCF, FMCArgs, "fmc");
    Value *Undef = UndefValue::get(LPI->getType());
    Value *Pair0 = IRB.CreateInsertValue(Undef, FMCI, 0, "pair0");
    Value *TempRet0 = IRB.CreateCall(GetTempRet0F, None, "tempret0");
    Value *Pair1 = IRB.CreateInsertValue(Pair0, TempRet0, 1, "pair1");

    LPI->replaceAllUsesWith(Pair1);
    ToErase.push_back(LPI);
  }

  // Erase everything we no longer need in this function
  for (Instruction *I : ToErase)
    I->eraseFromParent();

  return Changed;
}

// This tries to get debug info from the instruction before which a new
// instruction will be inserted, and if there's no debug info in that
// instruction, tries to get the info instead from the previous instruction (if
// any). If none of these has debug info and a DISubprogram is provided, it
// creates a dummy debug info with the first line of the function, because IR
// verifier requires all inlinable callsites should have debug info when both a
// caller and callee have DISubprogram. If none of these conditions are met,
// returns empty info.
static DebugLoc getOrCreateDebugLoc(const Instruction *InsertBefore,
                                    DISubprogram *SP) {
  assert(InsertBefore);
  if (InsertBefore->getDebugLoc())
    return InsertBefore->getDebugLoc();
  const Instruction *Prev = InsertBefore->getPrevNode();
  if (Prev && Prev->getDebugLoc())
    return Prev->getDebugLoc();
  if (SP)
    return DILocation::get(SP->getContext(), SP->getLine(), 1, SP);
  return DebugLoc();
}

bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
  assert(EnableEmSjLj || EnableWasmSjLj);
  Module &M = *F.getParent();
  LLVMContext &C = F.getContext();
  IRBuilder<> IRB(C);
  SmallVector<Instruction *, 64> ToErase;
  // Vector of %setjmpTable values
  SmallVector<Instruction *, 4> SetjmpTableInsts;
  // Vector of %setjmpTableSize values
  SmallVector<Instruction *, 4> SetjmpTableSizeInsts;

  // Setjmp preparation

  // This instruction effectively means %setjmpTableSize = 4.
  // We create this as an instruction intentionally, and we don't want to fold
  // this instruction to a constant 4, because this value will be used in
  // SSAUpdater.AddAvailableValue(...) later.
  BasicBlock *Entry = &F.getEntryBlock();
  DebugLoc FirstDL = getOrCreateDebugLoc(&*Entry->begin(), F.getSubprogram());
  SplitBlock(Entry, &*Entry->getFirstInsertionPt());

  BinaryOperator *SetjmpTableSize =
      BinaryOperator::Create(Instruction::Add, IRB.getInt32(4), IRB.getInt32(0),
                             "setjmpTableSize", Entry->getTerminator());
  SetjmpTableSize->setDebugLoc(FirstDL);
  // setjmpTable = (int *) malloc(40);
  Instruction *SetjmpTable = CallInst::CreateMalloc(
      SetjmpTableSize, IRB.getInt32Ty(), IRB.getInt32Ty(), IRB.getInt32(40),
      nullptr, nullptr, "setjmpTable");
  SetjmpTable->setDebugLoc(FirstDL);
  // CallInst::CreateMalloc may return a bitcast instruction if the result types
  // mismatch. We need to set the debug loc for the original call too.
  auto *MallocCall = SetjmpTable->stripPointerCasts();
  if (auto *MallocCallI = dyn_cast<Instruction>(MallocCall)) {
    MallocCallI->setDebugLoc(FirstDL);
  }
  // setjmpTable[0] = 0;
  IRB.SetInsertPoint(SetjmpTableSize);
  IRB.CreateStore(IRB.getInt32(0), SetjmpTable);
  SetjmpTableInsts.push_back(SetjmpTable);
  SetjmpTableSizeInsts.push_back(SetjmpTableSize);

  // Setjmp transformation
  SmallVector<PHINode *, 4> SetjmpRetPHIs;
  Function *SetjmpF = M.getFunction("setjmp");
  for (User *U : SetjmpF->users()) {
    auto *CI = dyn_cast<CallInst>(U);
    // FIXME 'invoke' to setjmp can happen when we use Wasm EH + Wasm SjLj, but
    // we don't support two being used together yet.
    if (!CI)
      report_fatal_error("Wasm EH + Wasm SjLj is not fully supported yet");
    BasicBlock *BB = CI->getParent();
    if (BB->getParent() != &F) // in other function
      continue;

    // The tail is everything right after the call, and will be reached once
    // when setjmp is called, and later when longjmp returns to the setjmp
    BasicBlock *Tail = SplitBlock(BB, CI->getNextNode());
    // Add a phi to the tail, which will be the output of setjmp, which
    // indicates if this is the first call or a longjmp back. The phi directly
    // uses the right value based on where we arrive from
    IRB.SetInsertPoint(Tail->getFirstNonPHI());
    PHINode *SetjmpRet = IRB.CreatePHI(IRB.getInt32Ty(), 2, "setjmp.ret");

    // setjmp initial call returns 0
    SetjmpRet->addIncoming(IRB.getInt32(0), BB);
    // The proper output is now this, not the setjmp call itself
    CI->replaceAllUsesWith(SetjmpRet);
    // longjmp returns to the setjmp will add themselves to this phi
    SetjmpRetPHIs.push_back(SetjmpRet);

    // Fix call target
    // Our index in the function is our place in the array + 1 to avoid index
    // 0, because index 0 means the longjmp is not ours to handle.
    IRB.SetInsertPoint(CI);
    Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),
                     SetjmpTable, SetjmpTableSize};
    Instruction *NewSetjmpTable =
        IRB.CreateCall(SaveSetjmpF, Args, "setjmpTable");
    Instruction *NewSetjmpTableSize =
        IRB.CreateCall(GetTempRet0F, None, "setjmpTableSize");
    SetjmpTableInsts.push_back(NewSetjmpTable);
    SetjmpTableSizeInsts.push_back(NewSetjmpTableSize);
    ToErase.push_back(CI);
  }

  // Handle longjmpable calls.
  if (EnableEmSjLj)
    handleLongjmpableCallsForEmscriptenSjLj(
        F, SetjmpTableInsts, SetjmpTableSizeInsts, SetjmpRetPHIs);
  else // EnableWasmSjLj
    handleLongjmpableCallsForWasmSjLj(F, SetjmpTableInsts, SetjmpTableSizeInsts,
                                      SetjmpRetPHIs);

  // Erase everything we no longer need in this function
  for (Instruction *I : ToErase)
    I->eraseFromParent();

  // Free setjmpTable buffer before each return instruction + function-exiting
  // call
  SmallVector<Instruction *, 16> ExitingInsts;
  for (BasicBlock &BB : F) {
    Instruction *TI = BB.getTerminator();
    if (isa<ReturnInst>(TI))
      ExitingInsts.push_back(TI);
    // Any 'call' instruction with 'noreturn' attribute exits the function at
    // this point. If this throws but unwinds to another EH pad within this
    // function instead of exiting, this would have been an 'invoke', which
    // happens if we use Wasm EH or Wasm SjLJ.
    for (auto &I : BB) {
      if (auto *CI = dyn_cast<CallInst>(&I)) {
        bool IsNoReturn = CI->hasFnAttr(Attribute::NoReturn);
        if (Function *CalleeF = CI->getCalledFunction())
          IsNoReturn |= CalleeF->hasFnAttribute(Attribute::NoReturn);
        if (IsNoReturn)
          ExitingInsts.push_back(&I);
      }
    }
  }
  for (auto *I : ExitingInsts) {
    DebugLoc DL = getOrCreateDebugLoc(I, F.getSubprogram());
    // If this existing instruction is a call within a catchpad, we should add
    // it as "funclet" to the operand bundle of 'free' call
    SmallVector<OperandBundleDef, 1> Bundles;
    if (auto *CB = dyn_cast<CallBase>(I))
      if (auto Bundle = CB->getOperandBundle(LLVMContext::OB_funclet))
        Bundles.push_back(OperandBundleDef(*Bundle));
    auto *Free = CallInst::CreateFree(SetjmpTable, Bundles, I);
    Free->setDebugLoc(DL);
    // CallInst::CreateFree may create a bitcast instruction if its argument
    // types mismatch. We need to set the debug loc for the bitcast too.
    if (auto *FreeCallI = dyn_cast<CallInst>(Free)) {
      if (auto *BitCastI = dyn_cast<BitCastInst>(FreeCallI->getArgOperand(0)))
        BitCastI->setDebugLoc(DL);
    }
  }

  // Every call to saveSetjmp can change setjmpTable and setjmpTableSize
  // (when buffer reallocation occurs)
  // entry:
  //   setjmpTableSize = 4;
  //   setjmpTable = (int *) malloc(40);
  //   setjmpTable[0] = 0;
  // ...
  // somebb:
  //   setjmpTable = saveSetjmp(env, label, setjmpTable, setjmpTableSize);
  //   setjmpTableSize = getTempRet0();
  // So we need to make sure the SSA for these variables is valid so that every
  // saveSetjmp and testSetjmp calls have the correct arguments.
  SSAUpdater SetjmpTableSSA;
  SSAUpdater SetjmpTableSizeSSA;
  SetjmpTableSSA.Initialize(Type::getInt32PtrTy(C), "setjmpTable");
  SetjmpTableSizeSSA.Initialize(Type::getInt32Ty(C), "setjmpTableSize");
  for (Instruction *I : SetjmpTableInsts)
    SetjmpTableSSA.AddAvailableValue(I->getParent(), I);
  for (Instruction *I : SetjmpTableSizeInsts)
    SetjmpTableSizeSSA.AddAvailableValue(I->getParent(), I);

  for (auto &U : make_early_inc_range(SetjmpTable->uses()))
    if (auto *I = dyn_cast<Instruction>(U.getUser()))
      if (I->getParent() != Entry)
        SetjmpTableSSA.RewriteUse(U);
  for (auto &U : make_early_inc_range(SetjmpTableSize->uses()))
    if (auto *I = dyn_cast<Instruction>(U.getUser()))
      if (I->getParent() != Entry)
        SetjmpTableSizeSSA.RewriteUse(U);

  // Finally, our modifications to the cfg can break dominance of SSA variables.
  // For example, in this code,
  // if (x()) { .. setjmp() .. }
  // if (y()) { .. longjmp() .. }
  // We must split the longjmp block, and it can jump into the block splitted
  // from setjmp one. But that means that when we split the setjmp block, it's
  // first part no longer dominates its second part - there is a theoretically
  // possible control flow path where x() is false, then y() is true and we
  // reach the second part of the setjmp block, without ever reaching the first
  // part. So, we rebuild SSA form here.
  rebuildSSA(F);
  return true;
}

// Update each call that can longjmp so it can return to the corresponding
// setjmp. Refer to 4) of "Emscripten setjmp/longjmp handling" section in the
// comments at top of the file for details.
void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForEmscriptenSjLj(
    Function &F, InstVector &SetjmpTableInsts, InstVector &SetjmpTableSizeInsts,
    SmallVectorImpl<PHINode *> &SetjmpRetPHIs) {
  Module &M = *F.getParent();
  LLVMContext &C = F.getContext();
  IRBuilder<> IRB(C);
  SmallVector<Instruction *, 64> ToErase;

  // We need to pass setjmpTable and setjmpTableSize to testSetjmp function.
  // These values are defined in the beginning of the function and also in each
  // setjmp callsite, but we don't know which values we should use at this
  // point. So here we arbitraily use the ones defined in the beginning of the
  // function, and SSAUpdater will later update them to the correct values.
  Instruction *SetjmpTable = *SetjmpTableInsts.begin();
  Instruction *SetjmpTableSize = *SetjmpTableSizeInsts.begin();

  // call.em.longjmp BB that will be shared within the function.
  BasicBlock *CallEmLongjmpBB = nullptr;
  // PHI node for the loaded value of __THREW__ global variable in
  // call.em.longjmp BB
  PHINode *CallEmLongjmpBBThrewPHI = nullptr;
  // PHI node for the loaded value of __threwValue global variable in
  // call.em.longjmp BB
  PHINode *CallEmLongjmpBBThrewValuePHI = nullptr;
  // rethrow.exn BB that will be shared within the function.
  BasicBlock *RethrowExnBB = nullptr;

  // Because we are creating new BBs while processing and don't want to make
  // all these newly created BBs candidates again for longjmp processing, we
  // first make the vector of candidate BBs.
  std::vector<BasicBlock *> BBs;
  for (BasicBlock &BB : F)
    BBs.push_back(&BB);

  // BBs.size() will change within the loop, so we query it every time
  for (unsigned I = 0; I < BBs.size(); I++) {
    BasicBlock *BB = BBs[I];
    for (Instruction &I : *BB) {
      if (isa<InvokeInst>(&I))
        report_fatal_error("When using Wasm EH with Emscripten SjLj, there is "
                           "a restriction that `setjmp` function call and "
                           "exception cannot be used within the same function");
      auto *CI = dyn_cast<CallInst>(&I);
      if (!CI)
        continue;

      const Value *Callee = CI->getCalledOperand();
      if (!canLongjmp(Callee))
        continue;
      if (isEmAsmCall(Callee))
        report_fatal_error("Cannot use EM_ASM* alongside setjmp/longjmp in " +
                               F.getName() +
                               ". Please consider using EM_JS, or move the "
                               "EM_ASM into another function.",
                           false);

      Value *Threw = nullptr;
      BasicBlock *Tail;
      if (Callee->getName().startswith("__invoke_")) {
        // If invoke wrapper has already been generated for this call in
        // previous EH phase, search for the load instruction
        // %__THREW__.val = __THREW__;
        // in postamble after the invoke wrapper call
        LoadInst *ThrewLI = nullptr;
        StoreInst *ThrewResetSI = nullptr;
        for (auto I = std::next(BasicBlock::iterator(CI)), IE = BB->end();
             I != IE; ++I) {
          if (auto *LI = dyn_cast<LoadInst>(I))
            if (auto *GV = dyn_cast<GlobalVariable>(LI->getPointerOperand()))
              if (GV == ThrewGV) {
                Threw = ThrewLI = LI;
                break;
              }
        }
        // Search for the store instruction after the load above
        // __THREW__ = 0;
        for (auto I = std::next(BasicBlock::iterator(ThrewLI)), IE = BB->end();
             I != IE; ++I) {
          if (auto *SI = dyn_cast<StoreInst>(I)) {
            if (auto *GV = dyn_cast<GlobalVariable>(SI->getPointerOperand())) {
              if (GV == ThrewGV &&
                  SI->getValueOperand() == getAddrSizeInt(&M, 0)) {
                ThrewResetSI = SI;
                break;
              }
            }
          }
        }
        assert(Threw && ThrewLI && "Cannot find __THREW__ load after invoke");
        assert(ThrewResetSI && "Cannot find __THREW__ store after invoke");
        Tail = SplitBlock(BB, ThrewResetSI->getNextNode());

      } else {
        // Wrap call with invoke wrapper and generate preamble/postamble
        Threw = wrapInvoke(CI);
        ToErase.push_back(CI);
        Tail = SplitBlock(BB, CI->getNextNode());

        // If exception handling is enabled, the thrown value can be not a
        // longjmp but an exception, in which case we shouldn't silently ignore
        // exceptions; we should rethrow them.
        // __THREW__'s value is 0 when nothing happened, 1 when an exception is
        // thrown, other values when longjmp is thrown.
        //
        // if (%__THREW__.val == 1)
        //   goto %eh.rethrow
        // else
        //   goto %normal
        //
        // eh.rethrow: ;; Rethrow exception
        //   %exn = call @__cxa_find_matching_catch_2() ;; Retrieve thrown ptr
        //   __resumeException(%exn)
        //
        // normal:
        //   <-- Insertion point. Will insert sjlj handling code from here
        //   goto %tail
        //
        // tail:
        //   ...
        if (supportsException(&F) && canThrow(Callee)) {
          // We will add a new conditional branch. So remove the branch created
          // when we split the BB
          ToErase.push_back(BB->getTerminator());

          // Generate rethrow.exn BB once and share it within the function
          if (!RethrowExnBB) {
            RethrowExnBB = BasicBlock::Create(C, "rethrow.exn", &F);
            IRB.SetInsertPoint(RethrowExnBB);
            CallInst *Exn =
                IRB.CreateCall(getFindMatchingCatch(M, 0), {}, "exn");
            IRB.CreateCall(ResumeF, {Exn});
            IRB.CreateUnreachable();
          }

          IRB.SetInsertPoint(CI);
          BasicBlock *NormalBB = BasicBlock::Create(C, "normal", &F);
          Value *CmpEqOne =
              IRB.CreateICmpEQ(Threw, getAddrSizeInt(&M, 1), "cmp.eq.one");
          IRB.CreateCondBr(CmpEqOne, RethrowExnBB, NormalBB);

          IRB.SetInsertPoint(NormalBB);
          IRB.CreateBr(Tail);
          BB = NormalBB; // New insertion point to insert testSetjmp()
        }
      }

      // We need to replace the terminator in Tail - SplitBlock makes BB go
      // straight to Tail, we need to check if a longjmp occurred, and go to the
      // right setjmp-tail if so
      ToErase.push_back(BB->getTerminator());

      // Generate a function call to testSetjmp function and preamble/postamble
      // code to figure out (1) whether longjmp occurred (2) if longjmp
      // occurred, which setjmp it corresponds to
      Value *Label = nullptr;
      Value *LongjmpResult = nullptr;
      BasicBlock *EndBB = nullptr;
      wrapTestSetjmp(BB, CI->getDebugLoc(), Threw, SetjmpTable, SetjmpTableSize,
                     Label, LongjmpResult, CallEmLongjmpBB,
                     CallEmLongjmpBBThrewPHI, CallEmLongjmpBBThrewValuePHI,
                     EndBB);
      assert(Label && LongjmpResult && EndBB);

      // Create switch instruction
      IRB.SetInsertPoint(EndBB);
      IRB.SetCurrentDebugLocation(EndBB->getInstList().back().getDebugLoc());
      SwitchInst *SI = IRB.CreateSwitch(Label, Tail, SetjmpRetPHIs.size());
      // -1 means no longjmp happened, continue normally (will hit the default
      // switch case). 0 means a longjmp that is not ours to handle, needs a
      // rethrow. Otherwise the index is the same as the index in P+1 (to avoid
      // 0).
      for (unsigned I = 0; I < SetjmpRetPHIs.size(); I++) {
        SI->addCase(IRB.getInt32(I + 1), SetjmpRetPHIs[I]->getParent());
        SetjmpRetPHIs[I]->addIncoming(LongjmpResult, EndBB);
      }

      // We are splitting the block here, and must continue to find other calls
      // in the block - which is now split. so continue to traverse in the Tail
      BBs.push_back(Tail);
    }
  }

  for (Instruction *I : ToErase)
    I->eraseFromParent();
}

// Create a catchpad in which we catch a longjmp's env and val arguments, test
// if the longjmp corresponds to one of setjmps in the current function, and if
// so, jump to the setjmp dispatch BB from which we go to one of post-setjmp
// BBs. Refer to 4) of "Wasm setjmp/longjmp handling" section in the comments at
// top of the file for details.
void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
    Function &F, InstVector &SetjmpTableInsts, InstVector &SetjmpTableSizeInsts,
    SmallVectorImpl<PHINode *> &SetjmpRetPHIs) {
  Module &M = *F.getParent();
  LLVMContext &C = F.getContext();
  IRBuilder<> IRB(C);

  // A function with catchswitch/catchpad instruction should have a personality
  // function attached to it. Search for the wasm personality function, and if
  // it exists, use it, and if it doesn't, create a dummy personality function.
  // (SjLj is not going to call it anyway.)
  if (!F.hasPersonalityFn()) {
    StringRef PersName = getEHPersonalityName(EHPersonality::Wasm_CXX);
    FunctionType *PersType =
        FunctionType::get(IRB.getInt32Ty(), /* isVarArg */ true);
    Value *PersF = M.getOrInsertFunction(PersName, PersType).getCallee();
    F.setPersonalityFn(
        cast<Constant>(IRB.CreateBitCast(PersF, IRB.getInt8PtrTy())));
  }

  // Use the entry BB's debugloc as a fallback
  BasicBlock *Entry = &F.getEntryBlock();
  DebugLoc FirstDL = getOrCreateDebugLoc(&*Entry->begin(), F.getSubprogram());
  IRB.SetCurrentDebugLocation(FirstDL);

  // Arbitrarily use the ones defined in the beginning of the function.
  // SSAUpdater will later update them to the correct values.
  Instruction *SetjmpTable = *SetjmpTableInsts.begin();
  Instruction *SetjmpTableSize = *SetjmpTableSizeInsts.begin();

  // Add setjmp.dispatch BB right after the entry block. Because we have
  // initialized setjmpTable/setjmpTableSize in the entry block and split the
  // rest into another BB, here 'OrigEntry' is the function's original entry
  // block before the transformation.
  //
  // entry:
  //   setjmpTable / setjmpTableSize initialization
  // setjmp.dispatch:
  //   switch will be inserted here later
  // entry.split: (OrigEntry)
  //   the original function starts here
  BasicBlock *OrigEntry = Entry->getNextNode();
  BasicBlock *SetjmpDispatchBB =
      BasicBlock::Create(C, "setjmp.dispatch", &F, OrigEntry);
  cast<BranchInst>(Entry->getTerminator())->setSuccessor(0, SetjmpDispatchBB);

  // Create catch.dispatch.longjmp BB a catchswitch instruction
  BasicBlock *CatchSwitchBB =
      BasicBlock::Create(C, "catch.dispatch.longjmp", &F);
  IRB.SetInsertPoint(CatchSwitchBB);
  CatchSwitchInst *CatchSwitch =
      IRB.CreateCatchSwitch(ConstantTokenNone::get(C), nullptr, 1);

  // Create catch.longjmp BB and a catchpad instruction
  BasicBlock *CatchLongjmpBB = BasicBlock::Create(C, "catch.longjmp", &F);
  CatchSwitch->addHandler(CatchLongjmpBB);
  IRB.SetInsertPoint(CatchLongjmpBB);
  CatchPadInst *CatchPad = IRB.CreateCatchPad(CatchSwitch, {});

  // Wasm throw and catch instructions can throw and catch multiple values, but
  // that requires multivalue support in the toolchain, which is currently not
  // very reliable. We instead throw and catch a pointer to a struct value of
  // type 'struct __WasmLongjmpArgs', which is defined in Emscripten.
  Instruction *CatchCI =
      IRB.CreateCall(CatchF, {IRB.getInt32(WebAssembly::C_LONGJMP)}, "thrown");
  Value *LongjmpArgs =
      IRB.CreateBitCast(CatchCI, LongjmpArgsTy->getPointerTo(), "longjmp.args");
  Value *EnvField =
      IRB.CreateConstGEP2_32(LongjmpArgsTy, LongjmpArgs, 0, 0, "env_gep");
  Value *ValField =
      IRB.CreateConstGEP2_32(LongjmpArgsTy, LongjmpArgs, 0, 1, "val_gep");
  // void *env = __wasm_longjmp_args.env;
  Instruction *Env = IRB.CreateLoad(IRB.getInt8PtrTy(), EnvField, "env");
  // int val = __wasm_longjmp_args.val;
  Instruction *Val = IRB.CreateLoad(IRB.getInt32Ty(), ValField, "val");

  // %label = testSetjmp(mem[%env], setjmpTable, setjmpTableSize);
  // if (%label == 0)
  //   __wasm_longjmp(%env, %val)
  // catchret to %setjmp.dispatch
  BasicBlock *ThenBB = BasicBlock::Create(C, "if.then", &F);
  BasicBlock *EndBB = BasicBlock::Create(C, "if.end", &F);
  Value *EnvP = IRB.CreateBitCast(Env, getAddrPtrType(&M), "env.p");
  Value *SetjmpID = IRB.CreateLoad(getAddrIntType(&M), EnvP, "setjmp.id");
  Value *Label =
      IRB.CreateCall(TestSetjmpF, {SetjmpID, SetjmpTable, SetjmpTableSize},
                     OperandBundleDef("funclet", CatchPad), "label");
  Value *Cmp = IRB.CreateICmpEQ(Label, IRB.getInt32(0));
  IRB.CreateCondBr(Cmp, ThenBB, EndBB);

  IRB.SetInsertPoint(ThenBB);
  CallInst *WasmLongjmpCI = IRB.CreateCall(
      WasmLongjmpF, {Env, Val}, OperandBundleDef("funclet", CatchPad));
  IRB.CreateUnreachable();

  IRB.SetInsertPoint(EndBB);
  // Jump to setjmp.dispatch block
  IRB.CreateCatchRet(CatchPad, SetjmpDispatchBB);

  // Go back to setjmp.dispatch BB
  // setjmp.dispatch:
  //   switch %label {
  //     label 1: goto post-setjmp BB 1
  //     label 2: goto post-setjmp BB 2
  //     ...
  //     default: goto splitted next BB
  //   }
  IRB.SetInsertPoint(SetjmpDispatchBB);
  PHINode *LabelPHI = IRB.CreatePHI(IRB.getInt32Ty(), 2, "label.phi");
  LabelPHI->addIncoming(Label, EndBB);
  LabelPHI->addIncoming(IRB.getInt32(-1), Entry);
  SwitchInst *SI = IRB.CreateSwitch(LabelPHI, OrigEntry, SetjmpRetPHIs.size());
  // -1 means no longjmp happened, continue normally (will hit the default
  // switch case). 0 means a longjmp that is not ours to handle, needs a
  // rethrow. Otherwise the index is the same as the index in P+1 (to avoid
  // 0).
  for (unsigned I = 0; I < SetjmpRetPHIs.size(); I++) {
    SI->addCase(IRB.getInt32(I + 1), SetjmpRetPHIs[I]->getParent());
    SetjmpRetPHIs[I]->addIncoming(Val, SetjmpDispatchBB);
  }

  // Convert all longjmpable call instructions to invokes that unwind to the
  // newly created catch.dispatch.longjmp BB.
  SmallVector<Instruction *, 64> ToErase;
  for (auto *BB = &*F.begin(); BB; BB = BB->getNextNode()) {
    for (Instruction &I : *BB) {
      auto *CI = dyn_cast<CallInst>(&I);
      if (!CI)
        continue;
      const Value *Callee = CI->getCalledOperand();
      if (!canLongjmp(Callee))
        continue;
      if (isEmAsmCall(Callee))
        report_fatal_error("Cannot use EM_ASM* alongside setjmp/longjmp in " +
                               F.getName() +
                               ". Please consider using EM_JS, or move the "
                               "EM_ASM into another function.",
                           false);
      // This is __wasm_longjmp() call we inserted in this function, which
      // rethrows the longjmp when the longjmp does not correspond to one of
      // setjmps in this function. We should not convert this call to an invoke.
      if (CI == WasmLongjmpCI)
        continue;
      ToErase.push_back(CI);

      // Even if the callee function has attribute 'nounwind', which is true for
      // all C functions, it can longjmp, which means it can throw a Wasm
      // exception now.
      CI->removeFnAttr(Attribute::NoUnwind);
      if (Function *CalleeF = CI->getCalledFunction()) {
        CalleeF->removeFnAttr(Attribute::NoUnwind);
      }

      IRB.SetInsertPoint(CI);
      BasicBlock *Tail = SplitBlock(BB, CI->getNextNode());
      // We will add a new invoke. So remove the branch created when we split
      // the BB
      ToErase.push_back(BB->getTerminator());
      SmallVector<Value *, 8> Args(CI->args());
      InvokeInst *II =
          IRB.CreateInvoke(CI->getFunctionType(), CI->getCalledOperand(), Tail,
                           CatchSwitchBB, Args);
      II->takeName(CI);
      II->setDebugLoc(CI->getDebugLoc());
      II->setAttributes(CI->getAttributes());
      CI->replaceAllUsesWith(II);
    }
  }

  for (Instruction *I : ToErase)
    I->eraseFromParent();
}
