diff --git a/clang/test/CodeGen/WebAssembly/builtins-table.c b/clang/test/CodeGen/WebAssembly/builtins-table.c index 74bb2442fe552..eeed335855e40 100644 --- a/clang/test/CodeGen/WebAssembly/builtins-table.c +++ b/clang/test/CodeGen/WebAssembly/builtins-table.c @@ -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) { @@ -35,9 +35,9 @@ 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) { @@ -45,9 +45,9 @@ int test_builtin_wasm_table_grow(__externref_t ref, int 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) { diff --git a/clang/test/CodeGen/WebAssembly/wasm-externref.c b/clang/test/CodeGen/WebAssembly/wasm-externref.c index 788438bb4a86a..d226c51b7fd4e 100644 --- a/clang/test/CodeGen/WebAssembly/wasm-externref.c +++ b/clang/test/CodeGen/WebAssembly/wasm-externref.c @@ -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) { diff --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c index d486d12085f9f..135334c0cd0a1 100644 --- a/clang/test/CodeGen/builtins-wasm.c +++ b/clang/test/CodeGen/builtins-wasm.c @@ -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 } diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h index 0dfe9f029f9b1..15802c366a116 100644 --- a/llvm/include/llvm/IR/Intrinsics.h +++ b/llvm/include/llvm/IR/Intrinsics.h @@ -136,6 +136,8 @@ namespace Intrinsic { AMX, PPCQuad, AArch64Svcount, + WasmExternref, + WasmFuncref, } Kind; union { diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td index b93a5e7be1b51..f635a9c1fc95e 100644 --- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -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 //===----------------------------------------------------------------------===// diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp index 2d16ff2dfb2fb..fc77eb65d47a5 100644 --- a/llvm/lib/CodeGen/ValueTypes.cpp +++ b/llvm/lib/CodeGen/ValueTypes.cpp @@ -590,6 +590,10 @@ MVT MVT::getVT(Type *Ty, bool HandleUnknown){ TargetExtType *TargetExtTy = cast(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) diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 49e0c1c5883c2..679bf97bbe007 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -1183,10 +1183,10 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef 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)); @@ -1339,7 +1339,10 @@ static Type *DecodeFixedType(ArrayRef &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: @@ -1500,6 +1503,12 @@ static bool matchIntrinsicType( case IITDescriptor::AArch64Svcount: return !isa(Ty) || cast(Ty)->getName() != "aarch64.svcount"; + case IITDescriptor::WasmExternref: + return !isa(Ty) || + cast(Ty)->getName() != "wasm.externref"; + case IITDescriptor::WasmFuncref: + return !isa(Ty) || + cast(Ty)->getName() != "wasm.funcref"; case IITDescriptor::Vector: { VectorType *VT = dyn_cast(Ty); return !VT || VT->getElementCount() != D.Vector_Width || diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp index 8a1bf9654fdc6..127dc5b9147c9 100644 --- a/llvm/lib/IR/Type.cpp +++ b/llvm/lib/IR/Type.cpp @@ -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; } @@ -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)); } diff --git a/llvm/lib/Target/WebAssembly/CMakeLists.txt b/llvm/lib/Target/WebAssembly/CMakeLists.txt index bb2ccea5c1459..9cd1af1483272 100644 --- a/llvm/lib/Target/WebAssembly/CMakeLists.txt +++ b/llvm/lib/Target/WebAssembly/CMakeLists.txt @@ -35,7 +35,6 @@ add_llvm_target(WebAssemblyCodeGen WebAssemblyInstrInfo.cpp WebAssemblyLowerBrUnless.cpp WebAssemblyLowerEmscriptenEHSjLj.cpp - WebAssemblyLowerRefTypesIntPtrConv.cpp WebAssemblyMachineFunctionInfo.cpp WebAssemblyMCInstLower.cpp WebAssemblyMCLowerPrePass.cpp diff --git a/llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h b/llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h index 2239badca69c3..d2ab2c0f9e777 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h +++ b/llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h @@ -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) { diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h index a8860477a2472..768e883d2aba6 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h @@ -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(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(Ty); + return TargetTy && TargetTy->getName() == "wasm.funcref"; } /// Return true if this is a WebAssembly Reference Type. diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h index 91765ad117bdb..4a1fec52ce7a6 100644 --- a/llvm/lib/Target/WebAssembly/WebAssembly.h +++ b/llvm/lib/Target/WebAssembly/WebAssembly.h @@ -29,7 +29,6 @@ ModulePass *createWebAssemblyLowerEmscriptenEHSjLj(); ModulePass *createWebAssemblyAddMissingPrototypes(); ModulePass *createWebAssemblyFixFunctionBitcasts(); FunctionPass *createWebAssemblyOptimizeReturned(); -FunctionPass *createWebAssemblyLowerRefTypesIntPtrConv(); // ISel and immediate followup passes. FunctionPass *createWebAssemblyISelDag(WebAssemblyTargetMachine &TM, @@ -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 &); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISD.def b/llvm/lib/Target/WebAssembly/WebAssemblyISD.def index b8954f4693f0a..f4476b999804f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISD.def +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISD.def @@ -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) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 4bcf89690505e..35d7d431bdf8e 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -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 @@ -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); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h index 1d1338ab40d0e..91c71bbc2e561 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h @@ -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. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 608963d588635..46480fce5c666 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -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("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, + []>; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp deleted file mode 100644 index e0a2192112285..0000000000000 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp +++ /dev/null @@ -1,86 +0,0 @@ -//=== WebAssemblyLowerRefTypesIntPtrConv.cpp - -// Lower IntToPtr and PtrToInt on Reference Types ---===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// Lowers IntToPtr and PtrToInt instructions on reference types to -/// Trap instructions since they have been allowed to operate -/// on non-integral pointers. -/// -//===----------------------------------------------------------------------===// - -#include "Utils/WebAssemblyTypeUtilities.h" -#include "WebAssembly.h" -#include "WebAssemblySubtarget.h" -#include "llvm/IR/InstIterator.h" -#include "llvm/Pass.h" -#include - -using namespace llvm; - -#define DEBUG_TYPE "wasm-lower-reftypes-intptr-conv" - -namespace { -class WebAssemblyLowerRefTypesIntPtrConv final : public FunctionPass { - StringRef getPassName() const override { - return "WebAssembly Lower RefTypes Int-Ptr Conversions"; - } - - bool runOnFunction(Function &MF) override; - -public: - static char ID; // Pass identification - WebAssemblyLowerRefTypesIntPtrConv() : FunctionPass(ID) {} -}; -} // end anonymous namespace - -char WebAssemblyLowerRefTypesIntPtrConv::ID = 0; -INITIALIZE_PASS(WebAssemblyLowerRefTypesIntPtrConv, DEBUG_TYPE, - "WebAssembly Lower RefTypes Int-Ptr Conversions", false, false) - -FunctionPass *llvm::createWebAssemblyLowerRefTypesIntPtrConv() { - return new WebAssemblyLowerRefTypesIntPtrConv(); -} - -bool WebAssemblyLowerRefTypesIntPtrConv::runOnFunction(Function &F) { - LLVM_DEBUG(dbgs() << "********** Lower RefTypes IntPtr Convs **********\n" - "********** Function: " - << F.getName() << '\n'); - - // This function will check for uses of ptrtoint and inttoptr on reference - // types and replace them with a trap instruction. - // - // We replace the instruction by a trap instruction - // and its uses by null in the case of inttoptr and 0 in the - // case of ptrtoint. - std::set worklist; - - for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { - PtrToIntInst *PTI = dyn_cast(&*I); - IntToPtrInst *ITP = dyn_cast(&*I); - if (!(PTI && WebAssembly::isWebAssemblyReferenceType( - PTI->getPointerOperand()->getType())) && - !(ITP && WebAssembly::isWebAssemblyReferenceType(ITP->getDestTy()))) - continue; - - UndefValue *U = UndefValue::get(I->getType()); - I->replaceAllUsesWith(U); - - Function *TrapIntrin = - Intrinsic::getDeclaration(F.getParent(), Intrinsic::debugtrap); - CallInst::Create(TrapIntrin, {}, "", &*I); - - worklist.insert(&*I); - } - - // erase each instruction replaced by trap - for (Instruction *I : worklist) - I->eraseFromParent(); - - return !worklist.empty(); -} diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index 2db1b6493cc47..df71b9828142a 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -87,7 +87,6 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTarget() { initializeWebAssemblyDebugFixupPass(PR); initializeWebAssemblyPeepholePass(PR); initializeWebAssemblyMCLowerPrePassPass(PR); - initializeWebAssemblyLowerRefTypesIntPtrConvPass(PR); initializeWebAssemblyFixBrTableDefaultsPass(PR); initializeWebAssemblyDAGToDAGISelPass(PR); } @@ -609,7 +608,6 @@ void WebAssemblyPassConfig::addPreEmitPass() { bool WebAssemblyPassConfig::addPreISel() { TargetPassConfig::addPreISel(); - addPass(createWebAssemblyLowerRefTypesIntPtrConv()); return false; } diff --git a/llvm/test/CodeGen/WebAssembly/externref-globalget.ll b/llvm/test/CodeGen/WebAssembly/externref-globalget.ll index cdf98c42439f2..9ee98150a66f3 100644 --- a/llvm/test/CodeGen/WebAssembly/externref-globalget.ll +++ b/llvm/test/CodeGen/WebAssembly/externref-globalget.ll @@ -1,6 +1,6 @@ ; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s -%externref = type ptr addrspace(10) ;; addrspace 10 is nonintegral +%externref = type target("wasm.externref") ;; addrspace 10 is nonintegral @externref_global = local_unnamed_addr addrspace(1) global %externref undef diff --git a/llvm/test/CodeGen/WebAssembly/externref-globalset.ll b/llvm/test/CodeGen/WebAssembly/externref-globalset.ll index 5bfd673e89fa1..c5f9fe1fff8bf 100644 --- a/llvm/test/CodeGen/WebAssembly/externref-globalset.ll +++ b/llvm/test/CodeGen/WebAssembly/externref-globalset.ll @@ -1,6 +1,6 @@ ; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s | FileCheck %s -%externref = type ptr addrspace(10) ;; addrspace 10 is nonintegral +%externref = type target("wasm.externref") ;; addrspace 10 is nonintegral @externref_global = local_unnamed_addr addrspace(1) global %externref undef diff --git a/llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll b/llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll index 64f955b6ed0f0..bdf04f73c54a7 100644 --- a/llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll +++ b/llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll @@ -1,16 +1,10 @@ -; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types 2>&1 | FileCheck %s +; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR -%externref = type ptr addrspace(10) +%externref = type target("wasm.externref") define %externref @int_to_externref(i32 %i) { %ref = inttoptr i32 %i to %externref ret %externref %ref } - -; CHECK-LABEL: int_to_externref: -; CHECK-NEXT: .functype int_to_externref (i32) -> (externref) -; CHECK-NEXT: .local externref -; CHECK-NEXT: unreachable -; CHECK-NEXT: local.get 1 -; CHECK-NEXT: end_function +# CHECK-ERROR: error: invalid cast opcode for cast from 'i32' to 'target("wasm.externref")' diff --git a/llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll b/llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll index 22558796f0624..f3cfe31445b60 100644 --- a/llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll +++ b/llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll @@ -1,15 +1,10 @@ -; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types 2>&1 | FileCheck %s +; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR -%externref = type ptr addrspace(10) +%externref = type target("wasm.externref") define i32 @externref_to_int(%externref %ref) { %i = ptrtoint %externref %ref to i32 ret i32 %i } -; CHECK-LABEL: externref_to_int: -; CHECK-NEXT: .functype externref_to_int (externref) -> (i32) -; CHECK-NEXT: .local i32 -; CHECK-NEXT: unreachable -; CHECK-NEXT: local.get 1 -; CHECK-NEXT: end_function +# CHECK-ERROR: error: invalid cast opcode for cast from 'target("wasm.externref")' to 'i32' diff --git a/llvm/test/CodeGen/WebAssembly/externref-tableget.ll b/llvm/test/CodeGen/WebAssembly/externref-tableget.ll index d9ae7c8f6c9b1..1e36ea7efa164 100644 --- a/llvm/test/CodeGen/WebAssembly/externref-tableget.ll +++ b/llvm/test/CodeGen/WebAssembly/externref-tableget.ll @@ -1,6 +1,6 @@ ; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s -%externref = type ptr addrspace(10) ;; addrspace 10 is nonintegral +%externref = type target("wasm.externref") ;; addrspace 10 is nonintegral @externref_table = local_unnamed_addr addrspace(1) global [0 x %externref] undef diff --git a/llvm/test/CodeGen/WebAssembly/externref-tableset.ll b/llvm/test/CodeGen/WebAssembly/externref-tableset.ll index 37c663869428e..4ce77df9bfdd8 100644 --- a/llvm/test/CodeGen/WebAssembly/externref-tableset.ll +++ b/llvm/test/CodeGen/WebAssembly/externref-tableset.ll @@ -1,6 +1,6 @@ ; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s | FileCheck %s -%externref = type ptr addrspace(10) ;; addrspace 10 is nonintegral +%externref = type target("wasm.externref") ;; addrspace 10 is nonintegral @externref_table = local_unnamed_addr addrspace(1) global [0 x %externref] undef diff --git a/llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll b/llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll index 945045d902ef5..98a0e801af387 100644 --- a/llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll +++ b/llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll @@ -1,10 +1,10 @@ ; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR -%externref = type ptr addrspace(10) +%externref = type target("wasm.externref") define void @load_extern(%externref %ref) { %e = load %extern, %externref %ref ret void } -; CHECK-ERROR: error: loading unsized types is not allowed +; CHECK-ERROR: error: load operand must be a pointer to a first class type diff --git a/llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll b/llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll index ca01f69a08ad2..933fb61e8577f 100644 --- a/llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll +++ b/llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll @@ -1,10 +1,10 @@ ; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR -%externref = type ptr addrspace(10) +%externref = type target("wasm.externref") define void @store_extern(%externref %ref) { store %extern undef, %externref %ref ret void } -; CHECK-ERROR: error: storing unsized types is not allowed +; CHECK-ERROR: error: store operand must be a pointer diff --git a/llvm/test/CodeGen/WebAssembly/funcref-call.ll b/llvm/test/CodeGen/WebAssembly/funcref-call.ll index c4eb425244450..397f56acda64d 100644 --- a/llvm/test/CodeGen/WebAssembly/funcref-call.ll +++ b/llvm/test/CodeGen/WebAssembly/funcref-call.ll @@ -1,7 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s --mtriple=wasm32-unknown-unknown -mattr=+reference-types | FileCheck %s -%funcref = type ptr addrspace(20) ;; addrspace 20 is nonintegral +%funcref = type target("wasm.funcref") + +declare ptr @llvm.wasm.funcref.to_ptr(%funcref) nounwind ; CHECK: .tabletype __funcref_call_table, funcref, 1 @@ -18,7 +20,8 @@ define void @call_funcref(%funcref %ref) { ; CHECK-NEXT: ref.null_func ; CHECK-NEXT: table.set __funcref_call_table ; CHECK-NEXT: # fallthrough-return - call addrspace(20) void %ref() + %refptr = call ptr @llvm.wasm.funcref.to_ptr(%funcref %ref) + call void %refptr() ret void } @@ -40,6 +43,7 @@ define float @call_funcref_with_args(%funcref %ref) { ; CHECK-NEXT: table.set __funcref_call_table ; CHECK-NEXT: local.get 1 ; CHECK-NEXT: # fallthrough-return - %ret = call addrspace(20) float %ref(double 1.0, i32 2) + %refptr = call ptr @llvm.wasm.funcref.to_ptr(%funcref %ref) + %ret = call float %refptr(double 1.0, i32 2) ret float %ret } diff --git a/llvm/test/CodeGen/WebAssembly/funcref-globalget.ll b/llvm/test/CodeGen/WebAssembly/funcref-globalget.ll index 9aa7fdabfdea9..2634e5a6fc57e 100644 --- a/llvm/test/CodeGen/WebAssembly/funcref-globalget.ll +++ b/llvm/test/CodeGen/WebAssembly/funcref-globalget.ll @@ -1,6 +1,6 @@ ; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s -%funcref = type ptr addrspace(20) ;; addrspace 20 is nonintegral +%funcref = type target("wasm.funcref") @funcref_global = local_unnamed_addr addrspace(1) global %funcref undef diff --git a/llvm/test/CodeGen/WebAssembly/funcref-globalset.ll b/llvm/test/CodeGen/WebAssembly/funcref-globalset.ll index ca2feb6617996..791e8648537c0 100644 --- a/llvm/test/CodeGen/WebAssembly/funcref-globalset.ll +++ b/llvm/test/CodeGen/WebAssembly/funcref-globalset.ll @@ -1,6 +1,6 @@ ; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s -%funcref = type ptr addrspace(20) ;; addrspace 20 is nonintegral +%funcref = type target("wasm.funcref") @funcref_global = local_unnamed_addr addrspace(1) global %funcref undef diff --git a/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll b/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll index 74bbc802ac077..dc8cb19d3239a 100644 --- a/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll +++ b/llvm/test/CodeGen/WebAssembly/funcref-table_call.ll @@ -1,6 +1,6 @@ ; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s -%funcref = type ptr addrspace(20) ;; addrspace 20 is nonintegral +%funcref = type target("wasm.funcref") @funcref_table = local_unnamed_addr addrspace(1) global [0 x %funcref] undef diff --git a/llvm/test/CodeGen/WebAssembly/funcref-tableget.ll b/llvm/test/CodeGen/WebAssembly/funcref-tableget.ll index 3df308c5ddf80..2621dcde6a79b 100644 --- a/llvm/test/CodeGen/WebAssembly/funcref-tableget.ll +++ b/llvm/test/CodeGen/WebAssembly/funcref-tableget.ll @@ -1,6 +1,6 @@ ; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s -%funcref = type ptr addrspace(20) ;; addrspace 20 is nonintegral +%funcref = type target("wasm.funcref") @funcref_table = local_unnamed_addr addrspace(1) global [0 x %funcref] undef diff --git a/llvm/test/CodeGen/WebAssembly/funcref-tableset.ll b/llvm/test/CodeGen/WebAssembly/funcref-tableset.ll index 98e1b55613d7d..e62eb8a6f2d20 100644 --- a/llvm/test/CodeGen/WebAssembly/funcref-tableset.ll +++ b/llvm/test/CodeGen/WebAssembly/funcref-tableset.ll @@ -1,6 +1,6 @@ ; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s | FileCheck %s -%funcref = type ptr addrspace(20) ;; addrspace 20 is nonintegral +%funcref = type target("wasm.funcref") @funcref_table = local_unnamed_addr addrspace(1) global [0 x %funcref] undef diff --git a/llvm/test/CodeGen/WebAssembly/ref-null.ll b/llvm/test/CodeGen/WebAssembly/ref-null.ll index af6ddfd8e0814..f2f2a0dad378b 100644 --- a/llvm/test/CodeGen/WebAssembly/ref-null.ll +++ b/llvm/test/CodeGen/WebAssembly/ref-null.ll @@ -1,8 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc --mtriple=wasm32-unknown-unknown -mattr=+reference-types < %s | FileCheck %s -%externref = type ptr addrspace(10) ;; addrspace 10 is nonintegral -%funcref = type ptr addrspace(20) ;; addrspace 20 is nonintegral +%externref = type target("wasm.externref") +%funcref = type target("wasm.funcref") declare %externref @llvm.wasm.ref.null.extern() nounwind declare %funcref @llvm.wasm.ref.null.func() nounwind diff --git a/llvm/test/CodeGen/WebAssembly/table-copy.ll b/llvm/test/CodeGen/WebAssembly/table-copy.ll index 5c0647ada4ab0..6740d4863239c 100644 --- a/llvm/test/CodeGen/WebAssembly/table-copy.ll +++ b/llvm/test/CodeGen/WebAssembly/table-copy.ll @@ -1,6 +1,6 @@ ; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s | FileCheck %s -%externref = type ptr addrspace(10) ;; addrspace 10 is nonintegral +%externref = type target("wasm.externref") ;; addrspace 10 is nonintegral @externref_table1 = local_unnamed_addr addrspace(1) global [0 x %externref] undef @externref_table2 = local_unnamed_addr addrspace(1) global [0 x %externref] undef diff --git a/llvm/test/CodeGen/WebAssembly/table-fill.ll b/llvm/test/CodeGen/WebAssembly/table-fill.ll index 0b78124f038b1..13a3fc28a8ae9 100644 --- a/llvm/test/CodeGen/WebAssembly/table-fill.ll +++ b/llvm/test/CodeGen/WebAssembly/table-fill.ll @@ -1,6 +1,6 @@ ; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s | FileCheck %s -%externref = type ptr addrspace(10) ;; addrspace 10 is nonintegral +%externref = type target("wasm.externref") ;; addrspace 10 is nonintegral @externref_table = local_unnamed_addr addrspace(1) global [0 x %externref] undef diff --git a/llvm/test/CodeGen/WebAssembly/table-grow.ll b/llvm/test/CodeGen/WebAssembly/table-grow.ll index 614c3400a782b..2b5801ea2fa17 100644 --- a/llvm/test/CodeGen/WebAssembly/table-grow.ll +++ b/llvm/test/CodeGen/WebAssembly/table-grow.ll @@ -1,6 +1,6 @@ ; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s | FileCheck %s -%externref = type ptr addrspace(10) ;; addrspace 10 is nonintegral +%externref = type target("wasm.externref") @externref_table = local_unnamed_addr addrspace(1) global [0 x %externref] undef diff --git a/llvm/test/CodeGen/WebAssembly/table-size.ll b/llvm/test/CodeGen/WebAssembly/table-size.ll index 42cd2e8a909d7..2b8d0185bb049 100644 --- a/llvm/test/CodeGen/WebAssembly/table-size.ll +++ b/llvm/test/CodeGen/WebAssembly/table-size.ll @@ -1,6 +1,6 @@ ; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s | FileCheck %s -%externref = type ptr addrspace(10) ;; addrspace 10 is nonintegral +%externref = type target("wasm.externref") @externref_table = local_unnamed_addr addrspace(1) global [0 x %externref] undef diff --git a/llvm/test/CodeGen/WebAssembly/table-types.ll b/llvm/test/CodeGen/WebAssembly/table-types.ll index cb5e54e2af230..da04ba35dd58e 100644 --- a/llvm/test/CodeGen/WebAssembly/table-types.ll +++ b/llvm/test/CodeGen/WebAssembly/table-types.ll @@ -1,7 +1,7 @@ ; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s -%externref = type ptr addrspace(10) ;; addrspace 10 is nonintegral -%funcref = type ptr addrspace(20) ;; addrspace 20 is nonintegral +%externref = type target("wasm.externref") +%funcref = type target("wasm.funcref") ; CHECK: .tabletype eref_table, externref ; CHECK-NEXT: .globl eref_table diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/BUILD.gn index 949b3b2147405..e08a7603378cf 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/BUILD.gn @@ -52,7 +52,6 @@ static_library("LLVMWebAssemblyCodeGen") { "WebAssemblyLateEHPrepare.cpp", "WebAssemblyLowerBrUnless.cpp", "WebAssemblyLowerEmscriptenEHSjLj.cpp", - "WebAssemblyLowerRefTypesIntPtrConv.cpp", "WebAssemblyMCInstLower.cpp", "WebAssemblyMCLowerPrePass.cpp", "WebAssemblyMachineFunctionInfo.cpp",