Skip to content

Commit 539b2e0

Browse files
authored
[WebAssembly] Fix catch block type in wasm64 (#124381)
`try_table`'s `catch` or `catch_ref`'s target block's return type should be `i64` and `(i64, exnref)` in case of wasm64.
1 parent 1bcf44b commit 539b2e0

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -852,12 +852,19 @@ void WebAssemblyCFGStackify::placeTryTableMarker(MachineBasicBlock &MBB) {
852852
// Add a CATCH_*** clause to the TRY_TABLE. These are pseudo instructions
853853
// following the destination END_BLOCK to simulate block return values,
854854
// because we currently don't support them.
855+
const auto &TLI =
856+
*MF.getSubtarget<WebAssemblySubtarget>().getTargetLowering();
857+
WebAssembly::BlockType PtrTy =
858+
TLI.getPointerTy(MF.getDataLayout()) == MVT::i32
859+
? WebAssembly::BlockType::I32
860+
: WebAssembly::BlockType::I64;
855861
auto *Catch = WebAssembly::findCatch(&MBB);
856862
switch (Catch->getOpcode()) {
857863
case WebAssembly::CATCH:
858864
// CATCH's destination block's return type is the extracted value type,
859-
// which is currently i32 for all supported tags.
860-
BlockMIB.addImm(int64_t(WebAssembly::BlockType::I32));
865+
// which is currently the thrown value's pointer type for all supported
866+
// tags.
867+
BlockMIB.addImm(int64_t(PtrTy));
861868
TryTableMIB.addImm(wasm::WASM_OPCODE_CATCH);
862869
for (const auto &Use : Catch->uses()) {
863870
// The only use operand a CATCH can have is the tag symbol.

llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,13 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
169169

170170
const MCInstrDesc &Desc = MI->getDesc();
171171
unsigned NumVariadicDefs = MI->getNumExplicitDefs() - Desc.getNumDefs();
172+
const MachineFunction *MF = MI->getMF();
173+
const auto &TLI =
174+
*MF->getSubtarget<WebAssemblySubtarget>().getTargetLowering();
175+
wasm::ValType PtrTy = TLI.getPointerTy(MF->getDataLayout()) == MVT::i32
176+
? wasm::ValType::I32
177+
: wasm::ValType::I64;
178+
172179
for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
173180
const MachineOperand &MO = MI->getOperand(I);
174181

@@ -234,12 +241,12 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
234241
// return type of the parent function.
235242
// 2. (catch_ref ...) clause in try_table instruction. Currently all
236243
// tags we support (cpp_exception and c_longjmp) throws a single
237-
// i32, so the multivalue signature for this case will be (i32,
238-
// exnref). Having MO_CATCH_BLOCK_SIG target flags means this is
239-
// a destination of a catch_ref.
240-
if (MO.getTargetFlags() == WebAssemblyII::MO_CATCH_BLOCK_SIG)
241-
Returns = {wasm::ValType::I32, wasm::ValType::EXNREF};
242-
else
244+
// pointer, so the multivalue signature for this case will be
245+
// (ptr, exnref). Having MO_CATCH_BLOCK_SIG target flags means
246+
// this is a destination of a catch_ref.
247+
if (MO.getTargetFlags() == WebAssemblyII::MO_CATCH_BLOCK_SIG) {
248+
Returns = {PtrTy, wasm::ValType::EXNREF};
249+
} else
243250
getFunctionReturns(MI, Returns);
244251
MCOp = lowerTypeIndexOperand(std::move(Returns),
245252
SmallVector<wasm::ValType, 4>());

llvm/test/CodeGen/WebAssembly/exception.ll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
; RUN: llc < %s -asm-verbose=false -wasm-enable-eh -wasm-use-legacy-eh=false -exception-model=wasm -mattr=+exception-handling -verify-machineinstrs -O0
33
; RUN: llc < %s -wasm-enable-eh -wasm-use-legacy-eh=false -exception-model=wasm -mattr=+exception-handling
44
; RUN: llc < %s -wasm-enable-eh -wasm-use-legacy-eh=false -exception-model=wasm -mattr=+exception-handling -filetype=obj
5+
; 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
56

67
target triple = "wasm32-unknown-unknown"
78

@@ -30,11 +31,13 @@ define void @throw(ptr %p) {
3031
; }
3132

3233
; CHECK-LABEL: catch:
34+
; WASM64-LABEL: catch:
3335
; CHECK: global.get __stack_pointer
3436
; CHECK: local.set 0
3537
; CHECK: block
3638
; CHECK: block () -> (i32, exnref)
3739
; CHECK: try_table (catch_ref __cpp_exception 0)
40+
; WASM64: block () -> (i64, exnref)
3841
; CHECK: call foo
3942
; CHECK: br 2
4043
; CHECK: end_try_table
@@ -138,8 +141,10 @@ ehcleanup: ; preds = %entry
138141
; }
139142

140143
; CHECK-LABEL: terminatepad
144+
; WASM64-LABEL: terminatepad
141145
; CHECK: block
142146
; CHECK: block i32
147+
; WASM64: block i64
143148
; CHECK: try_table (catch __cpp_exception 0)
144149
; CHECK: call foo
145150
; CHECK: br 2

0 commit comments

Comments
 (0)