mirror-llvm-project/llvm/test/CodeGen/WebAssembly/function-info.mir
Demetrius Kanios 1d4e04f7a7
[WebAssembly] Call EH personality function instead of Unwind_CallPersonality (#209282)
On Wasm, it's not currently possibly to change which `personality` is
attached to a given IR function. This is primarily because no matter
what `personality` is attached, codegen creates a call to a
`Unwind_CallPersonality` wrapper hard-coded to call c++abi's
personality.

In order to allow alternative personalities without introducing bloat at
each personality call site, this PR adjusts the ABI of the personality
on Wasm. `Unwind_CallPersonality` is moved to `libcxxabi` under the name
`__gxx_wasm_personality_v0`, with the "real" personality code renamed
`__gxx_personality_imp` and called by `__gxx_wasm_personality_v0` (after
resetting the landing pad context).

The signature of EH personalities on Wasm is now `int personality(void*
exception_object)` (where the int return is `_Unwind_Reason_Code` and
the `void*` is `_Unwind_Exception*`), and personalities are expected to
`__wasm_lpad_context.selector = 0;`.

Based on #175202
2026-07-28 20:05:45 -07:00

102 lines
2.6 KiB
YAML

# RUN: llc -mtriple=wasm32-unknown-unknown -exception-model=wasm -wasm-enable-sjlj -mattr=+exception-handling,+multivalue,+simd128 -run-pass wasm-cfg-sort -run-pass wasm-cfg-stackify %s -o - | FileCheck %s
--- |
target triple = "wasm32-unknown-unknown"
declare i32 @__gxx_wasm_personality_v0(ptr)
declare void @foo()
define void @function_property_test() {
ret void
}
;; Param / results tests
define i32 @i32__i64(i64) {
ret i32 0
}
define void @void__i32_i64_f32_f64() {
ret void
}
define void @void__v16i8_v8i16_v4i32_v2i64(<16 x i8>, <8 x i16>, <4 x i32>, <2 x i64>) {
ret void
}
%pair = type { i32, i64 }
define %pair @i32_i64__i32_i64(%pair %p) {
ret %pair %p
}
...
# CHECK-LABEL: name: function_property_test
# CHECK: machineFunctionInfo:
# CHECK: isCFGStackified: true
name: function_property_test
liveins:
- { reg: '$arguments' }
body: |
bb.0:
RETURN implicit-def dead $arguments
...
# Param / results tests
---
# CHECK-LABEL: name: i32__i64
# CHECK: machineFunctionInfo:
# CHECK: params: [ i64 ]
# CHECK-NEXT: results: [ i32 ]
name: i32__i64
liveins:
- { reg: '$arguments' }
machineFunctionInfo:
params: [ i64 ]
results: [ i32 ]
body: |
bb.0:
%0:i32 = CONST_I32 3, implicit-def dead $arguments
RETURN %0:i32, implicit-def dead $arguments
...
---
# CHECK-LABEL: name: void__i32_i64_f32_f64
# CHECK: machineFunctionInfo:
# CHECK: params: [ i32, i64, f32, f64 ]
# CHECK-NEXT: results: [ ]
name: void__i32_i64_f32_f64
liveins:
- { reg: '$arguments' }
machineFunctionInfo:
params: [ i32, i64, f32, f64 ]
results: [ ]
body: |
bb.0:
RETURN implicit-def dead $arguments
...
---
# CHECK-LABEL: name: void__v16i8_v8i16_v4i32_v2i64
# CHECK: machineFunctionInfo:
# CHECK: params: [ v16i8, v8i16, v4i32, v2i64 ]
# CHECK-NEXT: results: [ ]
name: void__v16i8_v8i16_v4i32_v2i64
liveins:
- { reg: '$arguments' }
machineFunctionInfo:
params: [ v16i8, v8i16, v4i32, v2i64 ]
results: [ ]
body: |
bb.0:
RETURN implicit-def dead $arguments
...
---
# CHECK-LABEL: name: i32_i64__i32_i64
# CHECK: machineFunctionInfo:
# CHECK: params: [ i32, i64 ]
# CHECK-NEXT: results: [ i32, i64 ]
name: i32_i64__i32_i64
liveins:
- { reg: '$arguments' }
machineFunctionInfo:
params: [ i32, i64 ]
results: [ i32, i64 ]
body: |
bb.0:
%0:i32 = ARGUMENT_i32 0, implicit $arguments
%1:i64 = ARGUMENT_i64 1, implicit $arguments
RETURN %0, %1, implicit-def dead $arguments
...