Skip to content

[WebAssembly] Refactor Wasm Reference Types as TargetExtType #71540

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

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
16 changes: 8 additions & 8 deletions clang/test/CodeGen/WebAssembly/builtins-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ static __externref_t table[0];
// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_get
// CHECK-SAME: (i32 noundef [[INDEX:%.*]]) #[[ATTR0:[0-9]+]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = call ptr addrspace(10) @llvm.wasm.table.get.externref(ptr addrspace(1) @table, i32 [[INDEX]])
// CHECK-NEXT: ret ptr addrspace(10) [[TMP0]]
// CHECK-NEXT: [[TMP0:%.*]] = call target("wasm.externref") @llvm.wasm.table.get.externref(ptr addrspace(1) @table, i32 [[INDEX]])
// CHECK-NEXT: ret target("wasm.externref") [[TMP0]]
//
__externref_t test_builtin_wasm_table_get(int index) {
return __builtin_wasm_table_get(table, index);
}

// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_set
// CHECK-SAME: (i32 noundef [[INDEX:%.*]], ptr addrspace(10) [[REF:%.*]]) #[[ATTR0]] {
// CHECK-SAME: (i32 noundef [[INDEX:%.*]], target("wasm.externref") [[REF:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: call void @llvm.wasm.table.set.externref(ptr addrspace(1) @table, i32 [[INDEX]], ptr addrspace(10) [[REF]])
// CHECK-NEXT: call void @llvm.wasm.table.set.externref(ptr addrspace(1) @table, i32 [[INDEX]], target("wasm.externref") [[REF]])
// CHECK-NEXT: ret void
//
void test_builtin_wasm_table_set(int index, __externref_t ref) {
Expand All @@ -35,19 +35,19 @@ int test_builtin_wasm_table_size() {
}

// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_grow
// CHECK-SAME: (ptr addrspace(10) [[REF:%.*]], i32 noundef [[NELEM:%.*]]) #[[ATTR0]] {
// CHECK-SAME: (target("wasm.externref") [[REF:%.*]], i32 noundef [[NELEM:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.wasm.table.grow.externref(ptr addrspace(1) @table, ptr addrspace(10) [[REF]], i32 [[NELEM]])
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.wasm.table.grow.externref(ptr addrspace(1) @table, target("wasm.externref") [[REF]], i32 [[NELEM]])
// CHECK-NEXT: ret i32 [[TMP0]]
//
int test_builtin_wasm_table_grow(__externref_t ref, int nelem) {
return __builtin_wasm_table_grow(table, ref, nelem);
}

// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_fill
// CHECK-SAME: (i32 noundef [[INDEX:%.*]], ptr addrspace(10) [[REF:%.*]], i32 noundef [[NELEM:%.*]]) #[[ATTR0]] {
// CHECK-SAME: (i32 noundef [[INDEX:%.*]], target("wasm.externref") [[REF:%.*]], i32 noundef [[NELEM:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: call void @llvm.wasm.table.fill.externref(ptr addrspace(1) @table, i32 [[INDEX]], ptr addrspace(10) [[REF]], i32 [[NELEM]])
// CHECK-NEXT: call void @llvm.wasm.table.fill.externref(ptr addrspace(1) @table, i32 [[INDEX]], target("wasm.externref") [[REF]], i32 [[NELEM]])
// CHECK-NEXT: ret void
//
void test_builtin_wasm_table_fill(int index, __externref_t ref, int nelem) {
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CodeGen/WebAssembly/wasm-externref.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ void helper(externref_t);

// CHECK-LABEL: @handle(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[OBJ_ADDR:%.*]] = alloca ptr addrspace(10), align 1
// CHECK-NEXT: store ptr addrspace(10) [[OBJ:%.*]], ptr [[OBJ_ADDR]], align 1
// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(10), ptr [[OBJ_ADDR]], align 1
// CHECK-NEXT: call void @helper(ptr addrspace(10) [[TMP0]])
// CHECK-NEXT: [[OBJ_ADDR:%.*]] = alloca target("wasm.externref"), align 1
// CHECK-NEXT: store target("wasm.externref") [[OBJ:%.*]], ptr [[OBJ_ADDR]], align 1
// CHECK-NEXT: [[TMP0:%.*]] = load target("wasm.externref"), ptr [[OBJ_ADDR]], align 1
// CHECK-NEXT: call void @helper(target("wasm.externref") [[TMP0]])
// CHECK-NEXT: ret void
//
void handle(externref_t obj) {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGen/builtins-wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,6 @@ f32x4 relaxed_dot_bf16x8_add_f32_f32x4(u16x8 a, u16x8 b, f32x4 c) {

__externref_t externref_null() {
return __builtin_wasm_ref_null_extern();
// WEBASSEMBLY: tail call ptr addrspace(10) @llvm.wasm.ref.null.extern()
// WEBASSEMBLY: tail call target("wasm.externref") @llvm.wasm.ref.null.extern()
// WEBASSEMBLY-NEXT: ret
}
2 changes: 2 additions & 0 deletions llvm/include/llvm/IR/Intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ namespace Intrinsic {
AMX,
PPCQuad,
AArch64Svcount,
WasmExternref,
WasmFuncref,
} Kind;

union {
Expand Down
7 changes: 7 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsWebAssembly.td
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ def int_wasm_ref_is_null_func :
DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_funcref_ty],
[IntrNoMem], "llvm.wasm.ref.is_null.func">;

//===----------------------------------------------------------------------===//
// funcref target ext type -> pointer intrinsic
//===----------------------------------------------------------------------===//
def int_wasm_funcref_to_ptr :
DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_funcref_ty],
[IntrNoMem], "llvm.wasm.funcref.to_ptr">;

//===----------------------------------------------------------------------===//
// Table intrinsics
//===----------------------------------------------------------------------===//
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/CodeGen/ValueTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,10 @@ MVT MVT::getVT(Type *Ty, bool HandleUnknown){
TargetExtType *TargetExtTy = cast<TargetExtType>(Ty);
if (TargetExtTy->getName() == "aarch64.svcount")
return MVT(MVT::aarch64svcount);
else if(TargetExtTy->getName() == "wasm.externref")
return MVT(MVT::externref);
else if(TargetExtTy->getName() == "wasm.funcref")
return MVT(MVT::funcref);
else if (TargetExtTy->getName().starts_with("spirv."))
return MVT(MVT::spirvbuiltin);
if (HandleUnknown)
Expand Down
15 changes: 12 additions & 3 deletions llvm/lib/IR/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1183,10 +1183,10 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
DecodeIITType(NextElt, Infos, Info, OutputTable);
return;
case IIT_EXTERNREF:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 10));
OutputTable.push_back(IITDescriptor::get(IITDescriptor::WasmExternref, 0));
return;
case IIT_FUNCREF:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 20));
OutputTable.push_back(IITDescriptor::get(IITDescriptor::WasmFuncref, 0));
return;
case IIT_PTR:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
Expand Down Expand Up @@ -1339,7 +1339,10 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::PPCQuad: return Type::getPPC_FP128Ty(Context);
case IITDescriptor::AArch64Svcount:
return TargetExtType::get(Context, "aarch64.svcount");

case IITDescriptor::WasmExternref:
return TargetExtType::get(Context, "wasm.externref");
case IITDescriptor::WasmFuncref:
return TargetExtType::get(Context, "wasm.funcref");
case IITDescriptor::Integer:
return IntegerType::get(Context, D.Integer_Width);
case IITDescriptor::Vector:
Expand Down Expand Up @@ -1500,6 +1503,12 @@ static bool matchIntrinsicType(
case IITDescriptor::AArch64Svcount:
return !isa<TargetExtType>(Ty) ||
cast<TargetExtType>(Ty)->getName() != "aarch64.svcount";
case IITDescriptor::WasmExternref:
return !isa<TargetExtType>(Ty) ||
cast<TargetExtType>(Ty)->getName() != "wasm.externref";
case IITDescriptor::WasmFuncref:
return !isa<TargetExtType>(Ty) ||
cast<TargetExtType>(Ty)->getName() != "wasm.funcref";
case IITDescriptor::Vector: {
VectorType *VT = dyn_cast<VectorType>(Ty);
return !VT || VT->getElementCount() != D.Vector_Width ||
Expand Down
10 changes: 6 additions & 4 deletions llvm/lib/IR/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,12 @@ IntegerType *Type::getIntNTy(LLVMContext &C, unsigned N) {
}

Type *Type::getWasm_ExternrefTy(LLVMContext &C) {
// opaque pointer in addrspace(10)
static PointerType *Ty = PointerType::get(C, 10);
static TargetExtType *Ty = TargetExtType::get(C, "wasm.externref", {}, {});
return Ty;
}

Type *Type::getWasm_FuncrefTy(LLVMContext &C) {
// opaque pointer in addrspace(20)
static PointerType *Ty = PointerType::get(C, 20);
static TargetExtType *Ty = TargetExtType::get(C, "wasm.funcref", {}, {});
return Ty;
}

Expand Down Expand Up @@ -840,6 +838,10 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
return TargetTypeInfo(ScalableVectorType::get(Type::getInt1Ty(C), 16),
TargetExtType::HasZeroInit);

// Opaque types in the WebAssembly name space.
if (Name.startswith("wasm."))
return TargetTypeInfo(PointerType::getUnqual(C), TargetExtType::HasZeroInit, TargetExtType::CanBeGlobal);

return TargetTypeInfo(Type::getVoidTy(C));
}

Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/WebAssembly/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ add_llvm_target(WebAssemblyCodeGen
WebAssemblyInstrInfo.cpp
WebAssemblyLowerBrUnless.cpp
WebAssemblyLowerEmscriptenEHSjLj.cpp
WebAssemblyLowerRefTypesIntPtrConv.cpp
WebAssemblyMachineFunctionInfo.cpp
WebAssemblyMCInstLower.cpp
WebAssemblyMCLowerPrePass.cpp
Expand Down
6 changes: 1 addition & 5 deletions llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@ enum WasmAddressSpace : unsigned {
// linear memory: WebAssembly globals or WebAssembly locals. Loads and stores
// to these pointers are lowered to global.get / global.set or local.get /
// local.set, as appropriate.
WASM_ADDRESS_SPACE_VAR = 1,
// A non-integral address space for externref values
WASM_ADDRESS_SPACE_EXTERNREF = 10,
// A non-integral address space for funcref values
WASM_ADDRESS_SPACE_FUNCREF = 20,
WASM_ADDRESS_SPACE_VAR = 1
};

inline bool isDefaultAddressSpace(unsigned AS) {
Expand Down
10 changes: 4 additions & 6 deletions llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,14 @@ namespace WebAssembly {

/// Return true if this is a WebAssembly Externref Type.
inline bool isWebAssemblyExternrefType(const Type *Ty) {
return Ty->isPointerTy() &&
Ty->getPointerAddressSpace() ==
WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
const TargetExtType *TargetTy = dyn_cast<TargetExtType>(Ty);
return TargetTy && TargetTy->getName() == "wasm.externref";
}

/// Return true if this is a WebAssembly Funcref Type.
inline bool isWebAssemblyFuncrefType(const Type *Ty) {
return Ty->isPointerTy() &&
Ty->getPointerAddressSpace() ==
WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
const TargetExtType *TargetTy = dyn_cast<TargetExtType>(Ty);
return TargetTy && TargetTy->getName() == "wasm.funcref";
}

/// Return true if this is a WebAssembly Reference Type.
Expand Down
2 changes: 0 additions & 2 deletions llvm/lib/Target/WebAssembly/WebAssembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ ModulePass *createWebAssemblyLowerEmscriptenEHSjLj();
ModulePass *createWebAssemblyAddMissingPrototypes();
ModulePass *createWebAssemblyFixFunctionBitcasts();
FunctionPass *createWebAssemblyOptimizeReturned();
FunctionPass *createWebAssemblyLowerRefTypesIntPtrConv();

// ISel and immediate followup passes.
FunctionPass *createWebAssemblyISelDag(WebAssemblyTargetMachine &TM,
Expand Down Expand Up @@ -72,7 +71,6 @@ void initializeWebAssemblyFixIrreducibleControlFlowPass(PassRegistry &);
void initializeWebAssemblyLateEHPreparePass(PassRegistry &);
void initializeWebAssemblyLowerBrUnlessPass(PassRegistry &);
void initializeWebAssemblyLowerEmscriptenEHSjLjPass(PassRegistry &);
void initializeWebAssemblyLowerRefTypesIntPtrConvPass(PassRegistry &);
void initializeWebAssemblyMCLowerPrePassPass(PassRegistry &);
void initializeWebAssemblyMemIntrinsicResultsPass(PassRegistry &);
void initializeWebAssemblyNullifyDebugValueListsPass(PassRegistry &);
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyISD.def
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ HANDLE_NODETYPE(DEMOTE_ZERO)
HANDLE_NODETYPE(MEMORY_COPY)
HANDLE_NODETYPE(MEMORY_FILL)

// Pointer Conversion intrinsic for funcref
HANDLE_NODETYPE(FUNCREF_TO_PTR)

// Memory intrinsics
HANDLE_MEM_NODETYPE(GLOBAL_GET)
HANDLE_MEM_NODETYPE(GLOBAL_SET)
Expand Down
22 changes: 1 addition & 21 deletions llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,24 +362,6 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
setMinimumJumpTableEntries(2);
}

MVT WebAssemblyTargetLowering::getPointerTy(const DataLayout &DL,
uint32_t AS) const {
if (AS == WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF)
return MVT::externref;
if (AS == WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF)
return MVT::funcref;
return TargetLowering::getPointerTy(DL, AS);
}

MVT WebAssemblyTargetLowering::getPointerMemTy(const DataLayout &DL,
uint32_t AS) const {
if (AS == WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF)
return MVT::externref;
if (AS == WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF)
return MVT::funcref;
return TargetLowering::getPointerMemTy(DL, AS);
}

TargetLowering::AtomicExpansionKind
WebAssemblyTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
// We have wasm instructions for these
Expand Down Expand Up @@ -1257,9 +1239,7 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
SDValue TableSet = DAG.getMemIntrinsicNode(
WebAssemblyISD::TABLE_SET, DL, DAG.getVTList(MVT::Other), TableSetOps,
MVT::funcref,
// Machine Mem Operand args
MachinePointerInfo(
WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF),
MachinePointerInfo(),
CLI.CB->getCalledOperand()->getPointerAlignment(DAG.getDataLayout()),
MachineMemOperand::MOStore);

Expand Down
3 changes: 0 additions & 3 deletions llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ class WebAssemblyTargetLowering final : public TargetLowering {
WebAssemblyTargetLowering(const TargetMachine &TM,
const WebAssemblySubtarget &STI);

MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override;
MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const override;

private:
/// Keep a pointer to the WebAssemblySubtarget around so that we can make the
/// right decision when generating code for different targets.
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ def : Pat<(select (i32 (setne I32:$cond, 0)), rc:$lhs, rc:$rhs),
def : Pat<(select (i32 (seteq I32:$cond, 0)), rc:$lhs, rc:$rhs),
(!cast<Instruction>("SELECT_"#rc) rc:$rhs, rc:$lhs, I32:$cond)>;
}

// Define node for wasm.funcref.to_ptr intrinsic
// This will then be combined with a call to the result of the intrinsic
// to generate a proper funcref call, which is a table.set + a call indirect.
def WebAssemblyFuncrefToPtr_t : SDTypeProfile<1, 1, [SDTCisPtrTy<0>]>;
def WebAssemblyFuncrefToPtr : SDNode<"WebAssemblyISD::FUNCREF_TO_PTR", WebAssemblyFuncrefToPtr_t,
[]>;
86 changes: 0 additions & 86 deletions llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

This file was deleted.

2 changes: 0 additions & 2 deletions llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTarget() {
initializeWebAssemblyDebugFixupPass(PR);
initializeWebAssemblyPeepholePass(PR);
initializeWebAssemblyMCLowerPrePassPass(PR);
initializeWebAssemblyLowerRefTypesIntPtrConvPass(PR);
initializeWebAssemblyFixBrTableDefaultsPass(PR);
initializeWebAssemblyDAGToDAGISelPass(PR);
}
Expand Down Expand Up @@ -609,7 +608,6 @@ void WebAssemblyPassConfig::addPreEmitPass() {

bool WebAssemblyPassConfig::addPreISel() {
TargetPassConfig::addPreISel();
addPass(createWebAssemblyLowerRefTypesIntPtrConv());
return false;
}

Expand Down
Loading