[llvm] 3419e85 - [WebAssembly] Free setjmpTable before exiting calls in EmSjLj
Heejin Ahn via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 30 21:46:37 PDT 2021
Author: Heejin Ahn
Date: 2021-08-30T21:46:25-07:00
New Revision: 3419e85b15e35e4b5b4d0cd8153fdbe0958e80c7
URL: https://github.com/llvm/llvm-project/commit/3419e85b15e35e4b5b4d0cd8153fdbe0958e80c7
DIFF: https://github.com/llvm/llvm-project/commit/3419e85b15e35e4b5b4d0cd8153fdbe0958e80c7.diff
LOG: [WebAssembly] Free setjmpTable before exiting calls in EmSjLj
This is an improvement over D107852. We don't need to enumerate specific
function names; we can just check for `noreturn` attribute. This also
requires us to make sure `__resumeExeption` and `emscripten_longjmp`
have `noreturn` attribute too; one of them is a JS function and the
other calls a JS function so Clang does not have a way to deduce they
don't return.
This is effectively NFC, because I'm not sure if there is an additional
case this case covers; if we add a custom function call that has
`noreturn` attribute, it will be processed within the SjLj handling and
turned into `__invoke` call. So this really applies to some special
functions like `emscripten_longjmp`.
Reviewed By: dschuff
Differential Revision: https://reviews.llvm.org/D108955
Added:
Modified:
llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 2e5b71ac5974..e9cad5e05678 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -434,15 +434,6 @@ Value *WebAssemblyLowerEmscriptenEHSjLj::wrapInvoke(CallBase *CI) {
Module *M = CI->getModule();
LLVMContext &C = M->getContext();
- // If we are calling a function that is noreturn, we must remove that
- // attribute. The code we insert here does expect it to return, after we
- // catch the exception.
- if (CI->doesNotReturn()) {
- if (auto *F = CI->getCalledFunction())
- F->removeFnAttr(Attribute::NoReturn);
- CI->removeFnAttr(Attribute::NoReturn);
- }
-
IRBuilder<> IRB(C);
IRB.SetInsertPoint(CI);
@@ -760,6 +751,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
FunctionType *ResumeFTy =
FunctionType::get(IRB.getVoidTy(), IRB.getInt8PtrTy(), false);
ResumeF = getEmscriptenFunction(ResumeFTy, "__resumeException", &M);
+ ResumeF->addFnAttr(Attribute::NoReturn);
// Register llvm_eh_typeid_for function
FunctionType *EHTypeIDTy =
@@ -790,6 +782,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
FunctionType *FTy = FunctionType::get(
IRB.getVoidTy(), {getAddrIntType(&M), IRB.getInt32Ty()}, false);
EmLongjmpF = getEmscriptenFunction(FTy, "emscripten_longjmp", &M);
+ EmLongjmpF->addFnAttr(Attribute::NoReturn);
if (SetjmpF) {
// Register saveSetjmp function
@@ -1152,11 +1145,16 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &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 *CB = dyn_cast<CallBase>(&I)) {
- StringRef CalleeName = CB->getCalledOperand()->getName();
- if (CalleeName == "__resumeException" ||
- CalleeName == "emscripten_longjmp" || CalleeName == "__cxa_throw")
+ if (auto *CI = dyn_cast<CallInst>(&I)) {
+ bool IsNoReturn = CI->hasFnAttr(Attribute::NoReturn);
+ if (auto *CalleeF = dyn_cast<Function>(CI->getCalledOperand()))
+ IsNoReturn |= CalleeF->hasFnAttribute(Attribute::NoReturn);
+ if (IsNoReturn)
ExitingInsts.push_back(&I);
}
}
diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
index 85ea09ef538b..5615901316b6 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
@@ -311,7 +311,7 @@ attributes #3 = { allocsize(0) }
; 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"="emscripten_longjmp" }
+; 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_i8*_i32_%struct.__jmp_buf_tag*" }
; CHECK-DAG: attributes #[[ALLOCSIZE_ATTR]] = { allocsize(1) }
More information about the llvm-commits
mailing list