Skip to content

[WebAssembly] support getVT from externref and funcref - #97080

Closed
HerrCai0907 wants to merge 5 commits into
llvm:mainfrom
HerrCai0907:fix69894
Closed

[WebAssembly] support getVT from externref and funcref#97080
HerrCai0907 wants to merge 5 commits into
llvm:mainfrom
HerrCai0907:fix69894

Conversation

@HerrCai0907

@HerrCai0907 HerrCai0907 commented Jun 28, 2024

Copy link
Copy Markdown
Contributor

Fixes: #69894
#71069 try to treat externref as invalid element type but It should be a normal opaque pointer containing some unknown data.
getVT should be inverse operation of getTypeForEVT which convert MVT::externref to externref.

@HerrCai0907
HerrCai0907 requested a review from pmatos June 28, 2024 16:25
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:WebAssembly llvm:ir labels Jun 28, 2024
@llvmbot

llvmbot commented Jun 28, 2024

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-backend-webassembly

@llvm/pr-subscribers-llvm-ir

Author: Congcong Cai (HerrCai0907)

Changes

Fixes: #69894


Full diff: https://github.com/llvm/llvm-project/pull/97080.diff

4 Files Affected:

  • (added) clang/test/CodeGen/WebAssembly/wasm-externref-novec.c (+18)
  • (modified) llvm/include/llvm/IR/Type.h (+2)
  • (modified) llvm/lib/CodeGen/ValueTypes.cpp (+9)
  • (modified) llvm/lib/IR/Type.cpp (+2-2)
diff --git a/clang/test/CodeGen/WebAssembly/wasm-externref-novec.c b/clang/test/CodeGen/WebAssembly/wasm-externref-novec.c
new file mode 100644
index 0000000000000..d91072f379623
--- /dev/null
+++ b/clang/test/CodeGen/WebAssembly/wasm-externref-novec.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -O2 -triple wasm32-unknown-unknown-wasm -target-feature +reference-types -emit-llvm -o - %s | FileCheck %s
+
+// From issue 69894. Reftypes need to be marked as not valid as vector elements.
+
+__externref_t foo(void);
+// CHECK: declare ptr addrspace(10) @foo()
+
+void bar(__externref_t);
+// CHECK: declare void @bar(ptr addrspace(10))
+
+void test(int flag, __externref_t ref1, __externref_t ref2) {
+  if (flag) {
+    ref1 = foo();
+    ref2 = foo();
+  }
+  bar(ref1);
+  bar(ref2);
+}
diff --git a/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h
index 1f0133c08e7d6..cacb0539b3ddf 100644
--- a/llvm/include/llvm/IR/Type.h
+++ b/llvm/include/llvm/IR/Type.h
@@ -479,6 +479,8 @@ class Type {
   }
   static Type *getFloatingPointTy(LLVMContext &C, const fltSemantics &S);
 
+  static constexpr unsigned WasmExternrefAddressSpace = 10;
+  static constexpr unsigned WasmFuncrefAddressSpace = 20;
   //===--------------------------------------------------------------------===//
   // Convenience methods for getting pointer types.
   //
diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp
index b0f736a49c20e..5aa7c406206d9 100644
--- a/llvm/lib/CodeGen/ValueTypes.cpp
+++ b/llvm/lib/CodeGen/ValueTypes.cpp
@@ -263,6 +263,15 @@ MVT MVT::getVT(Type *Ty, bool HandleUnknown){
       getVT(VTy->getElementType(), /*HandleUnknown=*/ false),
             VTy->getElementCount());
   }
+  case Type::PointerTyID: {
+    if (Ty->getPointerAddressSpace() == Type::WasmExternrefAddressSpace)
+      return MVT(MVT::externref);
+    if (Ty->getPointerAddressSpace() == Type::WasmFuncrefAddressSpace)
+      return MVT(MVT::funcref);
+    if (HandleUnknown)
+      return MVT(MVT::Other);
+    llvm_unreachable("Unknown pointer type!");
+  }
   }
 }
 
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 5c61ad9f000b0..2279b5eb873b7 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -261,13 +261,13 @@ 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 PointerType *Ty = PointerType::get(C, WasmExternrefAddressSpace);
   return Ty;
 }
 
 Type *Type::getWasm_FuncrefTy(LLVMContext &C) {
   // opaque pointer in addrspace(20)
-  static PointerType *Ty = PointerType::get(C, 20);
+  static PointerType *Ty = PointerType::get(C, WasmFuncrefAddressSpace);
   return Ty;
 }
 

@llvmbot

llvmbot commented Jun 28, 2024

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-clang

Author: Congcong Cai (HerrCai0907)

Changes

Fixes: #69894


Full diff: https://github.com/llvm/llvm-project/pull/97080.diff

4 Files Affected:

  • (added) clang/test/CodeGen/WebAssembly/wasm-externref-novec.c (+18)
  • (modified) llvm/include/llvm/IR/Type.h (+2)
  • (modified) llvm/lib/CodeGen/ValueTypes.cpp (+9)
  • (modified) llvm/lib/IR/Type.cpp (+2-2)
diff --git a/clang/test/CodeGen/WebAssembly/wasm-externref-novec.c b/clang/test/CodeGen/WebAssembly/wasm-externref-novec.c
new file mode 100644
index 0000000000000..d91072f379623
--- /dev/null
+++ b/clang/test/CodeGen/WebAssembly/wasm-externref-novec.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -O2 -triple wasm32-unknown-unknown-wasm -target-feature +reference-types -emit-llvm -o - %s | FileCheck %s
+
+// From issue 69894. Reftypes need to be marked as not valid as vector elements.
+
+__externref_t foo(void);
+// CHECK: declare ptr addrspace(10) @foo()
+
+void bar(__externref_t);
+// CHECK: declare void @bar(ptr addrspace(10))
+
+void test(int flag, __externref_t ref1, __externref_t ref2) {
+  if (flag) {
+    ref1 = foo();
+    ref2 = foo();
+  }
+  bar(ref1);
+  bar(ref2);
+}
diff --git a/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h
index 1f0133c08e7d6..cacb0539b3ddf 100644
--- a/llvm/include/llvm/IR/Type.h
+++ b/llvm/include/llvm/IR/Type.h
@@ -479,6 +479,8 @@ class Type {
   }
   static Type *getFloatingPointTy(LLVMContext &C, const fltSemantics &S);
 
+  static constexpr unsigned WasmExternrefAddressSpace = 10;
+  static constexpr unsigned WasmFuncrefAddressSpace = 20;
   //===--------------------------------------------------------------------===//
   // Convenience methods for getting pointer types.
   //
diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp
index b0f736a49c20e..5aa7c406206d9 100644
--- a/llvm/lib/CodeGen/ValueTypes.cpp
+++ b/llvm/lib/CodeGen/ValueTypes.cpp
@@ -263,6 +263,15 @@ MVT MVT::getVT(Type *Ty, bool HandleUnknown){
       getVT(VTy->getElementType(), /*HandleUnknown=*/ false),
             VTy->getElementCount());
   }
+  case Type::PointerTyID: {
+    if (Ty->getPointerAddressSpace() == Type::WasmExternrefAddressSpace)
+      return MVT(MVT::externref);
+    if (Ty->getPointerAddressSpace() == Type::WasmFuncrefAddressSpace)
+      return MVT(MVT::funcref);
+    if (HandleUnknown)
+      return MVT(MVT::Other);
+    llvm_unreachable("Unknown pointer type!");
+  }
   }
 }
 
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 5c61ad9f000b0..2279b5eb873b7 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -261,13 +261,13 @@ 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 PointerType *Ty = PointerType::get(C, WasmExternrefAddressSpace);
   return Ty;
 }
 
 Type *Type::getWasm_FuncrefTy(LLVMContext &C) {
   // opaque pointer in addrspace(20)
-  static PointerType *Ty = PointerType::get(C, 20);
+  static PointerType *Ty = PointerType::get(C, WasmFuncrefAddressSpace);
   return Ty;
 }
 

@aheejin aheejin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you compile a file that really vectorizes reference types? The attached test doesn't seem to actually end up getting vectorized after all. Can you add a test that get vectorized?

Comment thread clang/test/CodeGen/WebAssembly/wasm-externref-novec.c Outdated
Comment thread clang/test/CodeGen/WebAssembly/wasm-externref-novec.c Outdated
@HerrCai0907

Copy link
Copy Markdown
Contributor Author

What happens if you compile a file that really vectorizes reference types? The attached test doesn't seem to actually end up getting vectorized after all. Can you add a test that get vectorized?

Is it possible to vectorize external reference types? I don't think there are valid test case for it.

@HerrCai0907
HerrCai0907 deleted the fix69894 branch November 18, 2024 09:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:WebAssembly clang Clang issues not falling into any other category llvm:ir

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compilation crash targetting wasm with -O2 and reference types

3 participants