[llvm] a96d828 - [WebAssembly] Implementation of intrinsic for ref.null and HeapType removal
Paulo Matos via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 6 00:48:21 PST 2021
Author: Paulo Matos
Date: 2021-12-06T09:46:15+01:00
New Revision: a96d8285101546c92116246939c2d53c57b88cf0
URL: https://github.com/llvm/llvm-project/commit/a96d8285101546c92116246939c2d53c57b88cf0
DIFF: https://github.com/llvm/llvm-project/commit/a96d8285101546c92116246939c2d53c57b88cf0.diff
LOG: [WebAssembly] Implementation of intrinsic for ref.null and HeapType removal
This patch implements the intrinsic for ref.null.
In the process of implementing int_wasm_ref_null_func() and
int_wasm_ref_null_extern() intrinsics, it removes the redundant
HeapType.
This also causes the textual assembler syntax for ref.null to
change. Instead of receiving an argument: `func` or `extern`, the
instruction mnemonic is either ref.null_func or ref.null_extern,
without the need for a further operand.
Reviewed By: tlively
Differential Revision: https://reviews.llvm.org/D114979
Added:
llvm/test/CodeGen/WebAssembly/ref-null.ll
Modified:
llvm/include/llvm/IR/Intrinsics.td
llvm/include/llvm/IR/IntrinsicsWebAssembly.td
llvm/lib/IR/Function.cpp
llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td
llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
llvm/test/CodeGen/WebAssembly/funcref-call.ll
llvm/test/CodeGen/WebAssembly/funcref-table_call.ll
llvm/test/MC/WebAssembly/reference-types.s
llvm/utils/TableGen/IntrinsicEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 3e159550ce9bf..dcd3f12245e99 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -332,6 +332,9 @@ def llvm_v16f64_ty : LLVMType<v16f64>; // 16 x double
def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
+def llvm_externref_ty : LLVMType<externref>;
+def llvm_funcref_ty : LLVMType<funcref>;
+
//===----------------------------------------------------------------------===//
// Intrinsic Definitions.
//===----------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
index 6a8e6c797f85d..850b6500028b2 100644
--- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -23,6 +23,12 @@ def int_wasm_memory_grow : Intrinsic<[llvm_anyint_ty],
[llvm_i32_ty, LLVMMatchType<0>],
[]>;
+//===----------------------------------------------------------------------===//
+// ref.null intrinsics
+//===----------------------------------------------------------------------===//
+def int_wasm_ref_null_extern : Intrinsic<[llvm_externref_ty], [], [IntrNoMem]>;
+def int_wasm_ref_null_func : Intrinsic<[llvm_funcref_ty], [], [IntrNoMem]>;
+
//===----------------------------------------------------------------------===//
// Trapping float-to-int conversions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 63c85451fa9b2..f1a6402fb11b0 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -982,6 +982,8 @@ enum IIT_Info {
IIT_AMX = 51,
IIT_PPCF128 = 52,
IIT_V3 = 53,
+ IIT_EXTERNREF = 54,
+ IIT_FUNCREF = 55
};
static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
@@ -1097,6 +1099,14 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
OutputTable.push_back(IITDescriptor::getVector(1024, IsScalableVector));
DecodeIITType(NextElt, Infos, Info, OutputTable);
return;
+ case IIT_EXTERNREF:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 10));
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
+ return;
+ case IIT_FUNCREF:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 20));
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 8));
+ return;
case IIT_PTR:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
DecodeIITType(NextElt, Infos, Info, OutputTable);
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index 7d1e6c553f812..56689d3ee06b7 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -571,7 +571,6 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
// proper nesting.
bool ExpectBlockType = false;
bool ExpectFuncType = false;
- bool ExpectHeapType = false;
std::unique_ptr<WebAssemblyOperand> FunctionTable;
if (Name == "block") {
push(Block);
@@ -624,8 +623,6 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
if (parseFunctionTableOperand(&FunctionTable))
return true;
ExpectFuncType = true;
- } else if (Name == "ref.null") {
- ExpectHeapType = true;
}
if (ExpectFuncType || (ExpectBlockType && Lexer.is(AsmToken::LParen))) {
@@ -670,15 +667,6 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
return error("Unknown block type: ", Id);
addBlockTypeOperand(Operands, NameLoc, BT);
Parser.Lex();
- } else if (ExpectHeapType) {
- auto HeapType = WebAssembly::parseHeapType(Id.getString());
- if (HeapType == WebAssembly::HeapType::Invalid) {
- return error("Expected a heap type: ", Id);
- }
- Operands.push_back(std::make_unique<WebAssemblyOperand>(
- WebAssemblyOperand::Integer, Id.getLoc(), Id.getEndLoc(),
- WebAssemblyOperand::IntOp{static_cast<int64_t>(HeapType)}));
- Parser.Lex();
} else {
// Assume this identifier is a label.
const MCExpr *Val;
diff --git a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
index 2e1e4f0612195..5d38145559dae 100644
--- a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
+++ b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
@@ -241,28 +241,6 @@ MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction(
}
break;
}
- // heap_type operands, for e.g. ref.null:
- case WebAssembly::OPERAND_HEAPTYPE: {
- int64_t Val;
- uint64_t PrevSize = Size;
- if (!nextLEB(Val, Bytes, Size, true))
- return MCDisassembler::Fail;
- if (Val < 0 && Size == PrevSize + 1) {
- // The HeapType encoding is like BlockType, in that encodings that
- // decode as negative values indicate ValTypes. In practice we expect
- // either wasm::ValType::EXTERNREF or wasm::ValType::FUNCREF here.
- //
- // The positive SLEB values are reserved for future expansion and are
- // expected to be type indices in the typed function references
- // proposal, and should disassemble as MCSymbolRefExpr as in BlockType
- // above.
- MI.addOperand(MCOperand::createImm(Val & 0x7f));
- } else {
- MI.addOperand(
- MCOperand::createImm(int64_t(WebAssembly::HeapType::Invalid)));
- }
- break;
- }
// FP operands.
case WebAssembly::OPERAND_F32IMM: {
if (!parseImmediate<float>(MI, Size, Bytes))
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index 2967aaa00ad42..d72bfdbbfb992 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -366,26 +366,3 @@ void WebAssemblyInstPrinter::printWebAssemblySignatureOperand(const MCInst *MI,
}
}
}
-
-void WebAssemblyInstPrinter::printWebAssemblyHeapTypeOperand(const MCInst *MI,
- unsigned OpNo,
- raw_ostream &O) {
- const MCOperand &Op = MI->getOperand(OpNo);
- if (Op.isImm()) {
- switch (Op.getImm()) {
- case long(wasm::ValType::EXTERNREF):
- O << "extern";
- break;
- case long(wasm::ValType::FUNCREF):
- O << "func";
- break;
- default:
- O << "unsupported_heap_type_value";
- break;
- }
- } else {
- // Typed function references and other subtypes of funcref and externref
- // currently unimplemented.
- O << "unsupported_heap_type_operand";
- }
-}
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
index 7d980c78c3c9f..fe104cbca12ea 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
@@ -47,8 +47,6 @@ class WebAssemblyInstPrinter final : public MCInstPrinter {
raw_ostream &O);
void printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O);
- void printWebAssemblyHeapTypeOperand(const MCInst *MI, unsigned OpNo,
- raw_ostream &O);
// Autogenerated by tblgen.
std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
index 4961c2ef9529a..6e494b9430f71 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
@@ -106,9 +106,6 @@ void WebAssemblyMCCodeEmitter::encodeInstruction(
encodeSLEB128(int64_t(MO.getImm()), OS);
break;
case WebAssembly::OPERAND_SIGNATURE:
- case WebAssembly::OPERAND_HEAPTYPE:
- OS << uint8_t(MO.getImm());
- break;
case WebAssembly::OPERAND_VEC_I8IMM:
support::endian::write<uint8_t>(OS, MO.getImm(), support::little);
break;
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index d07bfce9abc16..b2f10ca93a4fc 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -78,8 +78,6 @@ enum OperandType {
OPERAND_BRLIST,
/// 32-bit unsigned table number.
OPERAND_TABLE,
- /// heap type immediate for ref.null.
- OPERAND_HEAPTYPE,
};
} // end namespace WebAssembly
diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
index 6f81431bba2d5..0412e524f800e 100644
--- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
+++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
@@ -41,13 +41,6 @@ Optional<wasm::ValType> WebAssembly::parseType(StringRef Type) {
return Optional<wasm::ValType>();
}
-WebAssembly::HeapType WebAssembly::parseHeapType(StringRef Type) {
- return StringSwitch<WebAssembly::HeapType>(Type)
- .Case("extern", WebAssembly::HeapType::Externref)
- .Case("func", WebAssembly::HeapType::Funcref)
- .Default(WebAssembly::HeapType::Invalid);
-}
-
WebAssembly::BlockType WebAssembly::parseBlockType(StringRef Type) {
// Multivalue block types are handled separately in parseSignature
return StringSwitch<WebAssembly::BlockType>(Type)
diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
index 8d757df27b34f..042d51c7d6cb9 100644
--- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -41,17 +41,9 @@ enum class BlockType : unsigned {
Multivalue = 0xffff,
};
-/// Used as immediate MachineOperands for heap types, e.g. for ref.null.
-enum class HeapType : unsigned {
- Invalid = 0x00,
- Externref = unsigned(wasm::ValType::EXTERNREF),
- Funcref = unsigned(wasm::ValType::FUNCREF),
-};
-
// Convert StringRef to ValType / HealType / BlockType
Optional<wasm::ValType> parseType(StringRef Type);
-HeapType parseHeapType(StringRef Type);
BlockType parseBlockType(StringRef Type);
MVT parseMVT(StringRef Type);
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 0df8f3e0e09c0..0c3ee545f8c55 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -644,8 +644,7 @@ LowerCallResults(MachineInstr &CallResults, DebugLoc DL, MachineBasicBlock *BB,
Register RegFuncref =
MF.getRegInfo().createVirtualRegister(&WebAssembly::FUNCREFRegClass);
MachineInstr *RefNull =
- BuildMI(MF, DL, TII.get(WebAssembly::REF_NULL_FUNCREF), RegFuncref)
- .addImm(static_cast<int32_t>(WebAssembly::HeapType::Funcref));
+ BuildMI(MF, DL, TII.get(WebAssembly::REF_NULL_FUNCREF), RegFuncref);
BB->insertAfter(Const0->getIterator(), RefNull);
MachineInstr *TableSet =
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
index ee9247a8bef95..3fb0af1d47a0c 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
@@ -202,11 +202,6 @@ def Signature : Operand<i32> {
let PrintMethod = "printWebAssemblySignatureOperand";
}
-let OperandType = "OPERAND_HEAPTYPE" in
-def HeapType : Operand<i32> {
- let PrintMethod = "printWebAssemblyHeapTypeOperand";
-}
-
let OperandType = "OPERAND_TYPEINDEX" in
def TypeIndex : Operand<i32>;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td
index ef9bd35d004a5..76a88caafc470 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td
@@ -11,13 +11,14 @@
///
//===----------------------------------------------------------------------===//
-multiclass REF_I<WebAssemblyRegClass rc, ValueType vt> {
- defm REF_NULL_#rc : I<(outs rc:$res), (ins HeapType:$heaptype),
- (outs), (ins HeapType:$heaptype),
- [],
- "ref.null\t$res, $heaptype",
- "ref.null\t$heaptype",
- 0xd0>,
+multiclass REF_I<WebAssemblyRegClass rc, ValueType vt, string ht> {
+ defm REF_NULL_#rc : I<(outs rc:$dst), (ins),
+ (outs), (ins),
+ [(set rc:$dst, (!cast<Intrinsic>("int_wasm_ref_null_" # ht)))],
+ "ref.null_" # ht # "$dst",
+ "ref.null_" # ht,
+ !cond(!eq(ht, "func") : 0xd070,
+ !eq(ht, "extern") : 0xd06f)>,
Requires<[HasReferenceTypes]>;
defm SELECT_#rc: I<(outs rc:$dst), (ins rc:$lhs, rc:$rhs, I32:$cond),
(outs), (ins),
@@ -28,8 +29,8 @@ multiclass REF_I<WebAssemblyRegClass rc, ValueType vt> {
Requires<[HasReferenceTypes]>;
}
-defm "" : REF_I<FUNCREF, funcref>;
-defm "" : REF_I<EXTERNREF, externref>;
+defm "" : REF_I<FUNCREF, funcref, "func">;
+defm "" : REF_I<EXTERNREF, externref, "extern">;
foreach rc = [FUNCREF, EXTERNREF] in {
def : Pat<(select (i32 (setne I32:$cond, 0)), rc:$lhs, rc:$rhs),
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
index 0b953a90aeabb..f315b63d7f67c 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -275,11 +275,6 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
SmallVector<wasm::ValType, 4>());
break;
}
- } else if (Info.OperandType == WebAssembly::OPERAND_HEAPTYPE) {
- assert(static_cast<WebAssembly::HeapType>(MO.getImm()) !=
- WebAssembly::HeapType::Invalid);
- // With typed function references, this will need a case for type
- // index operands. Otherwise, fall through.
}
}
MCOp = MCOperand::createImm(MO.getImm());
diff --git a/llvm/test/CodeGen/WebAssembly/funcref-call.ll b/llvm/test/CodeGen/WebAssembly/funcref-call.ll
index abe6b7b80b90c..f65ea111e1aca 100644
--- a/llvm/test/CodeGen/WebAssembly/funcref-call.ll
+++ b/llvm/test/CodeGen/WebAssembly/funcref-call.ll
@@ -18,7 +18,7 @@ define void @call_funcref(%funcref %ref) {
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: call_indirect __funcref_call_table, () -> ()
; CHECK-NEXT: i32.const 0
-; CHECK-NEXT: ref.null func
+; CHECK-NEXT: ref.null_func
; CHECK-NEXT: table.set __funcref_call_table
; CHECK-NEXT: end_function
diff --git a/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll b/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll
index e19749c24f40a..f87f38eae2aba 100644
--- a/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll
+++ b/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll
@@ -23,7 +23,7 @@ define void @call_funcref_from_table(i32 %i) {
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: call_indirect __funcref_call_table, () -> ()
; CHECK-NEXT: i32.const 0
-; CHECK-NEXT: ref.null func
+; CHECK-NEXT: ref.null_func
; CHECK-NEXT: table.set __funcref_call_table
; CHECK-NEXT: end_function
diff --git a/llvm/test/CodeGen/WebAssembly/ref-null.ll b/llvm/test/CodeGen/WebAssembly/ref-null.ll
new file mode 100644
index 0000000000000..d8c356b66acc2
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/ref-null.ll
@@ -0,0 +1,26 @@
+; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s | FileCheck %s
+
+%extern = type opaque
+%externref = type %extern addrspace(10)* ;; addrspace 10 is nonintegral
+%funcref = type i8 addrspace(20)* ;; addrspace 20 is nonintegral
+
+declare %externref @llvm.wasm.ref.null.extern() nounwind
+declare %funcref @llvm.wasm.ref.null.func() nounwind
+
+define %externref @get_null_extern() {
+; CHECK-LABEL: get_null_extern:
+; CHECK-NEXT: .functype get_null_extern () -> (externref)
+; CHECK-NEXT: ref.null_extern
+; CHECK-NEXT: end_function
+ %null = call %externref @llvm.wasm.ref.null.extern()
+ ret %externref %null
+}
+
+define %funcref @get_null_func() {
+; CHECK-LABEL: get_null_func:
+; CHECK-NEXT: .functype get_null_func () -> (funcref)
+; CHECK-NEXT: ref.null_func
+; CHECK-NEXT: end_function
+ %null = call %funcref @llvm.wasm.ref.null.func()
+ ret %funcref %null
+}
diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s
index 84b4c9e2f0ca5..48673d23173dd 100644
--- a/llvm/test/MC/WebAssembly/reference-types.s
+++ b/llvm/test/MC/WebAssembly/reference-types.s
@@ -2,13 +2,13 @@
# RUN: llvm-mc -show-encoding -triple=wasm64-unknown-unknown -mattr=+reference-types < %s | FileCheck %s
# CHECK-LABEL: ref_null_test:
-# CHECK: ref.null func # encoding: [0xd0,0x70]
-# CHECK: ref.null extern # encoding: [0xd0,0x6f]
+# CHECK: ref.null_func # encoding: [0xd0,0x70]
+# CHECK: ref.null_extern # encoding: [0xd0,0x6f]
ref_null_test:
.functype ref_null_test () -> ()
- ref.null func
+ ref.null_func
drop
- ref.null extern
+ ref.null_extern
drop
end_function
@@ -31,13 +31,13 @@ ref_sig_test_externref:
# CHECK: externref.select # encoding: [0x1b]
ref_select_test:
.functype ref_select_test () -> ()
- ref.null func
- ref.null func
+ ref.null_func
+ ref.null_func
i32.const 0
funcref.select
drop
- ref.null extern
- ref.null extern
+ ref.null_extern
+ ref.null_extern
i32.const 0
externref.select
drop
@@ -50,8 +50,8 @@ ref_block_test:
.functype ref_block_test () -> (externref, funcref)
block funcref
block externref
- ref.null extern
+ ref.null_extern
end_block
- ref.null func
+ ref.null_func
end_block
end_function
diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp
index 94e60b31f2451..f4e5eb59cb809 100644
--- a/llvm/utils/TableGen/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp
@@ -252,6 +252,8 @@ enum IIT_Info {
IIT_AMX = 51,
IIT_PPCF128 = 52,
IIT_V3 = 53,
+ IIT_EXTERNREF = 54,
+ IIT_FUNCREF = 55
};
static void EncodeFixedValueType(MVT::SimpleValueType VT,
@@ -285,6 +287,10 @@ static void EncodeFixedValueType(MVT::SimpleValueType VT,
case MVT::Other: return Sig.push_back(IIT_EMPTYSTRUCT);
// MVT::isVoid is used to represent varargs here.
case MVT::isVoid: return Sig.push_back(IIT_VARARG);
+ case MVT::externref:
+ return Sig.push_back(IIT_EXTERNREF);
+ case MVT::funcref:
+ return Sig.push_back(IIT_FUNCREF);
}
}
More information about the llvm-commits
mailing list