[clang] [llvm] [WebAssembly] Implement an alternative translation for -wasm-enable-sjlj (PR #84137)

YAMAMOTO Takashi via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 14 23:00:04 PDT 2024


https://github.com/yamt updated https://github.com/llvm/llvm-project/pull/84137

>From 6c1bfa0aa292d81102a9aeb86ca4264516beb634 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Fri, 9 Feb 2024 15:49:55 +0900
Subject: [PATCH 01/26] [WebAssembly] Implement an alternative translation for
 -wasm-enable-sjlj

Instead of maintaining per-function-invocation malloc()'ed tables to
track which functions each label belongs to, store the equivalent info
in jump buffers (jmp_buf) themselves.

Also, use a less emscripten-looking ABI symbols:

    saveSetjmp     -> __wasm_sjlj_setjmp
    testSetjmp     -> __wasm_sjlj_test
    getTempRet0    -> (removed)
    __wasm_longjmp -> __wasm_sjlj_longjmp

Enabled with:

    -mllvm -wasm-enable-sjlj -mllvm -experimental-wasm-enable-alt-sjlj

(-experimental-wasm-enable-alt-sjlj is the new option this change
introduces.)

While I want to use this for WASI, it should work for emscripten as well.

An example runtime and a few tests:
https://github.com/yamt/garbage/tree/wasm-sjlj-alt2/wasm/longjmp

Discussion:
https://docs.google.com/document/d/1ZvTPT36K5jjiedF8MCXbEmYjULJjI723aOAks1IdLLg/edit
---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  14 ++
 .../MCTargetDesc/WebAssemblyMCTargetDesc.cpp  |   3 +
 .../MCTargetDesc/WebAssemblyMCTargetDesc.h    |   1 +
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp      | 174 +++++++++++-------
 .../WebAssembly/WebAssemblyTargetMachine.cpp  |   4 +
 5 files changed, 131 insertions(+), 65 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index b8c2573d6265fb..2e7c8e6e8d13f7 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -386,6 +386,20 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
       // Backend needs '-exception-model=wasm' to use Wasm EH instructions
       CC1Args.push_back("-exception-model=wasm");
     }
+
+    if (Opt.starts_with("-experimental-wasm-enable-alt-sjlj")) {
+      // '-mllvm -experimental-wasm-enable-alt-sjlj'  should be used with
+      // '-mllvm -wasm-enable-sjlj'
+      bool HasWasmEnableSjlj = false;
+      for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
+        if (StringRef(A->getValue(0)) == "-wasm-enable-sjlj")
+          HasWasmEnableSjlj = true;
+      }
+      if (!HasWasmEnableSjlj)
+        getDriver().Diag(diag::err_drv_argument_only_allowed_with)
+            << "-mllvm -experimental-wasm-enable-alt-sjlj"
+            << "-mllvm -wasm-enable-sjlj";
+    }
   }
 }
 
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
index e8f58a19d25e3b..7f15742367be09 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
@@ -54,6 +54,9 @@ cl::opt<bool>
 // setjmp/longjmp handling using wasm EH instrutions
 cl::opt<bool> WebAssembly::WasmEnableSjLj(
     "wasm-enable-sjlj", cl::desc("WebAssembly setjmp/longjmp handling"));
+cl::opt<bool> WebAssembly::WasmEnableAltSjLj(
+    "experimental-wasm-enable-alt-sjlj",
+    cl::desc("Use experimental alternate ABI for --wasm-enable-sjlj"));
 
 static MCAsmInfo *createMCAsmInfo(const MCRegisterInfo & /*MRI*/,
                                   const Triple &TT,
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index 15aeaaeb8c4a4e..d23de9d407d894 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -44,6 +44,7 @@ extern cl::opt<bool> WasmEnableEmEH;   // asm.js-style EH
 extern cl::opt<bool> WasmEnableEmSjLj; // asm.js-style SjLJ
 extern cl::opt<bool> WasmEnableEH;     // EH using Wasm EH instructions
 extern cl::opt<bool> WasmEnableSjLj;   // SjLj using Wasm EH instructions
+extern cl::opt<bool> WasmEnableAltSjLj; // Alt ABI for WasmEnableSjLj
 
 enum OperandType {
   /// Basic block label in a branch construct.
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 77e6640d5a8224..fc76757011f5d8 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -300,6 +300,7 @@ 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 EnableWasmAltSjLj; // Alt ABI for EnableWasmSjLj
   bool DoSjLj;         // Whether we actually perform setjmp/longjmp handling
 
   GlobalVariable *ThrewGV = nullptr;      // __THREW__ (Emscripten)
@@ -368,7 +369,8 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
   WebAssemblyLowerEmscriptenEHSjLj()
       : ModulePass(ID), EnableEmEH(WebAssembly::WasmEnableEmEH),
         EnableEmSjLj(WebAssembly::WasmEnableEmSjLj),
-        EnableWasmSjLj(WebAssembly::WasmEnableSjLj) {
+        EnableWasmSjLj(WebAssembly::WasmEnableSjLj),
+        EnableWasmAltSjLj(WebAssembly::WasmEnableAltSjLj) {
     assert(!(EnableEmSjLj && EnableWasmSjLj) &&
            "Two SjLj modes cannot be turned on at the same time");
     assert(!(EnableEmEH && EnableWasmSjLj) &&
@@ -619,6 +621,7 @@ static bool canLongjmp(const Value *Callee) {
   // 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 == "__wasm_sjlj_setjmp" || CalleeName == "__wasm_sjlj_test" ||
       CalleeName == "getTempRet0" || CalleeName == "setTempRet0")
     return false;
 
@@ -999,7 +1002,11 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
       // Register __wasm_longjmp function, which calls __builtin_wasm_longjmp.
       FunctionType *FTy = FunctionType::get(
           IRB.getVoidTy(), {Int8PtrTy, IRB.getInt32Ty()}, false);
-      WasmLongjmpF = getEmscriptenFunction(FTy, "__wasm_longjmp", &M);
+      if (EnableWasmAltSjLj) {
+        WasmLongjmpF = getEmscriptenFunction(FTy, "__wasm_sjlj_longjmp", &M);
+      } else {
+        WasmLongjmpF = getEmscriptenFunction(FTy, "__wasm_longjmp", &M);
+      }
       WasmLongjmpF->addFnAttr(Attribute::NoReturn);
     }
 
@@ -1007,17 +1014,30 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
       Type *Int8PtrTy = IRB.getPtrTy();
       Type *Int32PtrTy = IRB.getPtrTy();
       Type *Int32Ty = IRB.getInt32Ty();
-      // Register saveSetjmp function
-      FunctionType *SetjmpFTy = SetjmpF->getFunctionType();
-      FunctionType *FTy = FunctionType::get(
-          Int32PtrTy,
-          {SetjmpFTy->getParamType(0), Int32Ty, Int32PtrTy, Int32Ty}, false);
-      SaveSetjmpF = getEmscriptenFunction(FTy, "saveSetjmp", &M);
 
       // Register testSetjmp function
-      FTy = FunctionType::get(Int32Ty,
-                              {getAddrIntType(&M), Int32PtrTy, Int32Ty}, false);
-      TestSetjmpF = getEmscriptenFunction(FTy, "testSetjmp", &M);
+      if (EnableWasmAltSjLj) {
+        // Register saveSetjmp function
+        FunctionType *SetjmpFTy = SetjmpF->getFunctionType();
+        FunctionType *FTy = FunctionType::get(
+            IRB.getVoidTy(), {SetjmpFTy->getParamType(0), Int32Ty, Int32PtrTy},
+            false);
+        SaveSetjmpF = getEmscriptenFunction(FTy, "__wasm_sjlj_setjmp", &M);
+
+        FTy = FunctionType::get(Int32Ty, {Int32PtrTy, Int32PtrTy}, false);
+        TestSetjmpF = getEmscriptenFunction(FTy, "__wasm_sjlj_test", &M);
+      } else {
+        // Register saveSetjmp function
+        FunctionType *SetjmpFTy = SetjmpF->getFunctionType();
+        FunctionType *FTy = FunctionType::get(
+            Int32PtrTy,
+            {SetjmpFTy->getParamType(0), Int32Ty, Int32PtrTy, Int32Ty}, false);
+        SaveSetjmpF = getEmscriptenFunction(FTy, "saveSetjmp", &M);
+
+        FTy = FunctionType::get(
+            Int32Ty, {getAddrIntType(&M), Int32PtrTy, Int32Ty}, false);
+        TestSetjmpF = getEmscriptenFunction(FTy, "testSetjmp", &M);
+      }
 
       // wasm.catch() will be lowered down to wasm 'catch' instruction in
       // instruction selection.
@@ -1291,19 +1311,29 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
   Type *IntPtrTy = getAddrIntType(&M);
   Constant *size = ConstantInt::get(IntPtrTy, 40);
   IRB.SetInsertPoint(SetjmpTableSize);
-  auto *SetjmpTable = IRB.CreateMalloc(IntPtrTy, IRB.getInt32Ty(), size,
-                                       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);
+  Instruction *SetjmpTable;
+  if (EnableWasmAltSjLj) {
+    // This alloca'ed pointer is used by the runtime to identify function
+    // inovactions. It's just for pointer comparisons. It will never
+    // be dereferenced.
+    SetjmpTable = IRB.CreateAlloca(IRB.getInt32Ty());
+    SetjmpTable->setDebugLoc(FirstDL);
+    SetjmpTableInsts.push_back(SetjmpTable);
+  } else {
+    SetjmpTable = IRB.CreateMalloc(IntPtrTy, IRB.getInt32Ty(), size, 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.CreateStore(IRB.getInt32(0), SetjmpTable);
+    SetjmpTableInsts.push_back(SetjmpTable);
+    SetjmpTableSizeInsts.push_back(SetjmpTableSize);
   }
-  // setjmpTable[0] = 0;
-  IRB.CreateStore(IRB.getInt32(0), SetjmpTable);
-  SetjmpTableInsts.push_back(SetjmpTable);
-  SetjmpTableSizeInsts.push_back(SetjmpTableSize);
 
   // Setjmp transformation
   SmallVector<PHINode *, 4> SetjmpRetPHIs;
@@ -1349,14 +1379,20 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
     // 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, std::nullopt, "setjmpTableSize");
-    SetjmpTableInsts.push_back(NewSetjmpTable);
-    SetjmpTableSizeInsts.push_back(NewSetjmpTableSize);
+    if (EnableWasmAltSjLj) {
+      Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),
+                       SetjmpTable};
+      IRB.CreateCall(SaveSetjmpF, Args);
+    } else {
+      Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),
+                       SetjmpTable, SetjmpTableSize};
+      Instruction *NewSetjmpTable =
+          IRB.CreateCall(SaveSetjmpF, Args, "setjmpTable");
+      Instruction *NewSetjmpTableSize =
+          IRB.CreateCall(GetTempRet0F, std::nullopt, "setjmpTableSize");
+      SetjmpTableInsts.push_back(NewSetjmpTable);
+      SetjmpTableSizeInsts.push_back(NewSetjmpTableSize);
+    }
     ToErase.push_back(CI);
   }
 
@@ -1372,38 +1408,40 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
   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);
+  if (!EnableWasmAltSjLj) {
+    // 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));
-    IRB.SetInsertPoint(I);
-    auto *Free = IRB.CreateFree(SetjmpTable, Bundles);
-    Free->setDebugLoc(DL);
+    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));
+      IRB.SetInsertPoint(I);
+      auto *Free = IRB.CreateFree(SetjmpTable, Bundles);
+      Free->setDebugLoc(DL);
+    }
   }
 
   // Every call to saveSetjmp can change setjmpTable and setjmpTableSize
@@ -1738,10 +1776,16 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
   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 *Label;
+  if (EnableWasmAltSjLj) {
+    Label = IRB.CreateCall(TestSetjmpF, {EnvP, SetjmpTable},
+                           OperandBundleDef("funclet", CatchPad), "label");
+  } else {
+    Value *SetjmpID = IRB.CreateLoad(getAddrIntType(&M), EnvP, "setjmp.id");
+    Label =
+        IRB.CreateCall(TestSetjmpF, {SetjmpID, SetjmpTable, SetjmpTableSize},
+                       OperandBundleDef("funclet", CatchPad), "label");
+  }
   Value *Cmp = IRB.CreateICmpEQ(Label, IRB.getInt32(0));
   IRB.CreateCondBr(Cmp, ThenBB, EndBB);
 
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index 70685b2e3bb2de..6db019034028bc 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -370,6 +370,7 @@ FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
   return nullptr; // No reg alloc
 }
 
+using WebAssembly::WasmEnableAltSjLj;
 using WebAssembly::WasmEnableEH;
 using WebAssembly::WasmEnableEmEH;
 using WebAssembly::WasmEnableEmSjLj;
@@ -405,6 +406,9 @@ static void basicCheckForEHAndSjLj(TargetMachine *TM) {
     report_fatal_error(
         "-exception-model=wasm only allowed with at least one of "
         "-wasm-enable-eh or -wasm-enable-sjlj");
+  if (!WasmEnableSjLj && WasmEnableAltSjLj)
+    report_fatal_error("-experimental-wasm-enable-alt-sjlj only allowed with "
+                       "-wasm-enable-sjlj");
 
   // You can't enable two modes of EH at the same time
   if (WasmEnableEmEH && WasmEnableEH)

>From 4c620a6fd7dcb676a2e86ef21439d9864c57b3e3 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Fri, 8 Mar 2024 09:49:52 +0900
Subject: [PATCH 02/26] WebAssemblyLowerEmscriptenEHSjLj.cpp: move a comment to
 appropriate places

---
 .../Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp    | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index fc76757011f5d8..7f98a2407a28b6 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -1015,7 +1015,6 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
       Type *Int32PtrTy = IRB.getPtrTy();
       Type *Int32Ty = IRB.getInt32Ty();
 
-      // Register testSetjmp function
       if (EnableWasmAltSjLj) {
         // Register saveSetjmp function
         FunctionType *SetjmpFTy = SetjmpF->getFunctionType();
@@ -1024,6 +1023,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
             false);
         SaveSetjmpF = getEmscriptenFunction(FTy, "__wasm_sjlj_setjmp", &M);
 
+        // Register testSetjmp function
         FTy = FunctionType::get(Int32Ty, {Int32PtrTy, Int32PtrTy}, false);
         TestSetjmpF = getEmscriptenFunction(FTy, "__wasm_sjlj_test", &M);
       } else {
@@ -1034,6 +1034,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
             {SetjmpFTy->getParamType(0), Int32Ty, Int32PtrTy, Int32Ty}, false);
         SaveSetjmpF = getEmscriptenFunction(FTy, "saveSetjmp", &M);
 
+        // Register testSetjmp function
         FTy = FunctionType::get(
             Int32Ty, {getAddrIntType(&M), Int32PtrTy, Int32Ty}, false);
         TestSetjmpF = getEmscriptenFunction(FTy, "testSetjmp", &M);

>From 86e7e9187195134e2b267dcf8ebe7435a2e38935 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Fri, 8 Mar 2024 10:22:45 +0900
Subject: [PATCH 03/26] WebAssemblyLowerEmscriptenEHSjLj.cpp: comment

---
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp          | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 7f98a2407a28b6..3e9ca5114c2d1a 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -265,6 +265,21 @@
 ///     __wasm_longjmp(%env, %val)
 ///   catchret to %setjmp.dispatch
 ///
+/// * Wasm setjmp / longjmp handling (with -experimental-wasm-enable-alt-sjlj)
+///
+/// The translation is basically same as what we do for
+/// "Wasm setjmp / longjmp handling" w/o -experimental-wasm-enable-alt-sjlj.
+///
+/// The differences are:
+///
+/// - We do not use malloc'ed tables.
+///
+/// - On the entry of setjmp-calling functions, we initialize a pointer
+///   to identify the function invocation using alloc().
+///
+/// - We use simpler ABI functions with different names.
+///   (prefixed with "__wasm_sjlj_")
+///
 ///===----------------------------------------------------------------------===//
 
 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"

>From 4796060386ca715b38fafa3822645551dab8d4e9 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Mon, 11 Mar 2024 11:14:49 +0900
Subject: [PATCH 04/26] clang/lib/Driver/ToolChains/WebAssembly.cpp: fix
 whitespace in a comment

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 2e7c8e6e8d13f7..069e1236e8b006 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -388,7 +388,7 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
     }
 
     if (Opt.starts_with("-experimental-wasm-enable-alt-sjlj")) {
-      // '-mllvm -experimental-wasm-enable-alt-sjlj'  should be used with
+      // '-mllvm -experimental-wasm-enable-alt-sjlj' should be used with
       // '-mllvm -wasm-enable-sjlj'
       bool HasWasmEnableSjlj = false;
       for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {

>From b2b1f53382ababedf1059bbc075da8f002e0967f Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Mon, 11 Mar 2024 11:15:35 +0900
Subject: [PATCH 05/26] WebAssemblyMCTargetDesc.cpp: fix a typo in a
 description

---
 .../Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
index 7f15742367be09..4371318f4443ce 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
@@ -56,7 +56,7 @@ cl::opt<bool> WebAssembly::WasmEnableSjLj(
     "wasm-enable-sjlj", cl::desc("WebAssembly setjmp/longjmp handling"));
 cl::opt<bool> WebAssembly::WasmEnableAltSjLj(
     "experimental-wasm-enable-alt-sjlj",
-    cl::desc("Use experimental alternate ABI for --wasm-enable-sjlj"));
+    cl::desc("Use experimental alternate ABI for -wasm-enable-sjlj"));
 
 static MCAsmInfo *createMCAsmInfo(const MCRegisterInfo & /*MRI*/,
                                   const Triple &TT,

>From ea5db86d9cd27976b1da39ae062dc54d7893fca8 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Mon, 11 Mar 2024 19:05:34 +0900
Subject: [PATCH 06/26] move some SSAUpdate stuff in !EnableWasmAltSjLj block

---
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp      | 60 +++++++++----------
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 3e9ca5114c2d1a..70b35e656c976f 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -1458,37 +1458,37 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
       auto *Free = IRB.CreateFree(SetjmpTable, Bundles);
       Free->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(PointerType::get(C, 0), "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);
+    // 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(PointerType::get(C, 0), "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,

>From a79a4b6be0b793f09c1155cb855c08c39d93b53d Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Mon, 11 Mar 2024 13:18:12 +0900
Subject: [PATCH 07/26] WebAssemblyLowerEmscriptenEHSjLj: move some code to
 !EnableWasmAltSjLj block

---
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp      | 26 ++++++++++---------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 70b35e656c976f..a7947bc1f723e2 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -1311,24 +1311,14 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
 
   // 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);
-  Type *IntPtrTy = getAddrIntType(&M);
-  Constant *size = ConstantInt::get(IntPtrTy, 40);
-  IRB.SetInsertPoint(SetjmpTableSize);
+  BinaryOperator *SetjmpTableSize;
   Instruction *SetjmpTable;
   if (EnableWasmAltSjLj) {
+    IRB.SetInsertPoint(Entry->getTerminator());
     // This alloca'ed pointer is used by the runtime to identify function
     // inovactions. It's just for pointer comparisons. It will never
     // be dereferenced.
@@ -1336,6 +1326,18 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
     SetjmpTable->setDebugLoc(FirstDL);
     SetjmpTableInsts.push_back(SetjmpTable);
   } else {
+    // 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.
+    SetjmpTableSize = BinaryOperator::Create(Instruction::Add, IRB.getInt32(4),
+                                             IRB.getInt32(0), "setjmpTableSize",
+                                             Entry->getTerminator());
+    SetjmpTableSize->setDebugLoc(FirstDL);
+    IRB.SetInsertPoint(SetjmpTableSize);
+    // setjmpTable = (int *) malloc(40);
+    Type *IntPtrTy = getAddrIntType(&M);
+    Constant *size = ConstantInt::get(IntPtrTy, 40);
     SetjmpTable = IRB.CreateMalloc(IntPtrTy, IRB.getInt32Ty(), size, nullptr,
                                    nullptr, "setjmpTable");
     SetjmpTable->setDebugLoc(FirstDL);

>From d56c5d72d18a615b587db4a07ac98a89bd10ad3a Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 13:25:01 +0900
Subject: [PATCH 08/26] remove -mllvm -experimental-wasm-enable-alt-sjlj

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp        | 14 --------------
 .../MCTargetDesc/WebAssemblyMCTargetDesc.cpp       |  3 ---
 .../MCTargetDesc/WebAssemblyMCTargetDesc.h         |  1 -
 .../WebAssembly/WebAssemblyTargetMachine.cpp       |  4 ----
 4 files changed, 22 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 069e1236e8b006..b8c2573d6265fb 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -386,20 +386,6 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
       // Backend needs '-exception-model=wasm' to use Wasm EH instructions
       CC1Args.push_back("-exception-model=wasm");
     }
-
-    if (Opt.starts_with("-experimental-wasm-enable-alt-sjlj")) {
-      // '-mllvm -experimental-wasm-enable-alt-sjlj' should be used with
-      // '-mllvm -wasm-enable-sjlj'
-      bool HasWasmEnableSjlj = false;
-      for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
-        if (StringRef(A->getValue(0)) == "-wasm-enable-sjlj")
-          HasWasmEnableSjlj = true;
-      }
-      if (!HasWasmEnableSjlj)
-        getDriver().Diag(diag::err_drv_argument_only_allowed_with)
-            << "-mllvm -experimental-wasm-enable-alt-sjlj"
-            << "-mllvm -wasm-enable-sjlj";
-    }
   }
 }
 
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
index 4371318f4443ce..e8f58a19d25e3b 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
@@ -54,9 +54,6 @@ cl::opt<bool>
 // setjmp/longjmp handling using wasm EH instrutions
 cl::opt<bool> WebAssembly::WasmEnableSjLj(
     "wasm-enable-sjlj", cl::desc("WebAssembly setjmp/longjmp handling"));
-cl::opt<bool> WebAssembly::WasmEnableAltSjLj(
-    "experimental-wasm-enable-alt-sjlj",
-    cl::desc("Use experimental alternate ABI for -wasm-enable-sjlj"));
 
 static MCAsmInfo *createMCAsmInfo(const MCRegisterInfo & /*MRI*/,
                                   const Triple &TT,
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index d23de9d407d894..15aeaaeb8c4a4e 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -44,7 +44,6 @@ extern cl::opt<bool> WasmEnableEmEH;   // asm.js-style EH
 extern cl::opt<bool> WasmEnableEmSjLj; // asm.js-style SjLJ
 extern cl::opt<bool> WasmEnableEH;     // EH using Wasm EH instructions
 extern cl::opt<bool> WasmEnableSjLj;   // SjLj using Wasm EH instructions
-extern cl::opt<bool> WasmEnableAltSjLj; // Alt ABI for WasmEnableSjLj
 
 enum OperandType {
   /// Basic block label in a branch construct.
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index 6db019034028bc..70685b2e3bb2de 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -370,7 +370,6 @@ FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
   return nullptr; // No reg alloc
 }
 
-using WebAssembly::WasmEnableAltSjLj;
 using WebAssembly::WasmEnableEH;
 using WebAssembly::WasmEnableEmEH;
 using WebAssembly::WasmEnableEmSjLj;
@@ -406,9 +405,6 @@ static void basicCheckForEHAndSjLj(TargetMachine *TM) {
     report_fatal_error(
         "-exception-model=wasm only allowed with at least one of "
         "-wasm-enable-eh or -wasm-enable-sjlj");
-  if (!WasmEnableSjLj && WasmEnableAltSjLj)
-    report_fatal_error("-experimental-wasm-enable-alt-sjlj only allowed with "
-                       "-wasm-enable-sjlj");
 
   // You can't enable two modes of EH at the same time
   if (WasmEnableEmEH && WasmEnableEH)

>From 93bde2038af59fef6c17c0ada0b44856b0b5b0b1 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 13:40:33 +0900
Subject: [PATCH 09/26] remove -mllvm -experimental-wasm-enable-alt-sjlj

---
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp      | 26 ++++++-------------
 1 file changed, 8 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index a7947bc1f723e2..78817566230144 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -315,7 +315,6 @@ 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 EnableWasmAltSjLj; // Alt ABI for EnableWasmSjLj
   bool DoSjLj;         // Whether we actually perform setjmp/longjmp handling
 
   GlobalVariable *ThrewGV = nullptr;      // __THREW__ (Emscripten)
@@ -384,8 +383,7 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
   WebAssemblyLowerEmscriptenEHSjLj()
       : ModulePass(ID), EnableEmEH(WebAssembly::WasmEnableEmEH),
         EnableEmSjLj(WebAssembly::WasmEnableEmSjLj),
-        EnableWasmSjLj(WebAssembly::WasmEnableSjLj),
-        EnableWasmAltSjLj(WebAssembly::WasmEnableAltSjLj) {
+        EnableWasmSjLj(WebAssembly::WasmEnableSjLj) {
     assert(!(EnableEmSjLj && EnableWasmSjLj) &&
            "Two SjLj modes cannot be turned on at the same time");
     assert(!(EnableEmEH && EnableWasmSjLj) &&
@@ -1017,7 +1015,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
       // Register __wasm_longjmp function, which calls __builtin_wasm_longjmp.
       FunctionType *FTy = FunctionType::get(
           IRB.getVoidTy(), {Int8PtrTy, IRB.getInt32Ty()}, false);
-      if (EnableWasmAltSjLj) {
+      if (EnableWasmSjLj) {
         WasmLongjmpF = getEmscriptenFunction(FTy, "__wasm_sjlj_longjmp", &M);
       } else {
         WasmLongjmpF = getEmscriptenFunction(FTy, "__wasm_longjmp", &M);
@@ -1030,7 +1028,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
       Type *Int32PtrTy = IRB.getPtrTy();
       Type *Int32Ty = IRB.getInt32Ty();
 
-      if (EnableWasmAltSjLj) {
+      if (EnableWasmSjLj) {
         // Register saveSetjmp function
         FunctionType *SetjmpFTy = SetjmpF->getFunctionType();
         FunctionType *FTy = FunctionType::get(
@@ -1317,7 +1315,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
 
   BinaryOperator *SetjmpTableSize;
   Instruction *SetjmpTable;
-  if (EnableWasmAltSjLj) {
+  if (EnableWasmSjLj) {
     IRB.SetInsertPoint(Entry->getTerminator());
     // This alloca'ed pointer is used by the runtime to identify function
     // inovactions. It's just for pointer comparisons. It will never
@@ -1397,7 +1395,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
     // 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);
-    if (EnableWasmAltSjLj) {
+    if (EnableWasmSjLj) {
       Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),
                        SetjmpTable};
       IRB.CreateCall(SaveSetjmpF, Args);
@@ -1426,7 +1424,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
   for (Instruction *I : ToErase)
     I->eraseFromParent();
 
-  if (!EnableWasmAltSjLj) {
+  if (!EnableWasmSjLj) {
     // Free setjmpTable buffer before each return instruction + function-exiting
     // call
     SmallVector<Instruction *, 16> ExitingInsts;
@@ -1794,16 +1792,8 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
   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 *Label;
-  if (EnableWasmAltSjLj) {
-    Label = IRB.CreateCall(TestSetjmpF, {EnvP, SetjmpTable},
-                           OperandBundleDef("funclet", CatchPad), "label");
-  } else {
-    Value *SetjmpID = IRB.CreateLoad(getAddrIntType(&M), EnvP, "setjmp.id");
-    Label =
-        IRB.CreateCall(TestSetjmpF, {SetjmpID, SetjmpTable, SetjmpTableSize},
-                       OperandBundleDef("funclet", CatchPad), "label");
-  }
+  Value *Label = IRB.CreateCall(TestSetjmpF, {EnvP, SetjmpTable},
+                                OperandBundleDef("funclet", CatchPad), "label");
   Value *Cmp = IRB.CreateICmpEQ(Label, IRB.getInt32(0));
   IRB.CreateCondBr(Cmp, ThenBB, EndBB);
 

>From 2cdc54e7444ef53f883d36bafb0a7dc505447c64 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 13:49:38 +0900
Subject: [PATCH 10/26] handleLongjmpableCallsForWasmSjLj: simplify a bit

---
 .../WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp       | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 78817566230144..a090c029004e5a 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -355,7 +355,6 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
       SmallVectorImpl<PHINode *> &SetjmpRetPHIs);
   void
   handleLongjmpableCallsForWasmSjLj(Function &F, InstVector &SetjmpTableInsts,
-                                    InstVector &SetjmpTableSizeInsts,
                                     SmallVectorImpl<PHINode *> &SetjmpRetPHIs);
   Function *getFindMatchingCatch(Module &M, unsigned NumClauses);
 
@@ -1417,8 +1416,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
     handleLongjmpableCallsForEmscriptenSjLj(
         F, SetjmpTableInsts, SetjmpTableSizeInsts, SetjmpRetPHIs);
   else // EnableWasmSjLj
-    handleLongjmpableCallsForWasmSjLj(F, SetjmpTableInsts, SetjmpTableSizeInsts,
-                                      SetjmpRetPHIs);
+    handleLongjmpableCallsForWasmSjLj(F, SetjmpTableInsts, SetjmpRetPHIs);
 
   // Erase everything we no longer need in this function
   for (Instruction *I : ToErase)
@@ -1712,7 +1710,7 @@ static BasicBlock *getCleanupRetUnwindDest(const CleanupPadInst *CPI) {
 // 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,
+    Function &F, InstVector &SetjmpTableInsts,
     SmallVectorImpl<PHINode *> &SetjmpRetPHIs) {
   Module &M = *F.getParent();
   LLVMContext &C = F.getContext();
@@ -1739,7 +1737,6 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
   // 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

>From ff285f7dcc72ca4b3c44a3e4092a96e3dc748b2f Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 13:50:56 +0900
Subject: [PATCH 11/26] rename abi functions

---
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp            | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index a090c029004e5a..c7df56cf54022e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -278,7 +278,6 @@
 ///   to identify the function invocation using alloc().
 ///
 /// - We use simpler ABI functions with different names.
-///   (prefixed with "__wasm_sjlj_")
 ///
 ///===----------------------------------------------------------------------===//
 
@@ -633,7 +632,7 @@ static bool canLongjmp(const Value *Callee) {
   // 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 == "__wasm_sjlj_setjmp" || CalleeName == "__wasm_sjlj_test" ||
+      CalleeName == "__wasm_setjmp" || CalleeName == "__wasm_setjmp_test" ||
       CalleeName == "getTempRet0" || CalleeName == "setTempRet0")
     return false;
 
@@ -1014,11 +1013,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
       // Register __wasm_longjmp function, which calls __builtin_wasm_longjmp.
       FunctionType *FTy = FunctionType::get(
           IRB.getVoidTy(), {Int8PtrTy, IRB.getInt32Ty()}, false);
-      if (EnableWasmSjLj) {
-        WasmLongjmpF = getEmscriptenFunction(FTy, "__wasm_sjlj_longjmp", &M);
-      } else {
-        WasmLongjmpF = getEmscriptenFunction(FTy, "__wasm_longjmp", &M);
-      }
+      WasmLongjmpF = getEmscriptenFunction(FTy, "__wasm_longjmp", &M);
       WasmLongjmpF->addFnAttr(Attribute::NoReturn);
     }
 
@@ -1033,11 +1028,11 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
         FunctionType *FTy = FunctionType::get(
             IRB.getVoidTy(), {SetjmpFTy->getParamType(0), Int32Ty, Int32PtrTy},
             false);
-        SaveSetjmpF = getEmscriptenFunction(FTy, "__wasm_sjlj_setjmp", &M);
+        SaveSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp", &M);
 
         // Register testSetjmp function
         FTy = FunctionType::get(Int32Ty, {Int32PtrTy, Int32PtrTy}, false);
-        TestSetjmpF = getEmscriptenFunction(FTy, "__wasm_sjlj_test", &M);
+        TestSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp_test", &M);
       } else {
         // Register saveSetjmp function
         FunctionType *SetjmpFTy = SetjmpF->getFunctionType();

>From 9c21d8e6964e123f938a5c334acb7f0c4fade540 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 14:32:06 +0900
Subject: [PATCH 12/26] 
 llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp: comment

---
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp      | 34 +++++++++----------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index c7df56cf54022e..cdd72a3c926ba7 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -201,6 +201,20 @@
 /// 2) and 3): The same as 2) and 3) in Emscripten SjLj.
 /// (setjmpTable/setjmpTableSize initialization + setjmp callsite
 /// transformation)
+/// functionInvocationId
+///
+/// 2) In the function entry that calls setjmp, initialize
+///    functionInvocationId as follows:
+///
+///    functionInvocationId = alloca()
+///
+/// 3) Lower
+///      setjmp(env)
+///    into
+///      __wasm_setjmp(env, label, functionInvocationId)
+///
+///    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) Create a catchpad with a wasm.catch() intrinsic, which returns the value
 /// thrown by __wasm_longjmp function. In Emscripten library, we have this
@@ -232,12 +246,12 @@
 /// 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 function. (after functionInvocationId initialization)
 ///
 /// The below is the pseudocode for what we have described
 ///
 /// entry:
-///   Initialize setjmpTable and setjmpTableSize
+///   Initialize functionInvocationId
 ///
 /// setjmp.dispatch:
 ///    switch %label {
@@ -260,25 +274,11 @@
 ///   %longjmp.args = wasm.catch() ;; struct __WasmLongjmpArgs
 ///   %env = load 'env' field from __WasmLongjmpArgs
 ///   %val = load 'val' field from __WasmLongjmpArgs
-///   %label = testSetjmp(mem[%env], setjmpTable, setjmpTableSize);
+///   %label = __wasm_setjmp_test(%env, functionInvocationId);
 ///   if (%label == 0)
 ///     __wasm_longjmp(%env, %val)
 ///   catchret to %setjmp.dispatch
 ///
-/// * Wasm setjmp / longjmp handling (with -experimental-wasm-enable-alt-sjlj)
-///
-/// The translation is basically same as what we do for
-/// "Wasm setjmp / longjmp handling" w/o -experimental-wasm-enable-alt-sjlj.
-///
-/// The differences are:
-///
-/// - We do not use malloc'ed tables.
-///
-/// - On the entry of setjmp-calling functions, we initialize a pointer
-///   to identify the function invocation using alloc().
-///
-/// - We use simpler ABI functions with different names.
-///
 ///===----------------------------------------------------------------------===//
 
 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"

>From 210c4372b827c62ee4dccfc0fd91bdff4117dec0 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 14:44:55 +0900
Subject: [PATCH 13/26] handleLongjmpableCallsForWasmSjLj: simplify a bit

---
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp      | 21 ++++++++-----------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index cdd72a3c926ba7..a4395e54e65d3b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -353,7 +353,8 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
       InstVector &SetjmpTableSizeInsts,
       SmallVectorImpl<PHINode *> &SetjmpRetPHIs);
   void
-  handleLongjmpableCallsForWasmSjLj(Function &F, InstVector &SetjmpTableInsts,
+  handleLongjmpableCallsForWasmSjLj(Function &F,
+                                    Instruction *FunctionInvocationId,
                                     SmallVectorImpl<PHINode *> &SetjmpRetPHIs);
   Function *getFindMatchingCatch(Module &M, unsigned NumClauses);
 
@@ -1309,14 +1310,14 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
 
   BinaryOperator *SetjmpTableSize;
   Instruction *SetjmpTable;
+  Instruction *FunctionInvocationId;
   if (EnableWasmSjLj) {
     IRB.SetInsertPoint(Entry->getTerminator());
     // This alloca'ed pointer is used by the runtime to identify function
     // inovactions. It's just for pointer comparisons. It will never
     // be dereferenced.
-    SetjmpTable = IRB.CreateAlloca(IRB.getInt32Ty());
-    SetjmpTable->setDebugLoc(FirstDL);
-    SetjmpTableInsts.push_back(SetjmpTable);
+    FunctionInvocationId = IRB.CreateAlloca(IRB.getInt32Ty());
+    FunctionInvocationId->setDebugLoc(FirstDL);
   } else {
     // This instruction effectively means %setjmpTableSize = 4.
     // We create this as an instruction intentionally, and we don't want to fold
@@ -1411,7 +1412,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
     handleLongjmpableCallsForEmscriptenSjLj(
         F, SetjmpTableInsts, SetjmpTableSizeInsts, SetjmpRetPHIs);
   else // EnableWasmSjLj
-    handleLongjmpableCallsForWasmSjLj(F, SetjmpTableInsts, SetjmpRetPHIs);
+    handleLongjmpableCallsForWasmSjLj(F, FunctionInvocationId, SetjmpRetPHIs);
 
   // Erase everything we no longer need in this function
   for (Instruction *I : ToErase)
@@ -1705,7 +1706,7 @@ static BasicBlock *getCleanupRetUnwindDest(const CleanupPadInst *CPI) {
 // 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,
+    Function &F, Instruction *FunctionInvocationId,
     SmallVectorImpl<PHINode *> &SetjmpRetPHIs) {
   Module &M = *F.getParent();
   LLVMContext &C = F.getContext();
@@ -1729,10 +1730,6 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
   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();
-
   // 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
@@ -1777,14 +1774,14 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
   // int val = __wasm_longjmp_args.val;
   Instruction *Val = IRB.CreateLoad(IRB.getInt32Ty(), ValField, "val");
 
-  // %label = testSetjmp(mem[%env], setjmpTable, setjmpTableSize);
+  // %label = __wasm_setjmp_test(%env, functionInvocatinoId);
   // 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 *Label = IRB.CreateCall(TestSetjmpF, {EnvP, SetjmpTable},
+  Value *Label = IRB.CreateCall(TestSetjmpF, {EnvP, FunctionInvocationId},
                                 OperandBundleDef("funclet", CatchPad), "label");
   Value *Cmp = IRB.CreateICmpEQ(Label, IRB.getInt32(0));
   IRB.CreateCondBr(Cmp, ThenBB, EndBB);

>From a8d355c576a599ea6559dbcce2c8629a5d1d0a70 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 15:06:09 +0900
Subject: [PATCH 14/26] WebAssemblyLowerEmscriptenEHSjLj.cpp: fix a botch in
 FunctionIvocationId rename

---
 .../lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index a4395e54e65d3b..6160eb1cce05a2 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -1392,7 +1392,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
     IRB.SetInsertPoint(CI);
     if (EnableWasmSjLj) {
       Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),
-                       SetjmpTable};
+                       FunctionInvocationId};
       IRB.CreateCall(SaveSetjmpF, Args);
     } else {
       Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),

>From 5f16023740ff59eeb23fcbb52f7268d6474b864c Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 15:38:16 +0900
Subject: [PATCH 15/26] give an IR level name to function invocation id

---
 .../lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 6160eb1cce05a2..98a30444826125 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -1316,7 +1316,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
     // This alloca'ed pointer is used by the runtime to identify function
     // inovactions. It's just for pointer comparisons. It will never
     // be dereferenced.
-    FunctionInvocationId = IRB.CreateAlloca(IRB.getInt32Ty());
+    FunctionInvocationId = IRB.CreateAlloca(IRB.getInt32Ty(), nullptr, "functionInvocationId");
     FunctionInvocationId->setDebugLoc(FirstDL);
   } else {
     // This instruction effectively means %setjmpTableSize = 4.

>From a6ee1740bb2d6117eb9e2aef009f192dbcf36062 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 15:38:56 +0900
Subject: [PATCH 16/26] llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll:
 update

---
 .../CodeGen/WebAssembly/lower-wasm-sjlj.ll    | 22 +++++--------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll
index b8d2230fac9f5b..82c04e24b72f13 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll
@@ -25,16 +25,12 @@ entry:
   unreachable
 
 ; CHECK:    entry:
-; CHECK-NEXT: %setjmpTable = tail call ptr @malloc([[PTR]] 40)
-; CHECK-NEXT: store i32 0, ptr %setjmpTable, align 4
-; CHECK-NEXT: %setjmpTableSize = add i32 4, 0
+; CHECK-NEXT: %functionInvocationId = alloca i32, align 4
 ; CHECK-NEXT: br label %setjmp.dispatch
 
 ; CHECK:    setjmp.dispatch:
 ; CHECK-NEXT: %[[VAL2:.*]] = phi i32 [ %val, %if.end ], [ undef, %entry ]
 ; CHECK-NEXT: %[[BUF:.*]] = phi ptr [ %[[BUF2:.*]], %if.end ], [ undef, %entry ]
-; CHECK-NEXT: %[[SETJMPTABLESIZE2:.*]] = phi i32 [ %[[SETJMPTABLESIZE3:.*]], %if.end ], [ %setjmpTableSize, %entry ]
-; CHECK-NEXT: %[[SETJMPTABLE2:.*]] = phi ptr [ %[[SETJMPTABLE3:.*]], %if.end ], [ %setjmpTable, %entry ]
 ; CHECK-NEXT: %label.phi = phi i32 [ %label, %if.end ], [ -1, %entry ]
 ; CHECK-NEXT: switch i32 %label.phi, label %entry.split [
 ; CHECK-NEXT:   i32 1, label %entry.split.split
@@ -42,14 +38,11 @@ entry:
 
 ; CHECK:    entry.split:
 ; CHECK-NEXT: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16
-; CHECK-NEXT: %[[SETJMPTABLE4:.*]] = call ptr @saveSetjmp(ptr %buf, i32 1, ptr %[[SETJMPTABLE2]], i32 %[[SETJMPTABLESIZE2]])
-; CHECK-NEXT: %[[SETJMPTABLESIZE4:.*]] = call i32 @getTempRet0()
+; CHECK-NEXT: call void @__wasm_setjmp(ptr %buf, i32 1, ptr %functionInvocationId)
 ; CHECK-NEXT: br label %entry.split.split
 
 ; CHECK:    entry.split.split:
 ; CHECK-NEXT: %[[BUF2]] = phi ptr [ %[[BUF]], %setjmp.dispatch ], [ %buf, %entry.split ]
-; CHECK-NEXT: %[[SETJMPTABLESIZE3]] = phi i32 [ %[[SETJMPTABLESIZE4]], %entry.split ], [ %[[SETJMPTABLESIZE2]], %setjmp.dispatch ]
-; CHECK-NEXT: %[[SETJMPTABLE3]] = phi ptr [ %[[SETJMPTABLE4]], %entry.split ], [ %[[SETJMPTABLE2]], %setjmp.dispatch ]
 ; CHECK-NEXT: %setjmp.ret = phi i32 [ 0, %entry.split ], [ %[[VAL2]], %setjmp.dispatch ]
 ; CHECK-NEXT: invoke void @__wasm_longjmp(ptr %[[BUF2]], i32 1)
 ; CHECK-NEXT:         to label %.noexc unwind label %catch.dispatch.longjmp
@@ -67,13 +60,11 @@ entry:
 ; CHECK-NEXT: %val_gep = getelementptr { ptr, i32 }, ptr %thrown, i32 0, i32 1
 ; CHECK-NEXT: %env = load ptr, ptr %env_gep, align {{.*}}
 ; CHECK-NEXT: %val = load i32, ptr %val_gep, align 4
-; CHECK-NEXT: %setjmp.id = load [[PTR]], ptr %env, align {{.*}}
-; CHECK-NEXT: %label = call i32 @testSetjmp([[PTR]] %setjmp.id, ptr %[[SETJMPTABLE3]], i32 %[[SETJMPTABLESIZE3]]) [ "funclet"(token %1) ]
+; CHECK-NEXT: %label = call i32 @__wasm_setjmp_test(ptr %env, ptr %functionInvocationId) [ "funclet"(token %1) ]
 ; CHECK-NEXT: %2 = icmp eq i32 %label, 0
 ; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
 
 ; CHECK:    if.then:
-; CHECK-NEXT: tail call void @free(ptr %[[SETJMPTABLE3]]) [ "funclet"(token %1) ]
 ; CHECK-NEXT: call void @__wasm_longjmp(ptr %env, i32 %val) [ "funclet"(token %1) ]
 ; CHECK-NEXT: unreachable
 
@@ -142,10 +133,9 @@ declare ptr @__cxa_begin_catch(ptr)
 declare void @__cxa_end_catch()
 declare void @free(ptr)
 
-; JS glue function declarations
-; CHECK-DAG: declare i32 @getTempRet0()
-; CHECK-DAG: declare ptr @saveSetjmp(ptr, i32, ptr, i32)
-; CHECK-DAG: declare i32 @testSetjmp([[PTR]], ptr, i32)
+; Runtime glue function declarations
+; CHECK-DAG: declare void @__wasm_setjmp(ptr, i32, ptr)
+; CHECK-DAG: declare i32 @__wasm_setjmp_test(ptr, ptr)
 ; CHECK-DAG: declare void @__wasm_longjmp(ptr, i32)
 
 attributes #0 = { returns_twice }

>From 1b561bf2d7e36b043e24d50eda612bbb12f454ef Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 15:45:48 +0900
Subject: [PATCH 17/26] llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll:
 update

---
 llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll
index 25471eb50081b3..bd8db83a0e57ed 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll
@@ -108,8 +108,8 @@ catch:                                            ; preds = %catch.start
   call void @__cxa_end_catch() [ "funclet"(token %2) ]
   catchret from %2 to label %catchret.dest
 ; CHECK: catch:                                            ; preds = %catch.start
-; CHECK-NEXT:   %exn = load ptr, ptr %exn.slot15, align 4
-; CHECK-NEXT:   %5 = call ptr @__cxa_begin_catch(ptr %exn) #7 [ "funclet"(token %2) ]
+; CHECK-NEXT:   %exn = load ptr, ptr %exn.slot6, align 4
+; CHECK-NEXT:   %5 = call ptr @__cxa_begin_catch(ptr %exn) #6 [ "funclet"(token %2) ]
 ; CHECK-NEXT:   invoke void @__cxa_end_catch() [ "funclet"(token %2) ]
 ; CHECK-NEXT:           to label %.noexc unwind label %catch.dispatch.longjmp
 
@@ -265,7 +265,7 @@ ehcleanup:                                        ; preds = %entry
   ; (cleanuppad), whose parent is 'none', so we should unwind directly to
   ; %catch.dispatch.longjmp.
   %call2 = call noundef ptr @_ZN4TempD2Ev(ptr noundef %t) #2 [ "funclet"(token %0) ]
-; CHECK: %call13 = invoke {{.*}} ptr @_ZN4TempD2Ev(ptr
+; CHECK: %call11 = invoke {{.*}} ptr @_ZN4TempD2Ev(ptr
 ; CHECK-NEXT:    to label {{.*}} unwind label %catch.dispatch.longjmp
   cleanupret from %0 unwind to caller
 }

>From 1feae3f2f114241818d0a965686a1766339b08fc Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 15:49:18 +0900
Subject: [PATCH 18/26] WebAssemblyLowerEmscriptenEHSjLj.cpp: comment

---
 .../Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp  | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 98a30444826125..518b885216c032 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -198,11 +198,6 @@
 ///
 /// If there are calls to setjmp()
 ///
-/// 2) and 3): The same as 2) and 3) in Emscripten SjLj.
-/// (setjmpTable/setjmpTableSize initialization + setjmp callsite
-/// transformation)
-/// functionInvocationId
-///
 /// 2) In the function entry that calls setjmp, initialize
 ///    functionInvocationId as follows:
 ///

>From 79909d437682bdb569b2ce9b7556bb7b5a295b83 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 15:50:32 +0900
Subject: [PATCH 19/26] format

---
 .../Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp    | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 518b885216c032..9b2d33573cd71a 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -1311,7 +1311,8 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
     // This alloca'ed pointer is used by the runtime to identify function
     // inovactions. It's just for pointer comparisons. It will never
     // be dereferenced.
-    FunctionInvocationId = IRB.CreateAlloca(IRB.getInt32Ty(), nullptr, "functionInvocationId");
+    FunctionInvocationId =
+        IRB.CreateAlloca(IRB.getInt32Ty(), nullptr, "functionInvocationId");
     FunctionInvocationId->setDebugLoc(FirstDL);
   } else {
     // This instruction effectively means %setjmpTableSize = 4.

>From 1ed03ba2d01536b9cd4b7eb45fc7c91cd7e1cc50 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Wed, 13 Mar 2024 15:59:37 +0900
Subject: [PATCH 20/26] WebAssemblyLowerEmscriptenEHSjLj.cpp: comment

---
 .../WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp     | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 9b2d33573cd71a..7f80f8174f4428 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -318,8 +318,9 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
   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 *SaveSetjmpF = nullptr; // saveSetjmp()/__wasm_setjmp() (Emscripten)
+  Function *TestSetjmpF =
+      nullptr; // testSetjmp()/__wasm_setjmp_test() (Emscripten)
   Function *WasmLongjmpF = nullptr;       // __wasm_longjmp() (Emscripten)
   Function *CatchF = nullptr;             // wasm.catch() (intrinsic)
 
@@ -1019,14 +1020,14 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
       Type *Int32Ty = IRB.getInt32Ty();
 
       if (EnableWasmSjLj) {
-        // Register saveSetjmp function
+        // Register __wasm_setjmp function
         FunctionType *SetjmpFTy = SetjmpF->getFunctionType();
         FunctionType *FTy = FunctionType::get(
             IRB.getVoidTy(), {SetjmpFTy->getParamType(0), Int32Ty, Int32PtrTy},
             false);
         SaveSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp", &M);
 
-        // Register testSetjmp function
+        // Register __wasm_setjmp_test function
         FTy = FunctionType::get(Int32Ty, {Int32PtrTy, Int32PtrTy}, false);
         TestSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp_test", &M);
       } else {

>From cee4b1be9fe94a8cc08ebb38c620678bf3999671 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Fri, 15 Mar 2024 11:57:20 +0900
Subject: [PATCH 21/26] WebAssemblyLowerEmscriptenEHSjLj.cpp: adapt emscripten
 sjlj as well

---
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp      | 259 ++++--------------
 1 file changed, 51 insertions(+), 208 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 7f80f8174f4428..df3b252cc65382 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -129,27 +129,18 @@
 ///
 /// 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.
+/// 2) In the function entry that calls setjmp, initialize
+///    functionInvocationId as follows:
+///
+///    functionInvocationId = alloca()
 ///
 /// 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.
+///      __wasm_setjmp(env, label, functionInvocationId)
+///
+///    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;
@@ -196,20 +187,9 @@
 ///    into
 ///      __wasm_longjmp(env, val)
 ///
-/// If there are calls to setjmp()
-///
-/// 2) In the function entry that calls setjmp, initialize
-///    functionInvocationId as follows:
-///
-///    functionInvocationId = alloca()
-///
-/// 3) Lower
-///      setjmp(env)
-///    into
-///      __wasm_setjmp(env, label, functionInvocationId)
-///
-///    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.
+/// 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
@@ -318,9 +298,8 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
   Function *ResumeF = nullptr;            // __resumeException() (Emscripten)
   Function *EHTypeIDF = nullptr;          // llvm.eh.typeid.for() (intrinsic)
   Function *EmLongjmpF = nullptr;         // emscripten_longjmp() (Emscripten)
-  Function *SaveSetjmpF = nullptr; // saveSetjmp()/__wasm_setjmp() (Emscripten)
-  Function *TestSetjmpF =
-      nullptr; // testSetjmp()/__wasm_setjmp_test() (Emscripten)
+  Function *SaveSetjmpF = nullptr;        // __wasm_setjmp() (Emscripten)
+  Function *TestSetjmpF = nullptr;        // __wasm_setjmp_test() (Emscripten)
   Function *WasmLongjmpF = nullptr;       // __wasm_longjmp() (Emscripten)
   Function *CatchF = nullptr;             // wasm.catch() (intrinsic)
 
@@ -345,8 +324,7 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
   bool runEHOnFunction(Function &F);
   bool runSjLjOnFunction(Function &F);
   void handleLongjmpableCallsForEmscriptenSjLj(
-      Function &F, InstVector &SetjmpTableInsts,
-      InstVector &SetjmpTableSizeInsts,
+      Function &F, Instruction *FunctionInvocationId,
       SmallVectorImpl<PHINode *> &SetjmpRetPHIs);
   void
   handleLongjmpableCallsForWasmSjLj(Function &F,
@@ -356,7 +334,7 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
 
   Value *wrapInvoke(CallBase *CI);
   void wrapTestSetjmp(BasicBlock *BB, DebugLoc DL, Value *Threw,
-                      Value *SetjmpTable, Value *SetjmpTableSize, Value *&Label,
+                      Value *FunctionInvocationId, Value *&Label,
                       Value *&LongjmpResult, BasicBlock *&CallEmLongjmpBB,
                       PHINode *&CallEmLongjmpBBThrewPHI,
                       PHINode *&CallEmLongjmpBBThrewValuePHI,
@@ -628,7 +606,6 @@ static bool canLongjmp(const Value *Callee) {
 
   // 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 == "__wasm_setjmp" || CalleeName == "__wasm_setjmp_test" ||
       CalleeName == "getTempRet0" || CalleeName == "setTempRet0")
     return false;
@@ -702,7 +679,7 @@ static bool isEmAsmCall(const Value *Callee) {
 // 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);
+//   %label = __wasm_setjmp_test(%__THREW__.val, functionInvocationId);
 //   if (%label == 0)
 //     emscripten_longjmp(%__THREW__.val, %__threwValue.val);
 //   setTempRet0(%__threwValue.val);
@@ -714,10 +691,10 @@ static bool isEmAsmCall(const Value *Callee) {
 // 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) {
+    BasicBlock *BB, DebugLoc DL, Value *Threw, Value *FunctionInvocationId,
+    Value *&Label, Value *&LongjmpResult, BasicBlock *&CallEmLongjmpBB,
+    PHINode *&CallEmLongjmpBBThrewPHI, PHINode *&CallEmLongjmpBBThrewValuePHI,
+    BasicBlock *&EndBB) {
   Function *F = BB->getParent();
   Module *M = F->getParent();
   LLVMContext &C = M->getContext();
@@ -754,7 +731,7 @@ void WebAssemblyLowerEmscriptenEHSjLj::wrapTestSetjmp(
     CallEmLongjmpBBThrewValuePHI->addIncoming(ThrewValue, ThenBB1);
   }
 
-  // %label = testSetjmp(mem[%__THREW__.val], setjmpTable, setjmpTableSize);
+  // %label = __wasm_setjmp_test(%__THREW__.val, functionInvocationId);
   // if (%label == 0)
   IRB.SetInsertPoint(ThenBB1);
   BasicBlock *EndBB2 = BasicBlock::Create(C, "if.end2", F);
@@ -762,8 +739,8 @@ void WebAssemblyLowerEmscriptenEHSjLj::wrapTestSetjmp(
       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 *ThenLabel =
+      IRB.CreateCall(TestSetjmpF, {LoadedThrew, FunctionInvocationId}, "label");
   Value *Cmp2 = IRB.CreateICmpEQ(ThenLabel, IRB.getInt32(0));
   IRB.CreateCondBr(Cmp2, CallEmLongjmpBB, EndBB2);
 
@@ -1019,30 +996,16 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
       Type *Int32PtrTy = IRB.getPtrTy();
       Type *Int32Ty = IRB.getInt32Ty();
 
-      if (EnableWasmSjLj) {
-        // Register __wasm_setjmp function
-        FunctionType *SetjmpFTy = SetjmpF->getFunctionType();
-        FunctionType *FTy = FunctionType::get(
-            IRB.getVoidTy(), {SetjmpFTy->getParamType(0), Int32Ty, Int32PtrTy},
-            false);
-        SaveSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp", &M);
-
-        // Register __wasm_setjmp_test function
-        FTy = FunctionType::get(Int32Ty, {Int32PtrTy, Int32PtrTy}, false);
-        TestSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp_test", &M);
-      } else {
-        // Register saveSetjmp function
-        FunctionType *SetjmpFTy = SetjmpF->getFunctionType();
-        FunctionType *FTy = FunctionType::get(
-            Int32PtrTy,
-            {SetjmpFTy->getParamType(0), Int32Ty, Int32PtrTy, Int32Ty}, false);
-        SaveSetjmpF = getEmscriptenFunction(FTy, "saveSetjmp", &M);
-
-        // Register testSetjmp function
-        FTy = FunctionType::get(
-            Int32Ty, {getAddrIntType(&M), Int32PtrTy, Int32Ty}, false);
-        TestSetjmpF = getEmscriptenFunction(FTy, "testSetjmp", &M);
-      }
+      // Register __wasm_setjmp function
+      FunctionType *SetjmpFTy = SetjmpF->getFunctionType();
+      FunctionType *FTy = FunctionType::get(
+          IRB.getVoidTy(), {SetjmpFTy->getParamType(0), Int32Ty, Int32PtrTy},
+          false);
+      SaveSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp", &M);
+
+      // Register __wasm_setjmp_test function
+      FTy = FunctionType::get(Int32Ty, {Int32PtrTy, Int32PtrTy}, false);
+      TestSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp_test", &M);
 
       // wasm.catch() will be lowered down to wasm 'catch' instruction in
       // instruction selection.
@@ -1293,10 +1256,6 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
   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
 
@@ -1304,44 +1263,14 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
   DebugLoc FirstDL = getOrCreateDebugLoc(&*Entry->begin(), F.getSubprogram());
   SplitBlock(Entry, &*Entry->getFirstInsertionPt());
 
-  BinaryOperator *SetjmpTableSize;
-  Instruction *SetjmpTable;
   Instruction *FunctionInvocationId;
-  if (EnableWasmSjLj) {
-    IRB.SetInsertPoint(Entry->getTerminator());
-    // This alloca'ed pointer is used by the runtime to identify function
-    // inovactions. It's just for pointer comparisons. It will never
-    // be dereferenced.
-    FunctionInvocationId =
-        IRB.CreateAlloca(IRB.getInt32Ty(), nullptr, "functionInvocationId");
-    FunctionInvocationId->setDebugLoc(FirstDL);
-  } else {
-    // 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.
-    SetjmpTableSize = BinaryOperator::Create(Instruction::Add, IRB.getInt32(4),
-                                             IRB.getInt32(0), "setjmpTableSize",
-                                             Entry->getTerminator());
-    SetjmpTableSize->setDebugLoc(FirstDL);
-    IRB.SetInsertPoint(SetjmpTableSize);
-    // setjmpTable = (int *) malloc(40);
-    Type *IntPtrTy = getAddrIntType(&M);
-    Constant *size = ConstantInt::get(IntPtrTy, 40);
-    SetjmpTable = IRB.CreateMalloc(IntPtrTy, IRB.getInt32Ty(), size, 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.CreateStore(IRB.getInt32(0), SetjmpTable);
-    SetjmpTableInsts.push_back(SetjmpTable);
-    SetjmpTableSizeInsts.push_back(SetjmpTableSize);
-  }
+  IRB.SetInsertPoint(Entry->getTerminator());
+  // This alloca'ed pointer is used by the runtime to identify function
+  // inovactions. It's just for pointer comparisons. It will never
+  // be dereferenced.
+  FunctionInvocationId =
+      IRB.CreateAlloca(IRB.getInt32Ty(), nullptr, "functionInvocationId");
+  FunctionInvocationId->setDebugLoc(FirstDL);
 
   // Setjmp transformation
   SmallVector<PHINode *, 4> SetjmpRetPHIs;
@@ -1387,27 +1316,16 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
     // 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);
-    if (EnableWasmSjLj) {
-      Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),
-                       FunctionInvocationId};
-      IRB.CreateCall(SaveSetjmpF, Args);
-    } else {
-      Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),
-                       SetjmpTable, SetjmpTableSize};
-      Instruction *NewSetjmpTable =
-          IRB.CreateCall(SaveSetjmpF, Args, "setjmpTable");
-      Instruction *NewSetjmpTableSize =
-          IRB.CreateCall(GetTempRet0F, std::nullopt, "setjmpTableSize");
-      SetjmpTableInsts.push_back(NewSetjmpTable);
-      SetjmpTableSizeInsts.push_back(NewSetjmpTableSize);
-    }
+    Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),
+                     FunctionInvocationId};
+    IRB.CreateCall(SaveSetjmpF, Args);
     ToErase.push_back(CI);
   }
 
   // Handle longjmpable calls.
   if (EnableEmSjLj)
-    handleLongjmpableCallsForEmscriptenSjLj(
-        F, SetjmpTableInsts, SetjmpTableSizeInsts, SetjmpRetPHIs);
+    handleLongjmpableCallsForEmscriptenSjLj(F, FunctionInvocationId,
+                                            SetjmpRetPHIs);
   else // EnableWasmSjLj
     handleLongjmpableCallsForWasmSjLj(F, FunctionInvocationId, SetjmpRetPHIs);
 
@@ -1415,72 +1333,6 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
   for (Instruction *I : ToErase)
     I->eraseFromParent();
 
-  if (!EnableWasmSjLj) {
-    // 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));
-      IRB.SetInsertPoint(I);
-      auto *Free = IRB.CreateFree(SetjmpTable, Bundles);
-      Free->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(PointerType::get(C, 0), "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() .. }
@@ -1499,21 +1351,13 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
 // 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,
+    Function &F, Instruction *FunctionInvocationId,
     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
@@ -1661,10 +1505,9 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForEmscriptenSjLj(
       Value *Label = nullptr;
       Value *LongjmpResult = nullptr;
       BasicBlock *EndBB = nullptr;
-      wrapTestSetjmp(BB, CI->getDebugLoc(), Threw, SetjmpTable, SetjmpTableSize,
-                     Label, LongjmpResult, CallEmLongjmpBB,
-                     CallEmLongjmpBBThrewPHI, CallEmLongjmpBBThrewValuePHI,
-                     EndBB);
+      wrapTestSetjmp(BB, CI->getDebugLoc(), Threw, FunctionInvocationId, Label,
+                     LongjmpResult, CallEmLongjmpBB, CallEmLongjmpBBThrewPHI,
+                     CallEmLongjmpBBThrewValuePHI, EndBB);
       assert(Label && LongjmpResult && EndBB);
 
       // Create switch instruction
@@ -1728,12 +1571,12 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
   IRB.SetCurrentDebugLocation(FirstDL);
 
   // Add setjmp.dispatch BB right after the entry block. Because we have
-  // initialized setjmpTable/setjmpTableSize in the entry block and split the
+  // initialized functionInvocationId 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
+  //   functionInvocationId initialization
   // setjmp.dispatch:
   //   switch will be inserted here later
   // entry.split: (OrigEntry)

>From 8629e75fd571bd10a355af7a391557fd572628f1 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Fri, 15 Mar 2024 12:15:14 +0900
Subject: [PATCH 22/26] fix __wasm_setjmp_test invocation

---
 .../Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp   | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index df3b252cc65382..8799ceb4715944 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -737,10 +737,8 @@ void WebAssemblyLowerEmscriptenEHSjLj::wrapTestSetjmp(
   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, FunctionInvocationId}, "label");
+      IRB.CreateCall(TestSetjmpF, {ThrewPtr, FunctionInvocationId}, "label");
   Value *Cmp2 = IRB.CreateICmpEQ(ThenLabel, IRB.getInt32(0));
   IRB.CreateCondBr(Cmp2, CallEmLongjmpBB, EndBB2);
 

>From 33d4e0f7d1fb2bb112ea8fac138c915f6fbf7afe Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Fri, 15 Mar 2024 12:16:43 +0900
Subject: [PATCH 23/26] rename variables

SaveSetjmpF -> WasmSetjmpF
TestSetjmpF -> WasmSetjmpTestF
---
 .../WebAssemblyLowerEmscriptenEHSjLj.cpp       | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 8799ceb4715944..7e96a7cc2e93c0 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -298,8 +298,8 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
   Function *ResumeF = nullptr;            // __resumeException() (Emscripten)
   Function *EHTypeIDF = nullptr;          // llvm.eh.typeid.for() (intrinsic)
   Function *EmLongjmpF = nullptr;         // emscripten_longjmp() (Emscripten)
-  Function *SaveSetjmpF = nullptr;        // __wasm_setjmp() (Emscripten)
-  Function *TestSetjmpF = nullptr;        // __wasm_setjmp_test() (Emscripten)
+  Function *WasmSetjmpF = nullptr;        // __wasm_setjmp() (Emscripten)
+  Function *WasmSetjmpTestF = nullptr;    // __wasm_setjmp_test() (Emscripten)
   Function *WasmLongjmpF = nullptr;       // __wasm_longjmp() (Emscripten)
   Function *CatchF = nullptr;             // wasm.catch() (intrinsic)
 
@@ -737,8 +737,8 @@ void WebAssemblyLowerEmscriptenEHSjLj::wrapTestSetjmp(
   BasicBlock *EndBB2 = BasicBlock::Create(C, "if.end2", F);
   Value *ThrewPtr =
       IRB.CreateIntToPtr(Threw, getAddrPtrType(M), Threw->getName() + ".p");
-  Value *ThenLabel =
-      IRB.CreateCall(TestSetjmpF, {ThrewPtr, FunctionInvocationId}, "label");
+  Value *ThenLabel = IRB.CreateCall(WasmSetjmpTestF,
+                                    {ThrewPtr, FunctionInvocationId}, "label");
   Value *Cmp2 = IRB.CreateICmpEQ(ThenLabel, IRB.getInt32(0));
   IRB.CreateCondBr(Cmp2, CallEmLongjmpBB, EndBB2);
 
@@ -999,11 +999,11 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
       FunctionType *FTy = FunctionType::get(
           IRB.getVoidTy(), {SetjmpFTy->getParamType(0), Int32Ty, Int32PtrTy},
           false);
-      SaveSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp", &M);
+      WasmSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp", &M);
 
       // Register __wasm_setjmp_test function
       FTy = FunctionType::get(Int32Ty, {Int32PtrTy, Int32PtrTy}, false);
-      TestSetjmpF = getEmscriptenFunction(FTy, "__wasm_setjmp_test", &M);
+      WasmSetjmpTestF = getEmscriptenFunction(FTy, "__wasm_setjmp_test", &M);
 
       // wasm.catch() will be lowered down to wasm 'catch' instruction in
       // instruction selection.
@@ -1049,7 +1049,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
     if (V && V->use_empty())
       V->eraseFromParent();
   for (auto *V : {GetTempRet0F, SetTempRet0F, ResumeF, EHTypeIDF, EmLongjmpF,
-                  SaveSetjmpF, TestSetjmpF, WasmLongjmpF, CatchF})
+                  WasmSetjmpF, WasmSetjmpTestF, WasmLongjmpF, CatchF})
     if (V && V->use_empty())
       V->eraseFromParent();
 
@@ -1316,7 +1316,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
     IRB.SetInsertPoint(CI);
     Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),
                      FunctionInvocationId};
-    IRB.CreateCall(SaveSetjmpF, Args);
+    IRB.CreateCall(WasmSetjmpF, Args);
     ToErase.push_back(CI);
   }
 
@@ -1619,7 +1619,7 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
   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 *Label = IRB.CreateCall(TestSetjmpF, {EnvP, FunctionInvocationId},
+  Value *Label = IRB.CreateCall(WasmSetjmpTestF, {EnvP, FunctionInvocationId},
                                 OperandBundleDef("funclet", CatchPad), "label");
   Value *Cmp = IRB.CreateICmpEQ(Label, IRB.getInt32(0));
   IRB.CreateCondBr(Cmp, ThenBB, EndBB);

>From 9bfc7e5af3506abbf32d7f81d7a793bce842dd1d Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Fri, 15 Mar 2024 12:20:40 +0900
Subject: [PATCH 24/26] comment

---
 .../lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 7e96a7cc2e93c0..bb3a496a9dc07a 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -187,6 +187,8 @@
 ///    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)

>From 0d1872fe2a04d75db8489c82b8e7f3ebcea2464a Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Fri, 15 Mar 2024 12:27:41 +0900
Subject: [PATCH 25/26] comment

---
 .../Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp  | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index bb3a496a9dc07a..1a96266f07d904 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -132,7 +132,10 @@
 /// 2) In the function entry that calls setjmp, initialize
 ///    functionInvocationId as follows:
 ///
-///    functionInvocationId = alloca()
+///    functionInvocationId = alloca(4)
+///
+///    Note: the alloca size is not important as this pointer is
+///    merely used for pointer comparisions.
 ///
 /// 3) Lower
 ///      setjmp(env)

>From 68e1118f6fda9dbcd61a1cab90f2adcd179ba1b8 Mon Sep 17 00:00:00 2001
From: YAMAMOTO Takashi <yamamoto at midokura.com>
Date: Fri, 15 Mar 2024 14:59:30 +0900
Subject: [PATCH 26/26] update llvm/test/CodeGen/WebAssembly/lower-em-*.ll

---
 .../WebAssembly/lower-em-ehsjlj-options.ll    |  4 +-
 .../CodeGen/WebAssembly/lower-em-ehsjlj.ll    |  5 +--
 .../WebAssembly/lower-em-sjlj-alias.ll        |  2 +-
 .../WebAssembly/lower-em-sjlj-debuginfo.ll    | 35 ++----------------
 .../test/CodeGen/WebAssembly/lower-em-sjlj.ll | 37 ++++++-------------
 5 files changed, 19 insertions(+), 64 deletions(-)

diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj-options.ll b/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj-options.ll
index aa4d87756c87d0..4a63c812d6ae9a 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj-options.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj-options.ll
@@ -59,12 +59,12 @@ entry:
   %call = call i32 @setjmp(ptr %buf) #0
   call void @longjmp(ptr %buf, i32 1) #1
   unreachable
-; SJLJ: call saveSetjmp
+; SJLJ: call __wasm_setjmp
 ; SJLJ: i32.const emscripten_longjmp
 ; SJLJ-NOT: i32.const emscripten_longjmp_jmpbuf
 ; SJLJ: call invoke_vii
 ; SJLJ-NOT: call "__invoke_void_ptr_i32"
-; SJLJ: call testSetjmp
+; SJLJ: call __wasm_setjmp_test
 
 ; NONE: call setjmp
 ; NONE: call longjmp
diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll
index 7cf05cc922cd37..32942cd92e684f 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll
@@ -49,7 +49,7 @@ try.cont:                                         ; preds = %lpad, %entry
 
 ; longjmp checking part
 ; CHECK:    if.then1:
-; CHECK:      call i32 @testSetjmp
+; CHECK:      call i32 @__wasm_setjmp_test
 }
 
 ; @foo can either throw an exception or longjmp. Because this function doesn't
@@ -117,7 +117,6 @@ if.end:                                           ; preds = %entry
 
 ; CHECK:    rethrow.exn:
 ; CHECK-NEXT: %exn = call ptr @__cxa_find_matching_catch_2()
-; CHECK-NEXT: call void @free(ptr %setjmpTable{{.*}})
 ; CHECK-NEXT: call void @__resumeException(ptr %exn)
 ; CHECK-NEXT: unreachable
 
@@ -147,7 +146,6 @@ throw:                                            ; preds = %if.end, %entry
   unreachable
 
 ; CHECK:    throw:
-; CHECK-NEXT: call void @free(ptr %setjmpTable{{.*}})
 ; CHECK-NEXT: call void @__cxa_throw(ptr null, ptr null, ptr null)
 ; CHECK-NEXT: unreachable
 }
@@ -208,7 +206,6 @@ return:                                           ; preds = %entry, %if.end
 
 ; CHECK:    rethrow.exn:
 ; CHECK-NEXT: %exn = call ptr @__cxa_find_matching_catch_2()
-; CHECK-NEXT: tail call void @free(ptr %setjmpTable{{.*}})
 ; CHECK-NEXT: call void @__resumeException(ptr %exn)
 ; CHECK-NEXT: unreachable
 }
diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-alias.ll b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-alias.ll
index 1a85a63e44ad4b..79ae16191d6b3c 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-alias.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-alias.ll
@@ -12,7 +12,7 @@ target triple = "wasm32-unknown-emscripten"
 ; CHECK-LABEL: @malloc_test
 define void @malloc_test() {
 entry:
-  ; CHECK: call ptr @malloc
+  ; CHECK: alloca i32
   %retval = alloca i32, align 4
   %jmp = alloca [1 x %struct.__jmp_buf_tag], align 16
   store i32 0, ptr %retval, align 4
diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-debuginfo.ll b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-debuginfo.ll
index 4f694151c76132..fec9836a1607c5 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-debuginfo.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-debuginfo.ll
@@ -16,25 +16,22 @@ entry:
   call void @foo(), !dbg !7
   ret void, !dbg !8
 ; CHECK: entry:
-  ; CHECK-NEXT: call ptr @malloc(i32 40), !dbg ![[DL0:.*]]
+  ; CHECK-NEXT: %functionInvocationId = alloca i32, align 4, !dbg ![[DL0:.*]]
 
 ; CHECK: entry.split:
   ; CHECK: alloca {{.*}}, !dbg ![[DL0]]
-  ; CHECK: call ptr @saveSetjmp{{.*}}, !dbg ![[DL1:.*]]
-  ; CHECK-NEXT: call i32 @getTempRet0{{.*}}, !dbg ![[DL1]]
+  ; CHECK: call void @__wasm_setjmp{{.*}}, !dbg ![[DL1:.*]]
   ; CHECK-NEXT: br {{.*}}, !dbg ![[DL2:.*]]
 
 ; CHECK: entry.split.split:
   ; CHECK: call {{.*}} void @__invoke_void{{.*}}, !dbg ![[DL2]]
 
 ; CHECK: entry.split.split.split:
-  ; CHECK-NEXT: call void @free{{.*}}, !dbg ![[DL3:.*]]
 
 ; CHECK: if.then1:
-  ; CHECK: call i32 @testSetjmp{{.*}}, !dbg ![[DL2]]
+  ; CHECK: call i32 @__wasm_setjmp_test{{.*}}, !dbg ![[DL2]]
 
 ; CHECK: if.end:
-  ; CHECK: call i32 @getTempRet0{{.*}}, !dbg ![[DL2]]
 
 ; CHECK: call.em.longjmp:
   ; CHECK: call void @emscripten_longjmp{{.*}}, !dbg ![[DL2]]
@@ -43,26 +40,6 @@ entry:
   ; CHECK: call void @setTempRet0{{.*}}, !dbg ![[DL2]]
 }
 
-; No instruction has debug info but the current function (setjmp_debug_info2)
-; and the called function (malloc / free) have DISubprograms, so the newly
-; generated calls should have debug info attached. We don't have an instruction
-; to take debug info from, so we create dummy debug info.
-define void @setjmp_debug_info1() !dbg !9 {
-; CHECK-LABEL: @setjmp_debug_info1
-entry:
-  %buf = alloca [1 x %struct.__jmp_buf_tag], align 16
-  %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], ptr %buf, i32 0, i32 0
-  %call = call i32 @setjmp(ptr %arraydecay) #0
-  call void @foo()
-  ret void
-  ; CHECK: call ptr @malloc(i32 40), !dbg ![[DL_DUMMY:.*]]
-  ; CHECK: call void @free{{.*}}, !dbg ![[DL_DUMMY]]
-}
-
-; Note that these functions have DISubprograms.
-declare !dbg !10 ptr @malloc(i32)
-declare !dbg !11 void @free(ptr)
-
 declare void @foo()
 ; Function Attrs: returns_twice
 declare i32 @setjmp(ptr) #0
@@ -79,9 +56,3 @@ declare i32 @setjmp(ptr) #0
 !6 = !DILocation(line:4, scope: !3)
 !7 = !DILocation(line:5, scope: !3)
 !8 = !DILocation(line:6, scope: !3)
-!9 = distinct !DISubprogram(name: "setjmp_debug_info1", unit:!2, file: !1, line: 50)
-!10 = !DISubprogram(name: "malloc", file: !1, line: 10, isDefinition: false)
-!11 = !DISubprogram(name: "free", file: !1, line: 20, isDefinition: false)
-
-; Dummy debug info generated
-; CHECK: ![[DL_DUMMY]] = !DILocation(line: 50, column: 1, scope: !9)
diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
index 7115b01ed1618e..27ec95a2c462ab 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
@@ -22,15 +22,12 @@ entry:
   call void @longjmp(ptr %buf, i32 1) #1
   unreachable
 ; CHECK: entry:
-; CHECK-NEXT: %[[MALLOCCALL:.*]] = tail call ptr @malloc([[PTR]] 40)
-; CHECK-NEXT: store i32 0, ptr %[[MALLOCCALL]]
-; CHECK-NEXT: %[[SETJMP_TABLE_SIZE:.*]] = add i32 4, 0
+; CHECK-NEXT: %functionInvocationId = alloca i32, align 4
 ; CHECK-NEXT: br label %entry.split
 
 ; CHECK: entry.split
 ; CHECK-NEXT: %[[BUF:.*]] = alloca [1 x %struct.__jmp_buf_tag]
-; CHECK-NEXT: %[[SETJMP_TABLE1:.*]] = call ptr @saveSetjmp(ptr %[[BUF]], i32 1, ptr %[[MALLOCCALL]], i32 %[[SETJMP_TABLE_SIZE]])
-; CHECK-NEXT: %[[SETJMP_TABLE_SIZE1:.*]] = call i32 @getTempRet0()
+; CHECK-NEXT: call void @__wasm_setjmp(ptr %[[BUF]], i32 1, ptr %functionInvocationId)
 ; CHECK-NEXT: br label %entry.split.split
 
 ; CHECK: entry.split.split:
@@ -51,8 +48,7 @@ entry:
 
 ; CHECK: if.then1:
 ; CHECK-NEXT: %[[__THREW__VAL_P:.*]] = inttoptr [[PTR]] %[[__THREW__VAL]] to ptr
-; CHECK-NEXT: %[[__THREW__VAL_P_LOADED:.*]] = load [[PTR]], ptr %[[__THREW__VAL_P]]
-; CHECK-NEXT: %[[LABEL:.*]] = call i32 @testSetjmp([[PTR]] %[[__THREW__VAL_P_LOADED]], ptr %[[SETJMP_TABLE1]], i32 %[[SETJMP_TABLE_SIZE1]])
+; CHECK-NEXT: %[[LABEL:.*]] = call i32 @__wasm_setjmp_test(ptr %[[__THREW__VAL_P]], ptr %functionInvocationId)
 ; CHECK-NEXT: %[[CMP:.*]] = icmp eq i32 %[[LABEL]], 0
 ; CHECK-NEXT: br i1 %[[CMP]], label %call.em.longjmp, label %if.end2
 
@@ -69,7 +65,6 @@ entry:
 ; CHECK: call.em.longjmp:
 ; CHECK-NEXT: %threw.phi = phi [[PTR]] [ %[[__THREW__VAL]], %if.then1 ]
 ; CHECK-NEXT: %threwvalue.phi = phi i32 [ %[[THREWVALUE_VAL]], %if.then1 ]
-; CHECK-NEXT: tail call void @free(ptr %[[SETJMP_TABLE1]])
 ; CHECK-NEXT: call void @emscripten_longjmp([[PTR]] %threw.phi, i32 %threwvalue.phi)
 ; CHECK-NEXT: unreachable
 
@@ -87,13 +82,12 @@ entry:
   call void @foo()
   ret void
 ; CHECK: entry:
-; CHECK: %[[SETJMP_TABLE:.*]] = call ptr @saveSetjmp(
+; CHECK: call void @__wasm_setjmp(
 
 ; CHECK: entry.split.split:
 ; CHECK: @__invoke_void(ptr @foo)
 
 ; CHECK: entry.split.split.split:
-; CHECK-NEXT: tail call void @free(ptr %[[SETJMP_TABLE]])
 ; CHECK-NEXT: ret void
 }
 
@@ -110,9 +104,8 @@ entry:
   call void @foo()
   ret void
 ; CHECK: call.em.longjmp:
-; CHECK-NEXT:  %threw.phi = phi [[PTR]] [ %__THREW__.val, %if.then1 ], [ %__THREW__.val4, %if.then15 ]
-; CHECK-NEXT:  %threwvalue.phi = phi i32 [ %__threwValue.val, %if.then1 ], [ %__threwValue.val8, %if.then15 ]
-; CHECK-NEXT: tail call void @free(ptr %[[SETJMP_TABLE1]])
+; CHECK-NEXT:  %threw.phi = phi [[PTR]] [ %__THREW__.val, %if.then1 ], [ %__THREW__.val2, %if.then13 ]
+; CHECK-NEXT:  %threwvalue.phi = phi i32 [ %__threwValue.val, %if.then1 ], [ %__threwValue.val6, %if.then13 ]
 ; CHECK-NEXT: call void @emscripten_longjmp([[PTR]] %threw.phi, i32 %threwvalue.phi)
 ; CHECK-NEXT: unreachable
 }
@@ -145,7 +138,6 @@ entry:
   %cmp = icmp sgt i32 %n, 5
   br i1 %cmp, label %if.then, label %if.end
 ; CHECK: entry:
-; CHECK: %[[SETJMP_TABLE_SIZE0:.*]] = add i32 4, 0
 
 if.then:                                          ; preds = %entry
   %0 = load i32, ptr @global_var, align 4
@@ -154,13 +146,10 @@ if.then:                                          ; preds = %entry
   br label %if.end
 ; CHECK: if.then:
 ; CHECK: %[[VAR0:.*]] = load i32, ptr @global_var, align 4
-; CHECK: %[[SETJMP_TABLE1:.*]] = call ptr @saveSetjmp(
-; CHECK-NEXT: %[[SETJMP_TABLE_SIZE1:.*]] = call i32 @getTempRet0()
+; CHECK: call void @__wasm_setjmp(
 
 ; CHECK: if.then.split:
-; CHECK: %[[VAR1:.*]] = phi i32 [ %[[VAR2:.*]], %if.end3 ], [ %[[VAR0]], %if.then ]
-; CHECK: %[[SETJMP_TABLE_SIZE2:.*]] = phi i32 [ %[[SETJMP_TABLE_SIZE1]], %if.then ], [ %[[SETJMP_TABLE_SIZE3:.*]], %if.end3 ]
-; CHECK: %[[SETJMP_TABLE2:.*]] = phi ptr [ %[[SETJMP_TABLE1]], %if.then ], [ %[[SETJMP_TABLE3:.*]], %if.end3 ]
+; CHECK: %[[VAR1:.*]] = phi i32 [ %[[VAR2:.*]], %if.end1 ], [ %[[VAR0]], %if.then ]
 ; CHECK: store i32 %[[VAR1]], ptr @global_var, align 4
 
 if.end:                                           ; preds = %if.then, %entry
@@ -168,8 +157,6 @@ if.end:                                           ; preds = %if.then, %entry
   unreachable
 ; CHECK: if.end:
 ; CHECK: %[[VAR2]] = phi i32 [ %[[VAR1]], %if.then.split ], [ undef, %entry.split ]
-; CHECK: %[[SETJMP_TABLE_SIZE3]] = phi i32 [ %[[SETJMP_TABLE_SIZE2]], %if.then.split ], [ %[[SETJMP_TABLE_SIZE0]], %entry.split ]
-; CHECK: %[[SETJMP_TABLE3]] = phi ptr [ %[[SETJMP_TABLE2]], %if.then.split ], [ %setjmpTable, %entry.split ]
 }
 
 ; Test a case when a function only calls other functions that are neither setjmp nor longjmp
@@ -296,8 +283,8 @@ declare void @free(ptr)
 ; JS glue functions and invoke wrappers declaration
 ; CHECK-DAG: declare i32 @getTempRet0()
 ; CHECK-DAG: declare void @setTempRet0(i32)
-; CHECK-DAG: declare ptr @saveSetjmp(ptr, i32, ptr, i32)
-; CHECK-DAG: declare i32 @testSetjmp([[PTR]], ptr, i32)
+; CHECK-DAG: declare void @__wasm_setjmp(ptr, i32, ptr)
+; CHECK-DAG: declare i32 @__wasm_setjmp_test(ptr, ptr)
 ; CHECK-DAG: declare void @emscripten_longjmp([[PTR]], i32)
 ; CHECK-DAG: declare void @__invoke_void(ptr)
 
@@ -308,8 +295,8 @@ attributes #3 = { allocsize(0) }
 ; CHECK-DAG: attributes #{{[0-9]+}} = { nounwind "wasm-import-module"="env" "wasm-import-name"="getTempRet0" }
 ; CHECK-DAG: attributes #{{[0-9]+}} = { nounwind "wasm-import-module"="env" "wasm-import-name"="setTempRet0" }
 ; CHECK-DAG: attributes #{{[0-9]+}} = { "wasm-import-module"="env" "wasm-import-name"="__invoke_void" }
-; CHECK-DAG: attributes #{{[0-9]+}} = { "wasm-import-module"="env" "wasm-import-name"="saveSetjmp" }
-; CHECK-DAG: attributes #{{[0-9]+}} = { "wasm-import-module"="env" "wasm-import-name"="testSetjmp" }
+; CHECK-DAG: attributes #{{[0-9]+}} = { "wasm-import-module"="env" "wasm-import-name"="__wasm_setjmp" }
+; CHECK-DAG: attributes #{{[0-9]+}} = { "wasm-import-module"="env" "wasm-import-name"="__wasm_setjmp_test" }
 ; CHECK-DAG: attributes #{{[0-9]+}} = { noreturn "wasm-import-module"="env" "wasm-import-name"="emscripten_longjmp" }
 ; CHECK-DAG: attributes #{{[0-9]+}} = { "wasm-import-module"="env" "wasm-import-name"="__invoke_ptr_i32_ptr" }
 ; CHECK-DAG: attributes #[[ALLOCSIZE_ATTR]] = { allocsize(1) }



More information about the llvm-commits mailing list