[llvm] [WebAssembly] Fix catch block type in wasm64 (PR #124381)
Heejin Ahn via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 24 18:22:26 PST 2025
https://github.com/aheejin updated https://github.com/llvm/llvm-project/pull/124381
>From b8d02f72c07e8d7d017a00398b89e801ea607527 Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Sat, 25 Jan 2025 02:17:44 +0000
Subject: [PATCH 1/2] [WebAssembly] Fix catch block type in wasm64
`try_table`'s `catch` or `catch_ref`'s target block's return type should
be `i64` and `(i64, exnref)` in case of wasm64.
---
.../WebAssembly/WebAssemblyCFGStackify.cpp | 11 +++++++++--
.../WebAssembly/WebAssemblyMCInstLower.cpp | 18 +++++++++++++-----
llvm/test/CodeGen/WebAssembly/exception.ll | 5 +++++
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
index bdc1cc6d652ac6..277d353d1db100 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
@@ -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.
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
index f09b29472cb6b2..c633a8b437ee93 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -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);
@@ -234,11 +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};
+ // 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),
diff --git a/llvm/test/CodeGen/WebAssembly/exception.ll b/llvm/test/CodeGen/WebAssembly/exception.ll
index 304664b622e800..febab822a6a9e3 100644
--- a/llvm/test/CodeGen/WebAssembly/exception.ll
+++ b/llvm/test/CodeGen/WebAssembly/exception.ll
@@ -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"
@@ -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
@@ -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
>From 4cb862b544ed541d40d07f2b6f699000cb90f148 Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Sat, 25 Jan 2025 02:21:58 +0000
Subject: [PATCH 2/2] clang-format
---
llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
index c633a8b437ee93..eed0b42863ee62 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -246,8 +246,7 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
// this is a destination of a catch_ref.
if (MO.getTargetFlags() == WebAssemblyII::MO_CATCH_BLOCK_SIG) {
Returns = {PtrTy, wasm::ValType::EXNREF};
- }
- else
+ } else
getFunctionReturns(MI, Returns);
MCOp = lowerTypeIndexOperand(std::move(Returns),
SmallVector<wasm::ValType, 4>());
More information about the llvm-commits
mailing list