[lld] [llvm] [WebAssembly] Add exnref type (PR #93586)
via llvm-commits
llvm-commits at lists.llvm.org
Tue May 28 10:31:49 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-binary-utilities
@llvm/pr-subscribers-mc
@llvm/pr-subscribers-objectyaml
Author: Heejin Ahn (aheejin)
<details>
<summary>Changes</summary>
This adds (back) the exnref type restored in the new EH proposal adopted in Oct 2023 CG meeting:
https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md:x
---
Patch is 32.31 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/93586.diff
28 Files Affected:
- (modified) lld/wasm/WriterUtils.cpp (+2)
- (modified) llvm/include/llvm/BinaryFormat/Wasm.h (+6-3)
- (modified) llvm/include/llvm/CodeGen/ValueTypes.td (+5-4)
- (modified) llvm/include/llvm/IR/Intrinsics.td (+2)
- (modified) llvm/include/llvm/IR/IntrinsicsWebAssembly.td (+18)
- (modified) llvm/lib/CodeGen/ValueTypes.cpp (+1)
- (modified) llvm/lib/Object/WasmObjectFile.cpp (+4)
- (modified) llvm/lib/ObjectYAML/WasmYAML.cpp (+2)
- (modified) llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h (+12)
- (modified) llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTypeUtilities.cpp (+6)
- (modified) llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTypeUtilities.h (+3-1)
- (modified) llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp (+3)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (+2)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp (+10)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp (+16)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (+3)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td (+3)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td (+5-3)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td (+2)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp (+2)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td (+2)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp (+2)
- (modified) llvm/test/CodeGen/WebAssembly/reg-argument.mir (+11)
- (modified) llvm/test/CodeGen/WebAssembly/reg-copy.mir (+11)
- (modified) llvm/test/MC/WebAssembly/basic-assembly.s (+13-8)
- (modified) llvm/test/MC/WebAssembly/reference-types.s (+24-2)
- (modified) llvm/test/MC/WebAssembly/type-checker-errors.s (+16)
- (modified) llvm/utils/TableGen/Common/CodeGenTarget.cpp (+1)
``````````diff
diff --git a/lld/wasm/WriterUtils.cpp b/lld/wasm/WriterUtils.cpp
index cdd2c42f939ef..c6a1592012e64 100644
--- a/lld/wasm/WriterUtils.cpp
+++ b/lld/wasm/WriterUtils.cpp
@@ -35,6 +35,8 @@ std::string toString(ValType type) {
return "funcref";
case ValType::EXTERNREF:
return "externref";
+ case ValType::EXNREF:
+ return "exnref";
case ValType::OTHERREF:
return "otherref";
}
diff --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h
index 38ef8e37df91d..d8aa899080097 100644
--- a/llvm/include/llvm/BinaryFormat/Wasm.h
+++ b/llvm/include/llvm/BinaryFormat/Wasm.h
@@ -58,15 +58,16 @@ enum : unsigned {
WASM_TYPE_V128 = 0x7B,
WASM_TYPE_NULLFUNCREF = 0x73,
WASM_TYPE_NULLEXTERNREF = 0x72,
+ WASM_TYPE_NULLEXNREF= 0x74,
WASM_TYPE_NULLREF = 0x71,
WASM_TYPE_FUNCREF = 0x70,
WASM_TYPE_EXTERNREF = 0x6F,
+ WASM_TYPE_EXNREF = 0x69,
WASM_TYPE_ANYREF = 0x6E,
WASM_TYPE_EQREF = 0x6D,
WASM_TYPE_I31REF = 0x6C,
WASM_TYPE_STRUCTREF = 0x6B,
WASM_TYPE_ARRAYREF = 0x6A,
- WASM_TYPE_EXNREF = 0x69,
WASM_TYPE_NONNULLABLE = 0x64,
WASM_TYPE_NULLABLE = 0x63,
WASM_TYPE_FUNC = 0x60,
@@ -261,8 +262,9 @@ enum class ValType {
V128 = WASM_TYPE_V128,
FUNCREF = WASM_TYPE_FUNCREF,
EXTERNREF = WASM_TYPE_EXTERNREF,
+ EXNREF = WASM_TYPE_EXNREF,
// Unmodeled value types include ref types with heap types other than
- // func or extern, and type-specialized funcrefs
+ // func, extern or exn, and type-specialized funcrefs
OTHERREF = 0xff,
};
@@ -410,7 +412,8 @@ struct WasmDataSegment {
// 1) Does not model passive or declarative segments (Segment will end up with
// an Offset field of i32.const 0)
// 2) Does not model init exprs (Segment will get an empty Functions list)
-// 2) Does not model types other than basic funcref/externref (see ValType)
+// 3) Does not model types other than basic funcref/externref/exnref (see
+// ValType)
struct WasmElemSegment {
uint32_t Flags;
uint32_t TableNumber;
diff --git a/llvm/include/llvm/CodeGen/ValueTypes.td b/llvm/include/llvm/CodeGen/ValueTypes.td
index 900b30d9b0249..6ae283b9c5a85 100644
--- a/llvm/include/llvm/CodeGen/ValueTypes.td
+++ b/llvm/include/llvm/CodeGen/ValueTypes.td
@@ -280,11 +280,12 @@ def untyped : ValueType<8, 193> { // Produces an untyped value
}
def funcref : ValueType<0, 194>; // WebAssembly's funcref type
def externref : ValueType<0, 195>; // WebAssembly's externref type
-def x86amx : ValueType<8192, 196>; // X86 AMX value
-def i64x8 : ValueType<512, 197>; // 8 Consecutive GPRs (AArch64)
+def exnref : ValueType<0, 196>; // WebAssembly's exnref type
+def x86amx : ValueType<8192, 197>; // X86 AMX value
+def i64x8 : ValueType<512, 198>; // 8 Consecutive GPRs (AArch64)
def aarch64svcount
- : ValueType<16, 198>; // AArch64 predicate-as-counter
-def spirvbuiltin : ValueType<0, 199>; // SPIR-V's builtin type
+ : ValueType<16, 199>; // AArch64 predicate-as-counter
+def spirvbuiltin : ValueType<0, 200>; // SPIR-V's builtin type
def token : ValueType<0, 248>; // TokenTy
def MetadataVT : ValueType<0, 249> { // Metadata
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 3019f68083d42..c3ac53837444e 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -316,6 +316,7 @@ def IIT_PPCF128 : IIT_VT<ppcf128, 52>;
def IIT_V3 : IIT_Vec<3, 53>;
def IIT_EXTERNREF : IIT_VT<externref, 54>;
def IIT_FUNCREF : IIT_VT<funcref, 55>;
+def IIT_EXNREF: IIT_VT<exnref, 56>;
def IIT_I2 : IIT_Int<2, 57>;
def IIT_I4 : IIT_Int<4, 58>;
def IIT_AARCH64_SVCOUNT : IIT_VT<aarch64svcount, 59>;
@@ -581,6 +582,7 @@ def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
def llvm_externref_ty : LLVMType<externref>;
def llvm_funcref_ty : LLVMType<funcref>;
+def llvm_exnref_ty : LLVMType<exnref>;
//===----------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
index 572d334ac9552..373a816f476a3 100644
--- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -31,12 +31,17 @@ def int_wasm_ref_null_extern :
DefaultAttrsIntrinsic<[llvm_externref_ty], [], [IntrNoMem]>;
def int_wasm_ref_null_func :
DefaultAttrsIntrinsic<[llvm_funcref_ty], [], [IntrNoMem]>;
+def int_wasm_ref_null_exn:
+ DefaultAttrsIntrinsic<[llvm_exnref_ty], [], [IntrNoMem]>;
def int_wasm_ref_is_null_extern :
DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_externref_ty], [IntrNoMem],
"llvm.wasm.ref.is_null.extern">;
def int_wasm_ref_is_null_func :
DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_funcref_ty],
[IntrNoMem], "llvm.wasm.ref.is_null.func">;
+def int_wasm_ref_is_null_exn :
+ DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_exnref_ty], [IntrNoMem],
+ "llvm.wasm.ref.is_null.exn">;
//===----------------------------------------------------------------------===//
// Table intrinsics
@@ -47,6 +52,9 @@ def int_wasm_table_set_externref :
def int_wasm_table_set_funcref :
DefaultAttrsIntrinsic<[], [llvm_table_ty, llvm_i32_ty, llvm_funcref_ty],
[IntrWriteMem]>;
+def int_wasm_table_set_exnref :
+ DefaultAttrsIntrinsic<[], [llvm_table_ty, llvm_i32_ty, llvm_exnref_ty],
+ [IntrWriteMem]>;
def int_wasm_table_get_externref :
DefaultAttrsIntrinsic<[llvm_externref_ty], [llvm_table_ty, llvm_i32_ty],
@@ -54,6 +62,9 @@ def int_wasm_table_get_externref :
def int_wasm_table_get_funcref :
DefaultAttrsIntrinsic<[llvm_funcref_ty], [llvm_table_ty, llvm_i32_ty],
[IntrReadMem]>;
+def int_wasm_table_get_exnref :
+ DefaultAttrsIntrinsic<[llvm_exnref_ty], [llvm_table_ty, llvm_i32_ty],
+ [IntrReadMem]>;
// Query the current table size, and increase the current table size.
def int_wasm_table_size :
@@ -68,6 +79,9 @@ def int_wasm_table_grow_externref :
def int_wasm_table_grow_funcref :
DefaultAttrsIntrinsic<[llvm_i32_ty],
[llvm_table_ty, llvm_funcref_ty, llvm_i32_ty], []>;
+def int_wasm_table_grow_exnref :
+ DefaultAttrsIntrinsic<[llvm_i32_ty],
+ [llvm_table_ty, llvm_exnref_ty, llvm_i32_ty], []>;
def int_wasm_table_fill_externref :
DefaultAttrsIntrinsic<[],
[llvm_table_ty, llvm_i32_ty, llvm_externref_ty,
@@ -76,6 +90,10 @@ def int_wasm_table_fill_funcref :
DefaultAttrsIntrinsic<[],
[llvm_table_ty, llvm_i32_ty, llvm_funcref_ty,
llvm_i32_ty], []>;
+def int_wasm_table_fill_exnref :
+ DefaultAttrsIntrinsic<[],
+ [llvm_table_ty, llvm_i32_ty, llvm_exnref_ty,
+ llvm_i32_ty], []>;
//===----------------------------------------------------------------------===//
// Trapping float-to-int conversions
diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp
index 58db686ec7d57..078894d5ac4ed 100644
--- a/llvm/lib/CodeGen/ValueTypes.cpp
+++ b/llvm/lib/CodeGen/ValueTypes.cpp
@@ -181,6 +181,7 @@ std::string EVT::getEVTString() const {
case MVT::Metadata: return "Metadata";
case MVT::Untyped: return "Untyped";
case MVT::funcref: return "funcref";
+ case MVT::exnref: return "exnref";
case MVT::externref: return "externref";
case MVT::aarch64svcount:
return "aarch64svcount";
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 6507a0e5950eb..872a1214d4f0e 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -187,6 +187,7 @@ static wasm::ValType parseValType(WasmObjectFile::ReadContext &Ctx,
case wasm::WASM_TYPE_V128:
case wasm::WASM_TYPE_FUNCREF:
case wasm::WASM_TYPE_EXTERNREF:
+ case wasm::WASM_TYPE_EXNREF:
return wasm::ValType(Code);
}
if (Code == wasm::WASM_TYPE_NULLABLE || Code == wasm::WASM_TYPE_NONNULLABLE) {
@@ -1288,6 +1289,7 @@ Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
auto ElemType = Im.Table.ElemType;
if (ElemType != wasm::ValType::FUNCREF &&
ElemType != wasm::ValType::EXTERNREF &&
+ ElemType != wasm::ValType::EXNREF &&
ElemType != wasm::ValType::OTHERREF)
return make_error<GenericBinaryError>("invalid table element type",
object_error::parse_failed);
@@ -1346,6 +1348,7 @@ Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
auto ElemType = Tables.back().Type.ElemType;
if (ElemType != wasm::ValType::FUNCREF &&
ElemType != wasm::ValType::EXTERNREF &&
+ ElemType != wasm::ValType::EXNREF &&
ElemType != wasm::ValType::OTHERREF) {
return make_error<GenericBinaryError>("invalid table element type",
object_error::parse_failed);
@@ -1680,6 +1683,7 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
Segment.ElemKind = parseValType(Ctx, ElemKind);
if (Segment.ElemKind != wasm::ValType::FUNCREF &&
Segment.ElemKind != wasm::ValType::EXTERNREF &&
+ Segment.ElemKind != wasm::ValType::EXNREF &&
Segment.ElemKind != wasm::ValType::OTHERREF) {
return make_error<GenericBinaryError>("invalid elem type",
object_error::parse_failed);
diff --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp
index 544a91d03dce0..7ad338f65706d 100644
--- a/llvm/lib/ObjectYAML/WasmYAML.cpp
+++ b/llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -606,6 +606,7 @@ void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration(
ECase(V128);
ECase(FUNCREF);
ECase(EXTERNREF);
+ ECase(EXNREF);
ECase(OTHERREF);
#undef ECase
}
@@ -640,6 +641,7 @@ void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration(
#define ECase(X) IO.enumCase(Type, #X, CONCAT(X));
ECase(FUNCREF);
ECase(EXTERNREF);
+ ECase(EXNREF);
ECase(OTHERREF);
#undef ECase
}
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index d4e9fb057c44d..c1859a28488e1 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -353,6 +353,8 @@ inline bool isArgument(unsigned Opc) {
case WebAssembly::ARGUMENT_funcref_S:
case WebAssembly::ARGUMENT_externref:
case WebAssembly::ARGUMENT_externref_S:
+ case WebAssembly::ARGUMENT_exnref:
+ case WebAssembly::ARGUMENT_exnref_S:
return true;
default:
return false;
@@ -375,6 +377,8 @@ inline bool isCopy(unsigned Opc) {
case WebAssembly::COPY_FUNCREF_S:
case WebAssembly::COPY_EXTERNREF:
case WebAssembly::COPY_EXTERNREF_S:
+ case WebAssembly::COPY_EXNREF:
+ case WebAssembly::COPY_EXNREF_S:
return true;
default:
return false;
@@ -397,6 +401,8 @@ inline bool isTee(unsigned Opc) {
case WebAssembly::TEE_FUNCREF_S:
case WebAssembly::TEE_EXTERNREF:
case WebAssembly::TEE_EXTERNREF_S:
+ case WebAssembly::TEE_EXNREF:
+ case WebAssembly::TEE_EXNREF_S:
return true;
default:
return false;
@@ -487,6 +493,8 @@ inline bool isLocalGet(unsigned Opc) {
case WebAssembly::LOCAL_GET_FUNCREF_S:
case WebAssembly::LOCAL_GET_EXTERNREF:
case WebAssembly::LOCAL_GET_EXTERNREF_S:
+ case WebAssembly::LOCAL_GET_EXNREF:
+ case WebAssembly::LOCAL_GET_EXNREF_S:
return true;
default:
return false;
@@ -509,6 +517,8 @@ inline bool isLocalSet(unsigned Opc) {
case WebAssembly::LOCAL_SET_FUNCREF_S:
case WebAssembly::LOCAL_SET_EXTERNREF:
case WebAssembly::LOCAL_SET_EXTERNREF_S:
+ case WebAssembly::LOCAL_SET_EXNREF:
+ case WebAssembly::LOCAL_SET_EXNREF_S:
return true;
default:
return false;
@@ -531,6 +541,8 @@ inline bool isLocalTee(unsigned Opc) {
case WebAssembly::LOCAL_TEE_FUNCREF_S:
case WebAssembly::LOCAL_TEE_EXTERNREF:
case WebAssembly::LOCAL_TEE_EXTERNREF_S:
+ case WebAssembly::LOCAL_TEE_EXNREF:
+ case WebAssembly::LOCAL_TEE_EXNREF_S:
return true;
default:
return false;
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTypeUtilities.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTypeUtilities.cpp
index 8ea02bd2ad1ff..d9c8e22bbbaf5 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTypeUtilities.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTypeUtilities.cpp
@@ -27,6 +27,7 @@ std::optional<wasm::ValType> WebAssembly::parseType(StringRef Type) {
wasm::ValType::V128)
.Case("funcref", wasm::ValType::FUNCREF)
.Case("externref", wasm::ValType::EXTERNREF)
+ .Case("exnref", wasm::ValType::EXNREF)
.Default(std::nullopt);
}
@@ -40,6 +41,7 @@ WebAssembly::BlockType WebAssembly::parseBlockType(StringRef Type) {
.Case("v128", WebAssembly::BlockType::V128)
.Case("funcref", WebAssembly::BlockType::Funcref)
.Case("externref", WebAssembly::BlockType::Externref)
+ .Case("exnref", WebAssembly::BlockType::Exnref)
.Case("void", WebAssembly::BlockType::Void)
.Default(WebAssembly::BlockType::Invalid);
}
@@ -62,6 +64,8 @@ const char *WebAssembly::anyTypeToString(unsigned Type) {
return "funcref";
case wasm::WASM_TYPE_EXTERNREF:
return "externref";
+ case wasm::WASM_TYPE_EXNREF:
+ return "exnref";
case wasm::WASM_TYPE_FUNC:
return "func";
case wasm::WASM_TYPE_NORESULT:
@@ -110,6 +114,8 @@ wasm::ValType WebAssembly::regClassToValType(unsigned RC) {
return wasm::ValType::FUNCREF;
case WebAssembly::EXTERNREFRegClassID:
return wasm::ValType::EXTERNREF;
+ case WebAssembly::EXNREFRegClassID:
+ return wasm::ValType::EXNREF;
default:
llvm_unreachable("unexpected type");
}
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTypeUtilities.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTypeUtilities.h
index 486cf264d13e2..063ee4dba9068 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTypeUtilities.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTypeUtilities.h
@@ -32,6 +32,7 @@ enum class BlockType : unsigned {
V128 = unsigned(wasm::ValType::V128),
Externref = unsigned(wasm::ValType::EXTERNREF),
Funcref = unsigned(wasm::ValType::FUNCREF),
+ Exnref = unsigned(wasm::ValType::EXNREF),
// Multivalue blocks (and other non-void blocks) are only emitted when the
// blocks will never be exited and are at the ends of functions (see
// WebAssemblyCFGStackify::fixEndsAtEndOfFunction). They also are never made
@@ -41,7 +42,8 @@ enum class BlockType : unsigned {
};
inline bool isRefType(wasm::ValType Type) {
- return Type == wasm::ValType::EXTERNREF || Type == wasm::ValType::FUNCREF;
+ return Type == wasm::ValType::EXTERNREF || Type == wasm::ValType::FUNCREF ||
+ Type == wasm::ValType::EXNREF;
}
// Convert ValType or a list/signature of ValTypes to a string.
diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
index fac2e0d935f5a..6e5905c301ad5 100644
--- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
+++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
@@ -33,6 +33,7 @@ MVT WebAssembly::parseMVT(StringRef Type) {
.Case("v2i64", MVT::v2i64)
.Case("funcref", MVT::funcref)
.Case("externref", MVT::externref)
+ .Case("exnref", MVT::exnref)
.Default(MVT::INVALID_SIMPLE_VALUE_TYPE);
}
@@ -57,6 +58,8 @@ wasm::ValType WebAssembly::toValType(MVT Type) {
return wasm::ValType::FUNCREF;
case MVT::externref:
return wasm::ValType::EXTERNREF;
+ case MVT::exnref:
+ return wasm::ValType::EXNREF;
default:
llvm_unreachable("unexpected type");
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 3524abba8990a..958705d7c51a0 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -125,6 +125,8 @@ static char getInvokeSig(wasm::ValType VT) {
return 'F';
case wasm::ValType::EXTERNREF:
return 'X';
+ case wasm::ValType::EXNREF:
+ return 'E';
default:
llvm_unreachable("Unhandled wasm::ValType enum");
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
index 0159c44a79b76..3c6a29311a10e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
@@ -100,6 +100,8 @@ static unsigned getDropOpcode(const TargetRegisterClass *RC) {
return WebAssembly::DROP_FUNCREF;
if (RC == &WebAssembly::EXTERNREFRegClass)
return WebAssembly::DROP_EXTERNREF;
+ if (RC == &WebAssembly::EXNREFRegClass)
+ return WebAssembly::DROP_EXNREF;
llvm_unreachable("Unexpected register class");
}
@@ -119,6 +121,8 @@ static unsigned getLocalGetOpcode(const TargetRegisterClass *RC) {
return WebAssembly::LOCAL_GET_FUNCREF;
if (RC == &WebAssembly::EXTERNREFRegClass)
return WebAssembly::LOCAL_GET_EXTERNREF;
+ if (RC == &WebAssembly::EXNREFRegClass)
+ return WebAssembly::LOCAL_GET_EXNREF;
llvm_unreachable("Unexpected register class");
}
@@ -138,6 +142,8 @@ static unsigned getLocalSetOpcode(const TargetRegisterClass *RC) {
return WebAssembly::LOCAL_SET_FUNCREF;
if (RC == &WebAssembly::EXTERNREFRegClass)
return WebAssembly::LOCAL_SET_EXTERNREF;
+ if (RC == &WebAssembly::EXNREFRegClass)
+ return WebAssembly::LOCAL_SET_EXNREF;
llvm_unreachable("Unexpected register class");
}
@@ -157,6 +163,8 @@ static unsigned getLocalTeeOpcode(const TargetRegisterClass *RC) {
return WebAssembly::LOCAL_TEE_FUNCREF;
if (RC == &WebAssembly::EXTERNREFRegClass)
return WebAssembly::LOCAL_TEE_EXTERNREF;
+ if (RC == &WebAssembly::EXNREFRegClass)
+ return WebAssembly::LOCAL_TEE_EXNREF;
llvm_unreachable("Unexpected register class");
}
@@ -176,6 +184,8 @@ static MVT typeForRegClass(const TargetRegisterClass *RC) {
return MVT::funcref;
if (RC == &WebAssembly::EXTERNREFRegClass)
return MVT::externref;
+ if (RC == &WebAssembly::EXNREFRegClass)
+ return MVT::exnref;
llvm_unreachable("unrecognized register class");
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index 1c62290704fe4..708e259d1a4cd 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -137,6 +137,10 @@ class WebAssemblyFastISel final : public FastISel {
if (Subtarget->hasReferenceTypes())
return VT;
break;
+ case MVT::exnref:
+ if (Subtarget->hasReferenceTypes() && Subtarget->hasExceptionHandling())
+ return VT;
+ break;
case MVT::f16:
return MVT::f32;
case MVT::v16i8:
@@ -717,6 +721,10 @@ bool WebAssemblyFastISel::fastLowerArguments() {
Opc = WebAssembly::ARGUMENT_externref;
RC = &WebAssembly::EXTERNREFRegClass;
break;
+ case MVT::exnref:
+ Opc = WebAssembly::ARGUMENT_exnref;
+ RC = &WebAssembly::EXNREFRegClass;
+ break;
default:
return false;
}
@@ -821,6 +829,9 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
case MVT::externref:
ResultReg = createResultReg(&WebAssembly::EXTERNREFRegClass);
break;
+ case MVT::exnref:
+ ResultReg = createResultReg(&WebAssembly::EXNREFRegClass);
+ break;
default:
return false;
}
@@ -960,6 +971,10 @@ bool WebAssemblyFastISel::selectSelect(const Instruction *I) {
Opc = WebAssembly::SELECT_EXTERNREF;
RC = &WebAssembly::EXTERNREFRegClass;
break;
+ case MVT::exnref:
+ Opc = WebAssembly::SELECT_EXNREF;
+ RC = &WebAssembly::EXNREFRegClass;
+ break;
default:
return false;
}
@@ -1367,6 +1382,7 @@ bool WebAssemblyFastISel::selectRet(const Instruction *I) {
...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/93586
More information about the llvm-commits
mailing list