[llvm] [WebAssembly,llvm] Add llvm.wasm.ref.test.func intrinsic, option 2 (PR #147486)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 8 06:13:42 PDT 2025


================
@@ -2253,6 +2255,72 @@ SDValue WebAssemblyTargetLowering::LowerIntrinsic(SDValue Op,
                            DAG.getTargetExternalSymbol(TlsBase, PtrVT)),
         0);
   }
+  case Intrinsic::wasm_ref_test_func: {
+    // First emit the TABLE_GET instruction to convert function pointer ==>
+    // funcref
+    MachineFunction &MF = DAG.getMachineFunction();
+    auto PtrVT = getPointerTy(MF.getDataLayout());
+    MCSymbol *Table =
+        WebAssembly::getOrCreateFunctionTableSymbol(MF.getContext(), Subtarget);
+    SDValue TableSym = DAG.getMCSymbol(Table, PtrVT);
+    SDValue FuncRef =
+        SDValue(DAG.getMachineNode(WebAssembly::TABLE_GET_FUNCREF, DL,
+                                   MVT::funcref, TableSym, Op.getOperand(1)),
+                0);
+
+    // Encode the signature information into the type index placeholder.
+    // This gets decoded and converted into the actual type signature in
+    // WebAssemblyMCInstLower.cpp.
+    auto NParams = Op.getNumOperands() - 2;
+    auto BitWidth = (NParams + 1) * 64;
+    auto Sig = APInt(BitWidth, 0);
+    // The return type has to be a BlockType since it can be void.
+    {
+      SDValue Operand = Op.getOperand(2);
+      MVT VT = Operand.getValueType().getSimpleVT();
+      WebAssembly::BlockType V;
+      if (VT == MVT::Untyped) {
+        V = WebAssembly::BlockType::Void;
+      } else if (VT == MVT::i32) {
+        V = WebAssembly::BlockType::I32;
+      } else if (VT == MVT::i64) {
+        V = WebAssembly::BlockType::I64;
+      } else if (VT == MVT::f32) {
+        V = WebAssembly::BlockType::F32;
+      } else if (VT == MVT::f64) {
+        V = WebAssembly::BlockType::F64;
+      } else {
+        llvm_unreachable("Unhandled type!");
+      }
+      Sig |= (int64_t)V;
+    }
+    for (unsigned i = 3; i < Op.getNumOperands(); ++i) {
+      SDValue Operand = Op.getOperand(i);
+      MVT VT = Operand.getValueType().getSimpleVT();
+      wasm::ValType V;
+      if (VT == MVT::i32) {
+        V = wasm::ValType::I32;
+      } else if (VT == MVT::i64) {
+        V = wasm::ValType::I64;
+      } else if (VT == MVT::f32) {
+        V = wasm::ValType::F32;
+      } else if (VT == MVT::f64) {
+        V = wasm::ValType::F64;
+      } else {
+        llvm_unreachable("Unhandled type!");
+      }
+      Sig <<= 64;
+      Sig |= (int64_t)V;
+    }
+
+    SmallVector<SDValue, 4> Ops;
+    Ops.push_back(DAG.getTargetConstant(
+        Sig, DL, EVT::getIntegerVT(*DAG.getContext(), BitWidth)));
+    Ops.push_back(FuncRef);
----------------
arsenm wrote:

This can be initializer list of array 

https://github.com/llvm/llvm-project/pull/147486


More information about the llvm-commits mailing list