https://github.com/QuantumSegfault updated https://github.com/llvm/llvm-project/pull/209282
>From 03a177003d05f9275a59ca6e6c79952abda782da Mon Sep 17 00:00:00 2001 From: Demetrius Kanios <[email protected]> Date: Mon, 13 Jul 2026 12:30:49 -0700 Subject: [PATCH 1/2] Call declared personality function --- clang/lib/CodeGen/CGException.cpp | 9 ++- libcxxabi/src/cxa_personality.cpp | 22 ++++++- libunwind/include/unwind.h | 4 ++ libunwind/include/unwind_wasm.h | 27 ++++++++ libunwind/src/Unwind-wasm.c | 39 ----------- libunwind/src/config.h | 2 +- llvm/include/llvm/IR/RuntimeLibcalls.td | 4 -- llvm/lib/CodeGen/WasmEHPrepare.cpp | 64 ++++++++----------- .../WebAssembly/cfg-stackify-eh-legacy.ll | 2 +- .../WebAssembly/cfg-stackify-eh-legacy.mir | 2 +- .../CodeGen/WebAssembly/cfg-stackify-eh.ll | 8 +-- llvm/test/CodeGen/WebAssembly/eh-lsda.ll | 2 +- .../CodeGen/WebAssembly/exception-legacy.ll | 4 +- .../CodeGen/WebAssembly/exception-legacy.mir | 2 +- llvm/test/CodeGen/WebAssembly/exception.ll | 4 +- .../CodeGen/WebAssembly/function-info.mir | 2 +- .../WebAssembly/lower-wasm-ehsjlj-phi.ll | 2 +- .../CodeGen/WebAssembly/lower-wasm-ehsjlj.ll | 2 +- .../WebAssembly/wasm-eh-em-sjlj-error.ll | 2 +- .../wasm-eh-invalid-personality.ll | 2 +- .../CodeGen/WebAssembly/wasm-eh-prepare.ll | 8 +-- .../wasm-eh-sjlj-setjmp-within-catch.ll | 2 +- 22 files changed, 108 insertions(+), 107 deletions(-) create mode 100644 libunwind/include/unwind_wasm.h diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 99dfaa80be429..25b57a0334413 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -265,7 +265,14 @@ const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) { static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality) { - return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true), + llvm::FunctionType *FTy; + + if (Personality.isWasmPersonality()) { + FTy = llvm::FunctionType::get(CGM.VoidTy, {CGM.VoidPtrTy}, false); + } else { + FTy = llvm::FunctionType::get(CGM.Int32Ty, true); + } + return CGM.CreateRuntimeFunction(FTy, Personality.PersonalityFn, llvm::AttributeList(), /*Local=*/true); } diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp index 6599f89740113..970cd0355ddf4 100644 --- a/libcxxabi/src/cxa_personality.cpp +++ b/libcxxabi/src/cxa_personality.cpp @@ -1011,9 +1011,7 @@ static inline void get_landing_pad(__cxa_catch_temp_type &dest, #endif } -#ifdef __WASM_EXCEPTIONS__ -_Unwind_Reason_Code __gxx_personality_wasm0 -#elif defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) +#if (defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)) || defined(__WASM_EXCEPTIONS__) static _Unwind_Reason_Code __gxx_personality_imp #else _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code @@ -1114,6 +1112,24 @@ __gxx_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame, } #endif + +#ifdef __WASM_EXCEPTIONS__ +extern "C" _LIBCXXABI_FUNC_VIS +void __gxx_wasm_personality_v0(void* exception_ptr) { + struct _Unwind_Exception *exception_object = + (struct _Unwind_Exception *)exception_ptr; + + // Reset the selector. + __wasm_lpad_context.selector = 0; + + // Call personality function. Wasm does not have two-phase unwinding, so we + // only do the cleanup phase. + __gxx_personality_imp( + 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object, + (struct _Unwind_Context *)&__wasm_lpad_context); +} +#endif + #else extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*, _Unwind_Context*); diff --git a/libunwind/include/unwind.h b/libunwind/include/unwind.h index b1775d3a3decc..93a9d92f327d3 100644 --- a/libunwind/include/unwind.h +++ b/libunwind/include/unwind.h @@ -61,6 +61,10 @@ typedef struct _Unwind_Context _Unwind_Context; // opaque #include <unwind_itanium.h> #endif +#if defined(__WASM_EXCEPTIONS__) +#include <unwind_wasm.h> +#endif + typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int version, _Unwind_Action actions, diff --git a/libunwind/include/unwind_wasm.h b/libunwind/include/unwind_wasm.h new file mode 100644 index 0000000000000..7bf3f30562bd8 --- /dev/null +++ b/libunwind/include/unwind_wasm.h @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef __WASM_UNWIND_H__ +#define __WASM_UNWIND_H__ + +#include <threads.h> + +struct _Unwind_LandingPadContext { + // Input information to personality function + uintptr_t lpad_index; // landing pad index + uintptr_t lsda; // LSDA address + + // Output information computed by personality function + uintptr_t selector; // selector value +}; + +// Communication channel between compiler-generated user code and personality +// function +extern thread_local struct _Unwind_LandingPadContext __wasm_lpad_context; + +#endif // __WASM_UNWIND_H__ diff --git a/libunwind/src/Unwind-wasm.c b/libunwind/src/Unwind-wasm.c index c0ca9b775d244..81793b3f36060 100644 --- a/libunwind/src/Unwind-wasm.c +++ b/libunwind/src/Unwind-wasm.c @@ -19,47 +19,8 @@ #include "unwind.h" #include <threads.h> -_Unwind_Reason_Code __gxx_personality_wasm0(int version, _Unwind_Action actions, - uint64_t exceptionClass, - _Unwind_Exception *unwind_exception, - _Unwind_Context *context); - -struct _Unwind_LandingPadContext { - // Input information to personality function - uintptr_t lpad_index; // landing pad index - uintptr_t lsda; // LSDA address - - // Output information computed by personality function - uintptr_t selector; // selector value -}; - -// Communication channel between compiler-generated user code and personality -// function thread_local struct _Unwind_LandingPadContext __wasm_lpad_context; -/// Calls to this function are in landing pads in compiler-generated user code. -/// In other EH schemes, stack unwinding is done by libunwind library, which -/// calls the personality function for each frame it lands. On the other hand, -/// WebAssembly stack unwinding process is performed by a VM, and the -/// personality function cannot be called from there. So the compiler inserts a -/// call to this function in landing pads in the user code, which in turn calls -/// the personality function. -_Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) { - struct _Unwind_Exception *exception_object = - (struct _Unwind_Exception *)exception_ptr; - _LIBUNWIND_TRACE_API("_Unwind_CallPersonality(exception_object=%p)", - (void *)exception_object); - - // Reset the selector. - __wasm_lpad_context.selector = 0; - - // Call personality function. Wasm does not have two-phase unwinding, so we - // only do the cleanup phase. - return __gxx_personality_wasm0( - 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object, - (struct _Unwind_Context *)&__wasm_lpad_context); -} - /// Called by __cxa_throw. _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *exception_object) { diff --git a/libunwind/src/config.h b/libunwind/src/config.h index f017403fa2234..fd1aba25e6822 100644 --- a/libunwind/src/config.h +++ b/libunwind/src/config.h @@ -75,7 +75,7 @@ #define _LIBUNWIND_EXPORT #define _LIBUNWIND_HIDDEN #else - #if !defined(__ELF__) && !defined(__MACH__) && !defined(_AIX) + #if !defined(__ELF__) && !defined(__MACH__) && !defined(_AIX) && !defined(__wasm__) #define _LIBUNWIND_EXPORT __declspec(dllexport) #define _LIBUNWIND_HIDDEN #else diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td index a7e45570c1b24..3745001b936f8 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.td +++ b/llvm/include/llvm/IR/RuntimeLibcalls.td @@ -1849,9 +1849,6 @@ defset list<RuntimeLibcallImpl> SjLjExceptionHandlingLibcalls = { def _Unwind_SjLj_Unregister : RuntimeLibcallImpl<UNWIND_UNREGISTER>; } -// Only used on wasm? -def _Unwind_CallPersonality : RuntimeLibcallImpl<UNWIND_CALL_PERSONALITY>; - // Used on OpenBSD def __stack_smash_handler : RuntimeLibcallImpl<STACK_SMASH_HANDLER>; @@ -3567,7 +3564,6 @@ def WasmSystemLibrary (add DefaultRuntimeLibcallImpls, Int128RTLibcalls, CompilerRTOnlyInt64Libcalls, CompilerRTOnlyInt128Libcalls, exp10f, exp10, - _Unwind_CallPersonality, emscripten_return_address, LibcallImpls<(add __small_printf, __small_sprintf, diff --git a/llvm/lib/CodeGen/WasmEHPrepare.cpp b/llvm/lib/CodeGen/WasmEHPrepare.cpp index b83bcf67716f9..363e7221f7118 100644 --- a/llvm/lib/CodeGen/WasmEHPrepare.cpp +++ b/llvm/lib/CodeGen/WasmEHPrepare.cpp @@ -28,7 +28,7 @@ // wasm.landingpad.index(index); // __wasm_lpad_context.lpad_index = index; // __wasm_lpad_context.lsda = wasm.lsda(); -// _Unwind_CallPersonality(exn); +// personality_fn(exn); // selector = __wasm_lpad_context.selector; // ... // @@ -38,18 +38,13 @@ // exception is thrown. After the stack is unwound, the control flow is // transfered to WebAssembly 'catch' instruction. // -// Unwinding the stack is not done by libunwind but the VM, so the personality -// function in libcxxabi cannot be called from libunwind during the unwinding -// process. So after a catch instruction, we insert a call to a wrapper function -// in libunwind that in turn calls the real personality function. -// // In Itanium EH, if the personality function decides there is no matching catch // clause in a call frame and no cleanup action to perform, the unwinder doesn't // stop there and continues unwinding. But in Wasm EH, the unwinder stops at // every call frame with a catch intruction, after which the personality // function is called from the compiler-generated user code here. // -// In libunwind, we have this struct that serves as a communincation channel +// In libunwind, we have this struct that serves as a communication channel // between the compiler-generated user code and the personality function in // libcxxabi. // @@ -60,20 +55,8 @@ // }; // struct _Unwind_LandingPadContext __wasm_lpad_context = ...; // -// And this wrapper in libunwind calls the personality function. -// -// _Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) { -// struct _Unwind_Exception *exception_obj = -// (struct _Unwind_Exception *)exception_ptr; -// _Unwind_Reason_Code ret = __gxx_personality_v0( -// 1, _UA_CLEANUP_PHASE, exception_obj->exception_class, exception_obj, -// (struct _Unwind_Context *)__wasm_lpad_context); -// return ret; -// } -// // We pass a landing pad index, and the address of LSDA for the current function -// to the wrapper function _Unwind_CallPersonality in libunwind, and we retrieve -// the selector after it returns. +// to the personality function, and we retrieve the selector after it returns. // //===----------------------------------------------------------------------===// @@ -111,8 +94,7 @@ class WasmEHPrepareImpl { Function *GetExnF = nullptr; // wasm.get.exception() intrinsic Function *CatchF = nullptr; // wasm.catch() intrinsic Function *GetSelectorF = nullptr; // wasm.get.ehselector() intrinsic - FunctionCallee CallPersonalityF = - nullptr; // _Unwind_CallPersonality() wrapper + FunctionCallee PersonalityF = nullptr; bool prepareThrows(Function &F); bool prepareEHPads(Function &F); @@ -235,11 +217,14 @@ bool WasmEHPrepareImpl::prepareEHPads(Function &F) { if (CatchPads.empty() && CleanupPads.empty()) return false; - if (!F.hasPersonalityFn() || - !isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) { + if (!F.hasPersonalityFn()) + return false; + + auto Personality = classifyEHPersonality(F.getPersonalityFn()); + + if (!isScopedEHPersonality(Personality)) { report_fatal_error("Function '" + F.getName() + - "' does not have a correct Wasm personality function " - "'__gxx_wasm_personality_v0'"); + "' does not have a supported Wasm personality function"); } assert(F.hasPersonalityFn() && "Personality function not found"); @@ -274,15 +259,12 @@ bool WasmEHPrepareImpl::prepareEHPads(Function &F) { // instruction selection. CatchF = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::wasm_catch); - // FIXME: Verify this is really supported for current module. - StringRef UnwindCallPersonalityName = - RTLIB::RuntimeLibcallsInfo::getLibcallImplName( - RTLIB::impl__Unwind_CallPersonality); + auto *PersPrototype = FunctionType::get( + IRB.getInt32Ty(), {IRB.getPtrTy()}, false); + PersonalityF = + M.getOrInsertFunction(getEHPersonalityName(Personality), PersPrototype); - // _Unwind_CallPersonality() wrapper function, which calls the personality - CallPersonalityF = M.getOrInsertFunction(UnwindCallPersonalityName, - IRB.getInt32Ty(), IRB.getPtrTy()); - if (Function *F = dyn_cast<Function>(CallPersonalityF.getCallee())) + if (Function *F = dyn_cast<Function>(PersonalityF.getCallee())) F->setDoesNotThrow(); unsigned Index = 0; @@ -367,9 +349,17 @@ void WasmEHPrepareImpl::prepareEHPad(BasicBlock *BB, bool NeedPersonality, // Pseudocode: __wasm_lpad_context.lsda = wasm.lsda(); IRB.CreateStore(IRB.CreateCall(LSDAF), LSDAField); - // Pseudocode: _Unwind_CallPersonality(exn); - CallInst *PersCI = IRB.CreateCall(CallPersonalityF, CatchCI, - OperandBundleDef("funclet", CPI)); + // Pseudocode: personality_fn(exn); + CallInst *PersCI; + + // Grab direct function when possible to use `call` instead of `call_indirect` + if (Function *F = dyn_cast<Function>(PersonalityF.getCallee())) + PersCI = IRB.CreateCall(F, CatchCI, + OperandBundleDef("funclet", CPI)); + else + PersCI = IRB.CreateCall(PersonalityF, CatchCI, + OperandBundleDef("funclet", CPI)); + PersCI->setDoesNotThrow(); // Pseudocode: int selector = __wasm_lpad_context.selector; diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.ll index a35129effcdee..301f7d81a4274 100644 --- a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.ll +++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.ll @@ -1911,7 +1911,7 @@ declare ptr @_ZN7MyClassD2Ev(ptr returned) #0 ; Function Attrs: nounwind declare ptr @_ZN7MyClassC2ERKS_(ptr returned, ptr dereferenceable(4)) #0 -declare i32 @__gxx_wasm_personality_v0(...) +declare void @__gxx_wasm_personality_v0(ptr) ; Function Attrs: nounwind declare ptr @llvm.wasm.get.exception(token) #0 ; Function Attrs: nounwind diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.mir b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.mir index 324dd29f2295e..f0341ed420241 100644 --- a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.mir +++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.mir @@ -3,7 +3,7 @@ --- | target triple = "wasm32-unknown-unknown" - declare i32 @__gxx_wasm_personality_v0(...) + declare void @__gxx_wasm_personality_v0(ptr) declare void @foo() define void @rethrow_arg_test() personality ptr @__gxx_wasm_personality_v0 { ret void diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll index a1e7616711ab9..a6611899806ea 100644 --- a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll +++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll @@ -35,7 +35,7 @@ target triple = "wasm32-unknown-unknown" ; CHECK: local.set 2 ; CHECK: local.set 1 ; CHECK: local.get 0 -; CHECK: call _Unwind_CallPersonality +; CHECK: call __gxx_wasm_personality_v0 ; CHECK: block ; CHECK: br_if 0 # 0: down to label[[L2:[0-9]+]] ; CHECK: call __cxa_begin_catch @@ -111,7 +111,7 @@ try.cont: ; preds = %catch, %catch2, %en ; CHECK: br 2 # 2: down to label[[L1:[0-9]+]] ; CHECK: end_try_table ; CHECK: end_block # label[[L0]]: -; CHECK: call _Unwind_CallPersonality +; CHECK: call __gxx_wasm_personality_v0 ; CHECK: block ; CHECK: block ; CHECK: br_if 0 # 0: down to label[[L2:[0-9]+]] @@ -124,7 +124,7 @@ try.cont: ; preds = %catch, %catch2, %en ; CHECK: br 5 # 5: down to label[[L5:[0-9]+]] ; CHECK: end_try_table ; CHECK: end_block # label[[L4]]: -; CHECK: call _Unwind_CallPersonality +; CHECK: call __gxx_wasm_personality_v0 ; CHECK: block ; CHECK: block ; CHECK: br_if 0 # 0: down to label[[L6:[0-9]+]] @@ -1644,7 +1644,7 @@ declare ptr @_ZN7MyClassD2Ev(ptr returned) #0 ; Function Attrs: nounwind declare ptr @_ZN7MyClassC2ERKS_(ptr returned, ptr dereferenceable(4)) #0 -declare i32 @__gxx_wasm_personality_v0(...) +declare void @__gxx_wasm_personality_v0(ptr) ; Function Attrs: nounwind declare ptr @llvm.wasm.get.exception(token) #0 ; Function Attrs: nounwind diff --git a/llvm/test/CodeGen/WebAssembly/eh-lsda.ll b/llvm/test/CodeGen/WebAssembly/eh-lsda.ll index d5b28b279d419..0c0fa9f840601 100644 --- a/llvm/test/CodeGen/WebAssembly/eh-lsda.ll +++ b/llvm/test/CodeGen/WebAssembly/eh-lsda.ll @@ -251,6 +251,6 @@ declare i32 @llvm.wasm.get.ehselector(token) #0 declare void @__cxa_rethrow() declare ptr @__cxa_begin_catch(ptr) declare void @__cxa_end_catch() -declare i32 @__gxx_wasm_personality_v0(...) +declare void @__gxx_wasm_personality_v0(ptr) attributes #0 = { nounwind } diff --git a/llvm/test/CodeGen/WebAssembly/exception-legacy.ll b/llvm/test/CodeGen/WebAssembly/exception-legacy.ll index 573f69df8b859..217da5c39e27f 100644 --- a/llvm/test/CodeGen/WebAssembly/exception-legacy.ll +++ b/llvm/test/CodeGen/WebAssembly/exception-legacy.ll @@ -35,7 +35,7 @@ define void @throw(ptr %p) { ; CHECK: catch $[[EXN:[0-9]+]]=, __cpp_exception ; CHECK: global.set __stack_pointer ; CHECK: i32.store __wasm_lpad_context -; CHECK: call $drop=, _Unwind_CallPersonality, $[[EXN]] +; CHECK: call __gxx_wasm_personality_v0, $[[EXN]] ; CHECK: block ; CHECK: br_if 0 ; CHECK: call $drop=, __cxa_begin_catch @@ -547,7 +547,7 @@ try.cont: ; preds = %entry declare void @foo() declare void @bar(ptr) declare void @take_i32(i32) -declare i32 @__gxx_wasm_personality_v0(...) +declare void @__gxx_wasm_personality_v0(ptr) ; Function Attrs: noreturn declare void @llvm.wasm.throw(i32, ptr) #1 ; Function Attrs: nounwind diff --git a/llvm/test/CodeGen/WebAssembly/exception-legacy.mir b/llvm/test/CodeGen/WebAssembly/exception-legacy.mir index 95929af4f4cea..7b8ba72ddfad9 100644 --- a/llvm/test/CodeGen/WebAssembly/exception-legacy.mir +++ b/llvm/test/CodeGen/WebAssembly/exception-legacy.mir @@ -3,7 +3,7 @@ --- | target triple = "wasm32-unknown-unknown" - declare i32 @__gxx_wasm_personality_v0(...) + declare void @__gxx_wasm_personality_v0(ptr) declare void @foo() define void @eh_label_test() personality ptr @__gxx_wasm_personality_v0 { ret void diff --git a/llvm/test/CodeGen/WebAssembly/exception.ll b/llvm/test/CodeGen/WebAssembly/exception.ll index f738216d087ec..a972fceba4715 100644 --- a/llvm/test/CodeGen/WebAssembly/exception.ll +++ b/llvm/test/CodeGen/WebAssembly/exception.ll @@ -47,7 +47,7 @@ define void @throw(ptr %p) { ; CHECK: local.get 0 ; CHECK: global.set __stack_pointer ; CHECK: i32.store __wasm_lpad_context -; CHECK: call _Unwind_CallPersonality +; CHECK: call __gxx_wasm_personality_v0 ; CHECK: block ; CHECK: br_if 0 ; CHECK: call __cxa_begin_catch @@ -648,7 +648,7 @@ try.cont: ; preds = %entry declare void @foo() declare void @bar(ptr) declare void @take_i32(i32) -declare i32 @__gxx_wasm_personality_v0(...) +declare void @__gxx_wasm_personality_v0(ptr) ; Function Attrs: noreturn declare void @llvm.wasm.throw(i32, ptr) #1 ; Function Attrs: nounwind diff --git a/llvm/test/CodeGen/WebAssembly/function-info.mir b/llvm/test/CodeGen/WebAssembly/function-info.mir index b81cdffde819f..be87bad9ec72c 100644 --- a/llvm/test/CodeGen/WebAssembly/function-info.mir +++ b/llvm/test/CodeGen/WebAssembly/function-info.mir @@ -3,7 +3,7 @@ --- | target triple = "wasm32-unknown-unknown" - declare i32 @__gxx_wasm_personality_v0(...) + declare void @__gxx_wasm_personality_v0(ptr) declare void @foo() define void @function_property_test() { ret void diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj-phi.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj-phi.ll index 5e8ebcf247000..b4ecb2911c89b 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj-phi.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj-phi.ll @@ -110,7 +110,7 @@ ehcleanup: ; preds = %bb3, %catch.start, } declare i32 @setjmp(ptr) -declare i32 @__gxx_wasm_personality_v0(...) +declare void @__gxx_wasm_personality_v0(ptr) declare void @foo() declare void @longjmpable() declare void @use_i32(i32) diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll index d5ae37d7e98bc..37e98c6a302d1 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll @@ -299,7 +299,7 @@ declare ptr @_ZN4TempD2Ev(ptr %this) #2 declare i32 @setjmp(ptr) #0 ; Function Attrs: noreturn declare void @longjmp(ptr, i32) #1 -declare i32 @__gxx_wasm_personality_v0(...) +declare void @__gxx_wasm_personality_v0(ptr) ; Function Attrs: nounwind declare ptr @llvm.wasm.get.exception(token) #2 ; Function Attrs: nounwind diff --git a/llvm/test/CodeGen/WebAssembly/wasm-eh-em-sjlj-error.ll b/llvm/test/CodeGen/WebAssembly/wasm-eh-em-sjlj-error.ll index 35637a996e3ab..8547b68824ee6 100644 --- a/llvm/test/CodeGen/WebAssembly/wasm-eh-em-sjlj-error.ll +++ b/llvm/test/CodeGen/WebAssembly/wasm-eh-em-sjlj-error.ll @@ -30,7 +30,7 @@ try.cont: ; preds = %entry, %catch.start } declare void @foo() -declare i32 @__gxx_wasm_personality_v0(...) +declare void @__gxx_wasm_personality_v0(ptr) ; Function Attrs: nounwind declare ptr @llvm.wasm.get.exception(token) #0 ; Function Attrs: nounwind diff --git a/llvm/test/CodeGen/WebAssembly/wasm-eh-invalid-personality.ll b/llvm/test/CodeGen/WebAssembly/wasm-eh-invalid-personality.ll index 1a4e888a26ef5..36340c1444525 100644 --- a/llvm/test/CodeGen/WebAssembly/wasm-eh-invalid-personality.ll +++ b/llvm/test/CodeGen/WebAssembly/wasm-eh-invalid-personality.ll @@ -6,7 +6,7 @@ target triple = "wasm32-unknown-unknown" ; not have a correct Wasm personality function. define void @test() personality ptr @invalid_personality { -; CHECK: LLVM ERROR: Function 'test' does not have a correct Wasm personality function '__gxx_wasm_personality_v0' +; CHECK: LLVM ERROR: Function 'test' does not have a supported Wasm personality function entry: invoke void @foo() to label %try.cont unwind label %catch.dispatch diff --git a/llvm/test/CodeGen/WebAssembly/wasm-eh-prepare.ll b/llvm/test/CodeGen/WebAssembly/wasm-eh-prepare.ll index 164c138cb7578..daa3bb0207b55 100644 --- a/llvm/test/CodeGen/WebAssembly/wasm-eh-prepare.ll +++ b/llvm/test/CodeGen/WebAssembly/wasm-eh-prepare.ll @@ -46,7 +46,7 @@ catch.start: ; preds = %catch.dispatch ; CHECK-NEXT: store i32 0, ptr @__wasm_lpad_context ; CHECK-NEXT: %[[LSDA:.*]] = call ptr @llvm.wasm.lsda() ; CHECK-NEXT: store ptr %[[LSDA]], ptr getelementptr inbounds ({ i32, ptr, i32 }, ptr @__wasm_lpad_context, i32 0, i32 1) -; CHECK-NEXT: call i32 @_Unwind_CallPersonality(ptr %[[EXN]]) {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] +; CHECK-NEXT: call void @__gxx_wasm_personality_v0(ptr %[[EXN]]) {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] ; CHECK-NEXT: %[[SELECTOR:.*]] = load i32, ptr getelementptr inbounds ({ i32, ptr, i32 }, ptr @__wasm_lpad_context, i32 0, i32 2) ; CHECK: icmp eq i32 %[[SELECTOR]] @@ -103,7 +103,7 @@ catch.start: ; preds = %catch.dispatch ; CHECK-NOT: call void @llvm.wasm.landingpad.index ; CHECK-NOT: store {{.*}} @__wasm_lpad_context ; CHECK-NOT: call ptr @llvm.wasm.lsda() -; CHECK-NOT: call i32 @_Unwind_CallPersonality +; CHECK-NOT: call void @__gxx_wasm_personality_v0 ; CHECK-NOT: load {{.*}} @__wasm_lpad_context try.cont: ; preds = %entry, %catch.start @@ -257,7 +257,7 @@ merge: ; preds = %bb.true.0, %bb.fals declare void @foo() declare void @bar(i32) declare ptr @_ZN4TempD2Ev(ptr returned) -declare i32 @__gxx_wasm_personality_v0(...) +declare void @__gxx_wasm_personality_v0(ptr) ; Function Attrs: nounwind declare ptr @llvm.wasm.get.exception(token) #0 ; Function Attrs: nounwind @@ -277,4 +277,4 @@ attributes #1 = { noreturn } ; CHECK-DAG: declare void @llvm.wasm.landingpad.index(token, i32 immarg) ; CHECK-DAG: declare ptr @llvm.wasm.lsda() -; CHECK-DAG: declare i32 @_Unwind_CallPersonality(ptr) +; CHECK-DAG: declare void @__gxx_wasm_personality_v0(ptr) diff --git a/llvm/test/CodeGen/WebAssembly/wasm-eh-sjlj-setjmp-within-catch.ll b/llvm/test/CodeGen/WebAssembly/wasm-eh-sjlj-setjmp-within-catch.ll index ed9b62941a9c7..6cca5af633751 100644 --- a/llvm/test/CodeGen/WebAssembly/wasm-eh-sjlj-setjmp-within-catch.ll +++ b/llvm/test/CodeGen/WebAssembly/wasm-eh-sjlj-setjmp-within-catch.ll @@ -49,7 +49,7 @@ ehcleanup: ; preds = %catch } declare void @foo() -declare i32 @__gxx_wasm_personality_v0(...) +declare void @__gxx_wasm_personality_v0(ptr) ; Function Attrs: nounwind declare ptr @llvm.wasm.get.exception(token) #0 ; Function Attrs: nounwind >From f6d21590fc0d7ec1fe07daf8b24096d58bf60f3c Mon Sep 17 00:00:00 2001 From: Demetrius Kanios <[email protected]> Date: Mon, 13 Jul 2026 12:45:05 -0700 Subject: [PATCH 2/2] Update comment per #206660 --- libcxxabi/src/cxa_personality.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp index 970cd0355ddf4..e697950840e99 100644 --- a/libcxxabi/src/cxa_personality.cpp +++ b/libcxxabi/src/cxa_personality.cpp @@ -1123,7 +1123,7 @@ void __gxx_wasm_personality_v0(void* exception_ptr) { __wasm_lpad_context.selector = 0; // Call personality function. Wasm does not have two-phase unwinding, so we - // only do the cleanup phase. + // only do the search phase. __gxx_personality_imp( 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object, (struct _Unwind_Context *)&__wasm_lpad_context); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
