Skip to content

[WebAssembly] Fix catch block type in wasm64 #124381

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -852,12 +852,19 @@ void WebAssemblyCFGStackify::placeTryTableMarker(MachineBasicBlock &MBB) {
// Add a CATCH_*** clause to the TRY_TABLE. These are pseudo instructions
// following the destination END_BLOCK to simulate block return values,
// because we currently don't support them.
const auto &TLI =
*MF.getSubtarget<WebAssemblySubtarget>().getTargetLowering();
WebAssembly::BlockType PtrTy =
TLI.getPointerTy(MF.getDataLayout()) == MVT::i32
? WebAssembly::BlockType::I32
: WebAssembly::BlockType::I64;
auto *Catch = WebAssembly::findCatch(&MBB);
switch (Catch->getOpcode()) {
case WebAssembly::CATCH:
// CATCH's destination block's return type is the extracted value type,
// which is currently i32 for all supported tags.
BlockMIB.addImm(int64_t(WebAssembly::BlockType::I32));
// which is currently the thrown value's pointer type for all supported
// tags.
BlockMIB.addImm(int64_t(PtrTy));
TryTableMIB.addImm(wasm::WASM_OPCODE_CATCH);
for (const auto &Use : Catch->uses()) {
// The only use operand a CATCH can have is the tag symbol.
Expand Down
19 changes: 13 additions & 6 deletions llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,

const MCInstrDesc &Desc = MI->getDesc();
unsigned NumVariadicDefs = MI->getNumExplicitDefs() - Desc.getNumDefs();
const MachineFunction *MF = MI->getMF();
const auto &TLI =
*MF->getSubtarget<WebAssemblySubtarget>().getTargetLowering();
wasm::ValType PtrTy = TLI.getPointerTy(MF->getDataLayout()) == MVT::i32
? wasm::ValType::I32
: wasm::ValType::I64;

for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
const MachineOperand &MO = MI->getOperand(I);

Expand Down Expand Up @@ -234,12 +241,12 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
// return type of the parent function.
// 2. (catch_ref ...) clause in try_table instruction. Currently all
// tags we support (cpp_exception and c_longjmp) throws a single
// i32, so the multivalue signature for this case will be (i32,
// exnref). Having MO_CATCH_BLOCK_SIG target flags means this is
// a destination of a catch_ref.
if (MO.getTargetFlags() == WebAssemblyII::MO_CATCH_BLOCK_SIG)
Returns = {wasm::ValType::I32, wasm::ValType::EXNREF};
else
// pointer, so the multivalue signature for this case will be
// (ptr, exnref). Having MO_CATCH_BLOCK_SIG target flags means
// this is a destination of a catch_ref.
if (MO.getTargetFlags() == WebAssemblyII::MO_CATCH_BLOCK_SIG) {
Returns = {PtrTy, wasm::ValType::EXNREF};
} else
getFunctionReturns(MI, Returns);
MCOp = lowerTypeIndexOperand(std::move(Returns),
SmallVector<wasm::ValType, 4>());
Expand Down
5 changes: 5 additions & 0 deletions llvm/test/CodeGen/WebAssembly/exception.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
; RUN: llc < %s -asm-verbose=false -wasm-enable-eh -wasm-use-legacy-eh=false -exception-model=wasm -mattr=+exception-handling -verify-machineinstrs -O0
; RUN: llc < %s -wasm-enable-eh -wasm-use-legacy-eh=false -exception-model=wasm -mattr=+exception-handling
; RUN: llc < %s -wasm-enable-eh -wasm-use-legacy-eh=false -exception-model=wasm -mattr=+exception-handling -filetype=obj
; RUN: llc < %s -mtriple=wasm64-unknown-unknown -wasm-enable-eh -wasm-use-legacy-eh=false -exception-model=wasm -mattr=+exception-handling -verify-machineinstrs | FileCheck --implicit-check-not=ehgcr -allow-deprecated-dag-overlap %s --check-prefix=WASM64

target triple = "wasm32-unknown-unknown"

Expand Down Expand Up @@ -30,11 +31,13 @@ define void @throw(ptr %p) {
; }

; CHECK-LABEL: catch:
; WASM64-LABEL: catch:
; CHECK: global.get __stack_pointer
; CHECK: local.set 0
; CHECK: block
; CHECK: block () -> (i32, exnref)
; CHECK: try_table (catch_ref __cpp_exception 0)
; WASM64: block () -> (i64, exnref)
; CHECK: call foo
; CHECK: br 2
; CHECK: end_try_table
Expand Down Expand Up @@ -138,8 +141,10 @@ ehcleanup: ; preds = %entry
; }

; CHECK-LABEL: terminatepad
; WASM64-LABEL: terminatepad
; CHECK: block
; CHECK: block i32
; WASM64: block i64
; CHECK: try_table (catch __cpp_exception 0)
; CHECK: call foo
; CHECK: br 2
Expand Down
Loading