================
@@ -2839,6 +2840,43 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
     return CGF.authPointerToPointerCast(Result, E->getType(), DestTy);
   }
   case CK_AddressSpaceConversion: {
+    llvm::Type *DestLTy = ConvertType(DestTy);
+    // WebAssembly reference types are opaque target extension types so an
+    // "address space conversion" involving them is not a real pointer cast.
+    auto IsWasmFuncref = [](llvm::Type *T) {
+      auto *TET = dyn_cast<llvm::TargetExtType>(T);
+      return TET && TET->getName() == "wasm.funcref";
+    };
+    bool SrcIsFuncref = IsWasmFuncref(ConvertType(E->getType()));
+    bool DestIsFuncref = IsWasmFuncref(DestLTy);
+    if (SrcIsFuncref && DestIsFuncref) {
+      // funcref -> funcref (e.g. between differently-typed funcrefs) is the
+      // identity on the opaque reference value.
+      return Visit(E);
+    }
+    if (SrcIsFuncref && !DestIsFuncref) {
+      // funcref -> pointer: use wasm_funcref_to_ptr. This will probably crash
+      // later in codegen since we haven't implemented a way to actually get a
+      // function pointer from a funcref.
+      llvm::Function *ToPtr =
+          CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_funcref_to_ptr);
+      return CGF.Builder.CreateCall(ToPtr, {Visit(E)});
+    }
+    if (!SrcIsFuncref && DestIsFuncref) {
+      // A null function pointer converts to a null funcref (ref.null func),
----------------
hoodmane wrote:

Yeah it's always null:
>   // The table offset at which to place function addresses.  We reserve zero
>   // for the null function pointer.
https://github.com/llvm/llvm-project/blob/main/lld/wasm/Config.h?plain=1#L99

but it would work fine to emit a table.get 0 for this too since that will just 
return null. Would allow us to delete this special case.

https://github.com/llvm/llvm-project/pull/203165
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to