[PATCH] D155978: [SPIRV] Add SPIR-V logical triple.

2023-08-11 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added inline comments.



Comment at: llvm/include/llvm/TargetParser/Triple.h:106
+wasm32,  // WebAssembly with 32-bit pointers
+wasm64,  // WebAssembly with 64-bit pointers
 renderscript32, // 32-bit RenderScript

Keenuts wrote:
> pmatos wrote:
> > No need to reindent the whole block to add a single line.
> IIRC it I did a clang-format because the buildbot complained the format was 
> not right.
> Reverted the clang-format commit (which seems better, I agree), and I'll see 
> if the bots complains.
I know what you did and it makes sense - I did the same myself while working on 
another backend but lets try not to change such a large amount of lines in a 
patch focused on something else. I think it's certainly better to propose this 
change in a single NFC patch if we think that clang-format output is better 
than the existing formatting.



Comment at: llvm/unittests/TargetParser/TripleTest.cpp:1307
+  EXPECT_TRUE(T.isSPIRV());
+
   T.setArch(Triple::spirv32);

Keenuts wrote:
> pmatos wrote:
> > I am not well-versed in SPIRV for gfx but if we are using 32bits in SPIRV 
> > logical, can't we reuse spirv32? Is there some sort of strong reason not to 
> > or adding spirv for logical spirv as an alternative to spirv32 and spirv64 
> > is just easier?
> This is a very valid question! And I'm not sure of the best option.
> My understanding is: in logical SPIR-V, there are no notion of pointer size, 
> or architecture size. We cannot offset pointers by a sizeof(), or do such 
> things.
> 
> But the options I had didn't seem to allow this kind of "undefined 
> architecture".
> I chose 32bits here because the IDs are 32bit. But pointer addresses are not, 
> so returning 32bit is not quite right either.
> 
> 
This is a tricky one tbh - I would have to do a bit more research to have a 
more insighful reply here. Maybe @mpaszkowski or @Anastasia can add more.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155978/new/

https://reviews.llvm.org/D155978

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D155978: [SPIRV] Add SPIR-V logical triple.

2023-08-11 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added subscribers: iliya-diyachkov, zuban32.
pmatos added a comment.

Thanks for the patch. Left a few comments. Others can take a better look, I am 
sure. Maybe @iliya-diyachkov or @zuban32 can take a look as well.




Comment at: llvm/include/llvm/TargetParser/Triple.h:106
+wasm32,  // WebAssembly with 32-bit pointers
+wasm64,  // WebAssembly with 64-bit pointers
 renderscript32, // 32-bit RenderScript

No need to reindent the whole block to add a single line.



Comment at: llvm/lib/TargetParser/Triple.cpp:74
+  case spirv:
+return "spirv";
   case spirv32:return "spirv32";

This should be in the same line.



Comment at: llvm/lib/TargetParser/Triple.cpp:387
+  .Case("spir64", spir64)
+  .Case("spirv", spirv)
+  .Case("spirv32", spirv32)

Same as above. I guess there's no need to reindent a whole block.



Comment at: llvm/lib/TargetParser/Triple.cpp:529
+  .Case("spir64", Triple::spir64)
+  .Cases("spirv", "spirv1.0", "spirv1.1", "spirv1.2", "spirv1.3",
+ "spirv1.4", "spirv1.5", Triple::spirv)

Whole block reindent.



Comment at: llvm/unittests/TargetParser/TripleTest.cpp:1307
+  EXPECT_TRUE(T.isSPIRV());
+
   T.setArch(Triple::spirv32);

I am not well-versed in SPIRV for gfx but if we are using 32bits in SPIRV 
logical, can't we reuse spirv32? Is there some sort of strong reason not to or 
adding spirv for logical spirv as an alternative to spirv32 and spirv64 is just 
easier?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155978/new/

https://reviews.llvm.org/D155978

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-06-10 Thread Paulo Matos via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG55aeb23fe008: [clang][WebAssembly] Implement support for 
table types and builtins (authored by pmatos).

Changed prior to commit:
  https://reviews.llvm.org/D139010?vs=526578&id=530204#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-table-ped.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI && WebAssembly::isWebAssemblyReferenceType(
+ PTI->getPointerOperand()->getType())) &&
+!(ITP && WebAssembly::isWebAssemblyReferenceType(ITP->getDestTy(
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1214,8 +1214,8 @@
 
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
-  if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  if (CLI.CB && WebAssembly::isWebAssemblyFuncrefType(
+CLI.CB->getCalledOperand()->getType())) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -18,6 +18,7 @@
 #include "MCTargetDesc/WebAssemblyMCTypeUtilities.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/WasmAddressSpaces.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/MC/MCSymbolWasm.h"
 
@@ -27,41 +28,21 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
+/// Return

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-06-10 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

In D139010#4400303 , @aaron.ballman 
wrote:

> Spotted a typo in the docs, but otherwise LGTM (thanks for your patience 
> while I was out last week).

Thanks for your time one this.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152126: [WebAssembly] Add tests ensuring rotates persist

2023-06-05 Thread Paulo Matos via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9571a28ee4e8: [WebAssembly] Add tests ensuring rotates 
persist (authored by pmatos).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152126/new/

https://reviews.llvm.org/D152126

Files:
  clang/test/CodeGen/WebAssembly/wasm-rotate.c
  llvm/test/CodeGen/WebAssembly/rotate-i3264.ll

Index: llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: sed 's/iX/i32/g' %s | llc --mtriple=wasm32-unknown-unknown | FileCheck --check-prefix=I32 %s
+; RUN: sed 's/iX/i64/g' %s | llc --mtriple=wasm64-unknown-unknown | FileCheck --check-prefix=I64 %s
+
+declare iX @llvm.fshl.iX(iX, iX, iX)
+declare iX @llvm.fshr.iX(iX, iX, iX)
+
+; from https://github.com/llvm/llvm-project/issues/62703
+
+define iX @testLeft(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testLeft:
+; I32: .functype testLeft (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotl
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testLeft:
+; I64: .functype testLeft (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotl
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshl.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
+
+define iX @testRight(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testRight:
+; I32: .functype testRight (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotr
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testRight:
+; I64: .functype testRight (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotr
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshr.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
Index: clang/test/CodeGen/WebAssembly/wasm-rotate.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-rotate.c
@@ -0,0 +1,53 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -o - -emit-llvm %s | FileCheck --check-prefix=WEBASSEMBLY32 %s
+// RUN: %clang_cc1 -triple wasm64-unknown-unknown -o - -emit-llvm %s | FileCheck --check-prefix=WEBASSEMBLY64 %s
+
+// WEBASSEMBLY32-LABEL: define i32 @test32
+// WEBASSEMBLY32-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+// WEBASSEMBLY32-NEXT:  entry:
+// WEBASSEMBLY32-NEXT:[[X_ADDR:%.*]] = alloca i32, align 4
+// WEBASSEMBLY32-NEXT:store i32 [[X]], ptr [[X_ADDR]], align 4
+// WEBASSEMBLY32-NEXT:[[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// WEBASSEMBLY32-NEXT:[[AND:%.*]] = and i32 [[TMP0]], -16711936
+// WEBASSEMBLY32-NEXT:[[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[AND]], i32 [[AND]], i32 8)
+// WEBASSEMBLY32-NEXT:ret i32 [[TMP1]]
+//
+// WEBASSEMBLY64-LABEL: define i32 @test32
+// WEBASSEMBLY64-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+// WEBASSEMBLY64-NEXT:  entry:
+// WEBASSEMBLY64-NEXT:[[X_ADDR:%.*]] = alloca i32, align 4
+// WEBASSEMBLY64-NEXT:store i32 [[X]], ptr [[X_ADDR]], align 4
+// WEBASSEMBLY64-NEXT:[[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// WEBASSEMBLY64-NEXT:[[AND:%.*]] = and i32 [[TMP0]], -16711936
+// WEBASSEMBLY64-NEXT:[[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[AND]], i32 [[AND]], i32 8)
+// WEBASSEMBLY64-NEXT:ret i32 [[TMP1]]
+//
+unsigned int test32(unsigned int x) {
+  return __builtin_rotateleft32((x & 0xFF00FF00), 8);
+}
+
+// WEBASSEMBLY32-LABEL: define i32 @test64
+// WEBASSEMBLY32-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0]] {
+// WEBASSEMBLY32-NEXT:  entry:
+// WEBASSEMBLY32-NEXT:[[X_ADDR:%.*]] = alloca i32, align 4
+// WEBASSEMBLY32-NEXT:store i32 [[X]], ptr [[X_ADDR]], align 4
+// WEBASSEMBLY32-NEXT:[[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// WEBASSEMBLY32-NEXT:[[CONV:%.*]] = zext i32 [[TMP0]] to i64
+// WEBASSEMBLY32-NEXT:[[AND:%.*]] = and i64 [[CONV]], -71777214294589696
+// WEBASSEMBLY32-NEXT:[[TMP1:%.*]] = call i64 @llvm.fshl.i64(i64 [[AND]], i64 [[AND]], i64 8)
+// WEBASSEMBLY32-NEXT:[[CONV1:%.*]] = trunc i64 [[TMP1]] to i32
+// WEBASSEMBLY32-NEXT:ret i32 [[CONV1]]
+//
+// WEBASSEMBLY64-LABEL: define i64 @test64
+// WEBASSEMBLY64-SAME: (i64 noundef [[X:%.*]]) #[[ATTR0]] {
+// WEBASSEMBLY64-NEXT:  entry:
+// WEBASSEMBLY64-NEXT:[[X_ADDR:%.*]] = alloca i64, align 8
+// WEBASSEMBLY64-NEXT:store i64 [[X]], ptr [[X_ADDR]], align 8
+// WEBASSEMBLY64-NEXT:[[TMP0:%.*]] = load i64, ptr 

[PATCH] D152126: [WebAssembly] Add tests ensuring rotates persist

2023-06-05 Thread Paulo Matos via Phabricator via cfe-commits
pmatos created this revision.
pmatos added reviewers: dschuff, tlively.
Herald added subscribers: asb, wingo, sunfish, jgravelle-google, sbc100.
Herald added a project: All.
pmatos requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, aheejin.
Herald added projects: clang, LLVM.

Due to the nature of WebAssembly, it's always better to keep
rotates instead of trying to optimize it. Commit 9485d983 

disabled the generation of fsh for rotates, however these
tests ensure that future changes don't change the behaviour for
the Wasm backend that tends to have different optimization
requirements than other architectures. Also see:
https://github.com/llvm/llvm-project/issues/62703


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152126

Files:
  clang/test/CodeGen/WebAssembly/wasm-rotate.c
  llvm/test/CodeGen/WebAssembly/rotate-i3264.ll

Index: llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: sed 's/iX/i32/g' %s | llc --mtriple=wasm32-unknown-unknown | FileCheck --check-prefix=I32 %s
+; RUN: sed 's/iX/i64/g' %s | llc --mtriple=wasm64-unknown-unknown | FileCheck --check-prefix=I64 %s
+
+declare iX @llvm.fshl.iX(iX, iX, iX)
+declare iX @llvm.fshr.iX(iX, iX, iX)
+
+; from https://github.com/llvm/llvm-project/issues/62703
+
+define iX @testLeft(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testLeft:
+; I32: .functype testLeft (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotl
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testLeft:
+; I64: .functype testLeft (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotl
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshl.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
+
+define iX @testRight(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testRight:
+; I32: .functype testRight (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotr
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testRight:
+; I64: .functype testRight (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotr
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshr.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
Index: clang/test/CodeGen/WebAssembly/wasm-rotate.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-rotate.c
@@ -0,0 +1,53 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -o - -emit-llvm %s | FileCheck --check-prefix=WEBASSEMBLY32 %s
+// RUN: %clang_cc1 -triple wasm64-unknown-unknown -o - -emit-llvm %s | FileCheck --check-prefix=WEBASSEMBLY64 %s
+
+// WEBASSEMBLY32-LABEL: define i32 @test32
+// WEBASSEMBLY32-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+// WEBASSEMBLY32-NEXT:  entry:
+// WEBASSEMBLY32-NEXT:[[X_ADDR:%.*]] = alloca i32, align 4
+// WEBASSEMBLY32-NEXT:store i32 [[X]], ptr [[X_ADDR]], align 4
+// WEBASSEMBLY32-NEXT:[[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// WEBASSEMBLY32-NEXT:[[AND:%.*]] = and i32 [[TMP0]], -16711936
+// WEBASSEMBLY32-NEXT:[[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[AND]], i32 [[AND]], i32 8)
+// WEBASSEMBLY32-NEXT:ret i32 [[TMP1]]
+//
+// WEBASSEMBLY64-LABEL: define i32 @test32
+// WEBASSEMBLY64-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+// WEBASSEMBLY64-NEXT:  entry:
+// WEBASSEMBLY64-NEXT:[[X_ADDR:%.*]] = alloca i32, align 4
+// WEBASSEMBLY64-NEXT:store i32 [[X]], ptr [[X_ADDR]], align 4
+// WEBASSEMBLY64-NEXT:[[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// WEBASSEMBLY64-NEXT:[[AND:%.*]] = and i32 [[TMP0]], -16711936
+// WEBASSEMBLY64-NEXT:[[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[AND]], i32 [[AND]], i32 8)
+// WEBASSEMBLY64-NEXT:ret i32 [[TMP1]]
+//
+unsigned int test32(unsigned int x) {
+  return __builtin_rotateleft32((x & 0xFF00FF00), 8);
+}
+
+// WEBASSEMBLY32-LABEL: define i32 @test64
+// WEBASSEMBLY32-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0]] {
+// WEBASSEMBLY32-NEXT:  entry:
+// WEBASSEMBLY32-NEXT:[[X_ADDR:%.*]] = alloca i32, align 4
+// WEBASSEMBLY32-NEXT:store i32 [[X]], ptr [[X_ADDR]], align 4
+// WEBASSEMBLY32-NEXT:[[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// WEBASSEMBLY32-NEXT:[[CONV:%.*]] = zext i32 [[TMP0]] to i64
+// WEBASSEMBLY32-NEXT:[[AND:%.*]] = and i64 [[CONV]], -71777214294589696
+/

[PATCH] D150670: [InstCombine] Disable generation of fshl/fshr for rotates

2023-06-01 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

Landed, thanks for your patience. Lets hope it sticks.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [InstCombine] Disable generation of fshl/fshr for rotates

2023-06-01 Thread Paulo Matos via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9485d983ac0c: [InstCombine] Disable generation of fshl/fshr 
for rotates (authored by pmatos).

Changed prior to commit:
  https://reviews.llvm.org/D150670?vs=527326&id=527395#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

Files:
  llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
  llvm/test/Transforms/InstCombine/fsh.ll


Index: llvm/test/Transforms/InstCombine/fsh.ll
===
--- llvm/test/Transforms/InstCombine/fsh.ll
+++ llvm/test/Transforms/InstCombine/fsh.ll
@@ -440,12 +440,10 @@
   ret <2 x i32> %r
 }
 
-; TODO: Don't let SimplifyDemandedBits split up a rotate - keep the same 
operand.
-
 define i32 @rotl_common_demanded(i32 %a0) {
 ; CHECK-LABEL: @rotl_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i32 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[A0]], 
i32 8)
+; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 
8)
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %x = xor i32 %a0, 2
@@ -456,7 +454,7 @@
 define i33 @rotr_common_demanded(i33 %a0) {
 ; CHECK-LABEL: @rotr_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i33 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[A0]], 
i33 25)
+; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[X]], i33 
25)
 ; CHECK-NEXT:ret i33 [[R]]
 ;
   %x = xor i33 %a0, 2
@@ -704,6 +702,26 @@
   ret i32 %t3
 }
 
+define i32 @fsh_andconst_rotate(i32 %a) {
+; CHECK-LABEL: @fsh_andconst_rotate(
+; CHECK-NEXT:[[T2:%.*]] = lshr i32 [[A:%.*]], 16
+; CHECK-NEXT:ret i32 [[T2]]
+;
+  %t1 = and i32 %a, 4294901760 ; 0x
+  %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 16)
+  ret i32 %t2
+}
+
+define i32 @fsh_orconst_rotate(i32 %a) {
+; CHECK-LABEL: @fsh_orconst_rotate(
+; CHECK-NEXT:[[T2:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 
-268435456, i32 4)
+; CHECK-NEXT:ret i32 [[T2]]
+;
+  %t1 = or i32 %a, 4026531840 ; 0xf000
+  %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 4)
+  ret i32 %t2
+}
+
 define <2 x i31> @fshr_mask_args_same_vector(<2 x i31> %a) {
 ; CHECK-LABEL: @fshr_mask_args_same_vector(
 ; CHECK-NEXT:[[T3:%.*]] = shl <2 x i31> [[A:%.*]], 
Index: llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===
--- llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -912,9 +912,26 @@
 
 APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
 APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
-if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
-SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
-  return I;
+if (I->getOperand(0) != I->getOperand(1)) {
+  if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown,
+   Depth + 1) ||
+  SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
+return I;
+} else { // fshl is a rotate
+// Avoid converting rotate into funnel shift. 
+// Only simplify if one operand is constant.
+  KnownBits LHSKnown = computeKnownBits(I->getOperand(0), Depth + 1, 
I);
+  if (DemandedMaskLHS.isSubsetOf(LHSKnown.Zero | LHSKnown.One)) {
+replaceOperand(*I, 0, Constant::getIntegerValue(VTy, 
LHSKnown.One));
+return I;
+  }
+
+  KnownBits RHSKnown = computeKnownBits(I->getOperand(1), Depth + 1, 
I);
+  if (DemandedMaskRHS.isSubsetOf(RHSKnown.Zero | RHSKnown.One)) {
+replaceOperand(*I, 1, Constant::getIntegerValue(VTy, 
RHSKnown.One));
+return I;
+  }
+}
 
 Known.Zero = LHSKnown.Zero.shl(ShiftAmt) |
  RHSKnown.Zero.lshr(BitWidth - ShiftAmt);


Index: llvm/test/Transforms/InstCombine/fsh.ll
===
--- llvm/test/Transforms/InstCombine/fsh.ll
+++ llvm/test/Transforms/InstCombine/fsh.ll
@@ -440,12 +440,10 @@
   ret <2 x i32> %r
 }
 
-; TODO: Don't let SimplifyDemandedBits split up a rotate - keep the same operand.
-
 define i32 @rotl_common_demanded(i32 %a0) {
 ; CHECK-LABEL: @rotl_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i32 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[A0]], i32 8)
+; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 8)
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %x = xor i32 %a0, 2
@@ -456,7 +454,7 @@
 define i33 @rotr_common_demanded(i33 %a0) {
 ; CHECK-LABEL: @rotr_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xo

[PATCH] D150670: [InstCombine] Disable generation of fshl/fshr for rotates

2023-06-01 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

In D150670#4383823 , @nikic wrote:

> Can you please drop all wasm related tests and instead add an InstCombine 
> test for the fsh+and pattern?
>
> It would also be good to have a test where we can fold one side to a 
> constant, but that constant is not zero. We should then consider whether that 
> is profitable or not. (In that case we can't reduce to a simple shift and 
> will reduce to a shift and or with constant instead -- is that better or 
> worse than a rotate?)

I have added the tests. I looked into the output of WebAssembly and it looks 
good. Even in the case of the generation of a non-zero const, Wasm still 
managed to generate a rotate which is generally more profitable, since the 
runtime can be then the one choosing how to implement that depending on the 
hardware. In the general case, I am not sure what the right answer is tbh.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [InstCombine] Disable generation of fshl/fshr for rotates

2023-06-01 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 527326.
pmatos added a comment.

Simplify code according to @nikic suggestion. Add tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

Files:
  llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
  llvm/test/Transforms/InstCombine/fsh.ll


Index: llvm/test/Transforms/InstCombine/fsh.ll
===
--- llvm/test/Transforms/InstCombine/fsh.ll
+++ llvm/test/Transforms/InstCombine/fsh.ll
@@ -440,12 +440,10 @@
   ret <2 x i32> %r
 }
 
-; TODO: Don't let SimplifyDemandedBits split up a rotate - keep the same 
operand.
-
 define i32 @rotl_common_demanded(i32 %a0) {
 ; CHECK-LABEL: @rotl_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i32 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[A0]], 
i32 8)
+; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 
8)
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %x = xor i32 %a0, 2
@@ -456,7 +454,7 @@
 define i33 @rotr_common_demanded(i33 %a0) {
 ; CHECK-LABEL: @rotr_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i33 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[A0]], 
i33 25)
+; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[X]], i33 
25)
 ; CHECK-NEXT:ret i33 [[R]]
 ;
   %x = xor i33 %a0, 2
@@ -704,6 +702,26 @@
   ret i32 %t3
 }
 
+define i32 @fsh_andconst_rotate(i32 %a) {
+; CHECK-LABEL: @fsh_andconst_rotate(
+; CHECK-NEXT:[[T2:%.*]] = lshr i32 [[A:%.*]], 16
+; CHECK-NEXT:ret i32 [[T2]]
+;
+  %t1 = and i32 %a, 4294901760 ; 0x
+  %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 16)
+  ret i32 %t2
+}
+
+define i32 @fsh_orconst_rotate(i32 %a) {
+; CHECK-LABEL: @fsh_orconst_rotate(
+; CHECK-NEXT:[[T2:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 
-268435456, i32 4)
+; CHECK-NEXT:ret i32 [[T2]]
+;
+  %t1 = or i32 %a, 4026531840 ; 0xf000
+  %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 4)
+  ret i32 %t2
+}
+
 define <2 x i31> @fshr_mask_args_same_vector(<2 x i31> %a) {
 ; CHECK-LABEL: @fshr_mask_args_same_vector(
 ; CHECK-NEXT:[[T3:%.*]] = shl <2 x i31> [[A:%.*]], 
Index: llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===
--- llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -912,9 +912,24 @@
 
 APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
 APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
-if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
-SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
-  return I;
+if (I->getOperand(0) != I->getOperand(1)) {
+  if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown,
+   Depth + 1) ||
+  SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
+return I;
+} else { // fshl is a rotate
+  KnownBits LHSKnown = computeKnownBits(I->getOperand(0), Depth + 1, 
I);
+  if (DemandedMaskLHS.isSubsetOf(LHSKnown.Zero | LHSKnown.One)) {
+replaceOperand(*I, 0, Constant::getIntegerValue(VTy, 
LHSKnown.One));
+return I;
+  }
+
+  KnownBits RHSKnown = computeKnownBits(I->getOperand(1), Depth + 1, 
I);
+  if (DemandedMaskRHS.isSubsetOf(RHSKnown.Zero | RHSKnown.One)) {
+replaceOperand(*I, 1, Constant::getIntegerValue(VTy, 
RHSKnown.One));
+return I;
+  }
+}
 
 Known.Zero = LHSKnown.Zero.shl(ShiftAmt) |
  RHSKnown.Zero.lshr(BitWidth - ShiftAmt);


Index: llvm/test/Transforms/InstCombine/fsh.ll
===
--- llvm/test/Transforms/InstCombine/fsh.ll
+++ llvm/test/Transforms/InstCombine/fsh.ll
@@ -440,12 +440,10 @@
   ret <2 x i32> %r
 }
 
-; TODO: Don't let SimplifyDemandedBits split up a rotate - keep the same operand.
-
 define i32 @rotl_common_demanded(i32 %a0) {
 ; CHECK-LABEL: @rotl_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i32 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[A0]], i32 8)
+; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 8)
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %x = xor i32 %a0, 2
@@ -456,7 +454,7 @@
 define i33 @rotr_common_demanded(i33 %a0) {
 ; CHECK-LABEL: @rotr_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i33 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[A0]], i33 25)
+; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[X]], i33 25)
 ; CHECK-NEXT:ret i33 [[R]]
 ;
   %x = xor i33 %a0, 2
@@ -704,

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-05-30 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 526578.
pmatos added a comment.

Apply clang-format.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-table-ped.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI && WebAssembly::isWebAssemblyReferenceType(
+ PTI->getPointerOperand()->getType())) &&
+!(ITP && WebAssembly::isWebAssemblyReferenceType(ITP->getDestTy(
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,8 +1202,8 @@
 
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
-  if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  if (CLI.CB && WebAssembly::isWebAssemblyFuncrefType(
+CLI.CB->getCalledOperand()->getType())) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -18,6 +18,7 @@
 #include "MCTargetDesc/WebAssemblyMCTypeUtilities.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/WasmAddressSpaces.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/MC/MCSymbolWasm.h"
 
@@ -27,41 +28,21 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
+/// Return true if this is a WebAssembly Externref Type.
+inline bool isWebAssemblyExternrefType(const Type *Ty) {
+  return Ty->getPointerAddressSpace() ==
+ WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
 }
-inline bool isFuncrefType(

[PATCH] D150670: Disable generation of fshl/fshr for rotates

2023-05-30 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 526577.
pmatos added a comment.

Apply clang-format.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

Files:
  clang/test/CodeGen/WebAssembly/wasm-rotate.c
  llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
  llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
  llvm/test/Transforms/InstCombine/fsh.ll

Index: llvm/test/Transforms/InstCombine/fsh.ll
===
--- llvm/test/Transforms/InstCombine/fsh.ll
+++ llvm/test/Transforms/InstCombine/fsh.ll
@@ -440,12 +440,10 @@
   ret <2 x i32> %r
 }
 
-; TODO: Don't let SimplifyDemandedBits split up a rotate - keep the same operand.
-
 define i32 @rotl_common_demanded(i32 %a0) {
 ; CHECK-LABEL: @rotl_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i32 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[A0]], i32 8)
+; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 8)
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %x = xor i32 %a0, 2
@@ -456,7 +454,7 @@
 define i33 @rotr_common_demanded(i33 %a0) {
 ; CHECK-LABEL: @rotr_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i33 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[A0]], i33 25)
+; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[X]], i33 25)
 ; CHECK-NEXT:ret i33 [[R]]
 ;
   %x = xor i33 %a0, 2
Index: llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: sed 's/iX/i32/g' %s | llc --mtriple=wasm32-unknown-unknown | FileCheck --check-prefix=I32 %s
+; RUN: sed 's/iX/i64/g' %s | llc --mtriple=wasm64-unknown-unknown | FileCheck --check-prefix=I64 %s
+
+declare iX @llvm.fshl.iX(iX, iX, iX)
+declare iX @llvm.fshr.iX(iX, iX, iX)
+
+; from https://github.com/llvm/llvm-project/issues/62703
+
+define iX @testLeft(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testLeft:
+; I32: .functype testLeft (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotl
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testLeft:
+; I64: .functype testLeft (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotl
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshl.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
+
+define iX @testRight(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testRight:
+; I32: .functype testRight (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotr
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testRight:
+; I64: .functype testRight (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotr
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshr.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===
--- llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -912,9 +912,26 @@
 
 APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
 APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
-if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
-SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
-  return I;
+if (I->getOperand(0) != I->getOperand(1)) {
+  if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown,
+   Depth + 1) ||
+  SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
+return I;
+} else { // fshl is a rotate
+  KnownBits LHSKnown = computeKnownBits(I->getOperand(0), Depth + 1, I);
+  KnownBits RHSKnown = computeKnownBits(I->getOperand(1), Depth + 1, I);
+
+  // Although this is a rotate there are cases where we want to optimize
+  // it. If the demanded bits are known, then we proceed with the
+  // optimization.
+  if ((DemandedMaskLHS.isSubsetOf(LHSKnown.Zero | LHSKnown.One) ||
+   DemandedMaskRHS.isSubsetOf(RHSKnown.Zero | RHSKnown.One)) &&
+  (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown,
+Depth + 1) ||
+   SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown,
+Depth + 1)))
+return I;
+ 

[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-30 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 526559.
pmatos added a comment.

Fix up some spacing issues.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

Files:
  clang/test/CodeGen/WebAssembly/wasm-rotate.c
  llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
  llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
  llvm/test/Transforms/InstCombine/fsh.ll

Index: llvm/test/Transforms/InstCombine/fsh.ll
===
--- llvm/test/Transforms/InstCombine/fsh.ll
+++ llvm/test/Transforms/InstCombine/fsh.ll
@@ -440,12 +440,10 @@
   ret <2 x i32> %r
 }
 
-; TODO: Don't let SimplifyDemandedBits split up a rotate - keep the same operand.
-
 define i32 @rotl_common_demanded(i32 %a0) {
 ; CHECK-LABEL: @rotl_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i32 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[A0]], i32 8)
+; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 8)
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %x = xor i32 %a0, 2
@@ -456,7 +454,7 @@
 define i33 @rotr_common_demanded(i33 %a0) {
 ; CHECK-LABEL: @rotr_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i33 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[A0]], i33 25)
+; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[X]], i33 25)
 ; CHECK-NEXT:ret i33 [[R]]
 ;
   %x = xor i33 %a0, 2
Index: llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: sed 's/iX/i32/g' %s | llc --mtriple=wasm32-unknown-unknown | FileCheck --check-prefix=I32 %s
+; RUN: sed 's/iX/i64/g' %s | llc --mtriple=wasm64-unknown-unknown | FileCheck --check-prefix=I64 %s
+
+declare iX @llvm.fshl.iX(iX, iX, iX)
+declare iX @llvm.fshr.iX(iX, iX, iX)
+
+; from https://github.com/llvm/llvm-project/issues/62703
+
+define iX @testLeft(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testLeft:
+; I32: .functype testLeft (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotl
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testLeft:
+; I64: .functype testLeft (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotl
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshl.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
+
+define iX @testRight(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testRight:
+; I32: .functype testRight (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotr
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testRight:
+; I64: .functype testRight (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotr
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshr.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===
--- llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -912,9 +912,23 @@
 
 APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
 APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
-if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
-SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
-  return I;
+if (I->getOperand(0) != I->getOperand(1)) {
+if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
+SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
+return I;
+} else { // fshl is a rotate
+  KnownBits LHSKnown = computeKnownBits(I->getOperand(0), Depth + 1, I);
+  KnownBits RHSKnown = computeKnownBits(I->getOperand(1), Depth + 1, I);
+
+  // Although this is a rotate there are cases where we want to optimize
+  // it. If the demanded bits are known, then we proceed with the
+  // optimization.
+  if ((DemandedMaskLHS.isSubsetOf(LHSKnown.Zero | LHSKnown.One)
+  || DemandedMaskRHS.isSubsetOf(RHSKnown.Zero | RHSKnown.One)) &&
+  (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
+   SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))) 
+  return I;
+}
 
 Known.Zero = LHSKnown.Zero.shl(ShiftAmt) |
  RHS

[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-30 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 526556.
pmatos added a comment.

Implement optimization when demanded bits are known, skip otherwise for rotates.

@nikic Things look much better now. Thanks for your help with the changes in 
InstCombine. What do you think?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

Files:
  clang/test/CodeGen/WebAssembly/wasm-rotate.c
  llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
  llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
  llvm/test/Transforms/InstCombine/fsh.ll

Index: llvm/test/Transforms/InstCombine/fsh.ll
===
--- llvm/test/Transforms/InstCombine/fsh.ll
+++ llvm/test/Transforms/InstCombine/fsh.ll
@@ -440,12 +440,10 @@
   ret <2 x i32> %r
 }
 
-; TODO: Don't let SimplifyDemandedBits split up a rotate - keep the same operand.
-
 define i32 @rotl_common_demanded(i32 %a0) {
 ; CHECK-LABEL: @rotl_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i32 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[A0]], i32 8)
+; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 8)
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %x = xor i32 %a0, 2
@@ -456,7 +454,7 @@
 define i33 @rotr_common_demanded(i33 %a0) {
 ; CHECK-LABEL: @rotr_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i33 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[A0]], i33 25)
+; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[X]], i33 25)
 ; CHECK-NEXT:ret i33 [[R]]
 ;
   %x = xor i33 %a0, 2
Index: llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: sed 's/iX/i32/g' %s | llc --mtriple=wasm32-unknown-unknown | FileCheck --check-prefix=I32 %s
+; RUN: sed 's/iX/i64/g' %s | llc --mtriple=wasm64-unknown-unknown | FileCheck --check-prefix=I64 %s
+
+declare iX @llvm.fshl.iX(iX, iX, iX)
+declare iX @llvm.fshr.iX(iX, iX, iX)
+
+; from https://github.com/llvm/llvm-project/issues/62703
+
+define iX @testLeft(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testLeft:
+; I32: .functype testLeft (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotl
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testLeft:
+; I64: .functype testLeft (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotl
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshl.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
+
+define iX @testRight(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testRight:
+; I32: .functype testRight (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotr
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testRight:
+; I64: .functype testRight (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotr
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshr.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===
--- llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -912,9 +912,24 @@
 
 APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
 APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
-if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
-SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
-  return I;
+if (I->getOperand(0) != I->getOperand(1)) {
+if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
+  SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1)) 
+return I;
+} else { // fshl is a rotate
+  KnownBits LHSKnown = computeKnownBits(I->getOperand(0), Depth + 1, I);
+  KnownBits RHSKnown = computeKnownBits(I->getOperand(1), Depth + 1, I);
+
+  // Although this is a rotate there are cases where we want to optimize
+  // it. If the demanded bits are known, then we proceed with the
+  // optimization.
+  if ((DemandedMaskLHS.isSubsetOf(LHSKnown.Zero | LHSKnown.One)
+  || DemandedMaskRHS.isSubsetOf(RHSKnown.Zero | RHSKnown.One)) &&
+  (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
+   SimplifyDemandedBits

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-05-30 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 526539.
pmatos added a comment.

Remove test portion attempting to test coroutines.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-table-ped.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI && WebAssembly::isWebAssemblyReferenceType(
+ PTI->getPointerOperand()->getType())) &&
+!(ITP && WebAssembly::isWebAssemblyReferenceType(ITP->getDestTy(
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1203,7 +1203,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  WebAssembly::isWebAssemblyFuncrefType(CLI.CB->getCalledOperand()->getType())) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -18,6 +18,7 @@
 #include "MCTargetDesc/WebAssemblyMCTypeUtilities.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/WasmAddressSpaces.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/MC/MCSymbolWasm.h"
 
@@ -27,41 +28,21 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
+/// Return true if this is a WebAssembly Externref Type.
+inline bool isWebAssemblyExternrefType(const Type *Ty) {
+  return Ty->getPointerAddressSpace() ==
+ WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
 }
-inline bool isFuncrefType(con

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-05-29 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 526436.
pmatos marked an inline comment as done.
pmatos added a comment.

Address the comments wrt the documentation. Added link to Wasm spec.

@aaron.ballman What do you think? I added the reference to the top level of the 
WebAssembly section, rather than to the documentation in each builtin since it 
makes more sense imo.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-table-ped.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI && WebAssembly::isWebAssemblyReferenceType(
+ PTI->getPointerOperand()->getType())) &&
+!(ITP && WebAssembly::isWebAssemblyReferenceType(ITP->getDestTy(
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1203,7 +1203,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  WebAssembly::isWebAssemblyFuncrefType(CLI.CB->getCalledOperand()->getType())) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -18,6 +18,7 @@
 #include "MCTargetDesc/WebAssemblyMCTypeUtilities.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/WasmAddressSpaces.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/MC/MCSymbolWasm.h"
 
@@ -27,41 +28,21 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
+/// Return true if

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-05-29 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 3 inline comments as done.
pmatos added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:2288
+argument is the index to which to store the value into, and the
+third argument is a value of reference type to store in the table.
+It returns nothing.

aaron.ballman wrote:
> pmatos wrote:
> > aaron.ballman wrote:
> > > This sounds like any reference type will work, e.g.,
> > > ```
> > > static __externref_t table[0];
> > > void func(int i) {
> > >   int &ref = i;
> > >   __builtin_wasm_table_set(table, i, ref);
> > > }
> > > ```
> > > so might want to say "value of ``_externref_t`` type" instead?
> > Any reference type will work, i.e. externref or funcref. You can also store 
> > funcrefs in a wasm table. But of course, it needs to be well-typed. You 
> > cannot store a funcref value in an externref table and vice-versa.
> My point is more that "any reference type" suggests you can use an arbitrary 
> C++ reference type like `int &` and I think we mean something more specific 
> than that, right?
Yes, of course, I always mean a WebAssembly reference type in this context.



Comment at: clang/docs/LanguageExtensions.rst:2364-2365
+range, the third argument is the value to set in the new entries, and 
+the fourth and the last argument is the size of the range. It returns 
+nothing.
+

aaron.ballman wrote:
> pmatos wrote:
> > aaron.ballman wrote:
> > > What happens if the range is invalid for the table size? e.g., the user 
> > > never called `__builtin_wasm_table_grow` before calling 
> > > `__builtin_wasm_table_fill`?
> > The host executing the WebAssembly instance will trap. This is part of the 
> > WebAssembly spec.
> Hmmm, do you think we should mention that here? Alternatively, should we have 
> a link to other WebAssembly documentation so we can say "see  for more 
> details?" to avoid replicating docs too much?
Good idea. I will handle that.



Comment at: clang/test/SemaCXX/wasm-refs-and-tables.cpp:35
+task<__externref_t[]> g() {
+  co_return table;
+}

aaron.ballman wrote:
> pmatos wrote:
> > aaron.ballman wrote:
> > > pmatos wrote:
> > > > @aaron.ballman I tried and failed to create a good testcase for 
> > > > co_return. However creating coroutines seems to be an stdlib thing 
> > > > which I am not sure how to test here. Do you have any suggestions here?
> > > ```
> > > #include "Inputs/std-coroutine.h"
> > > 
> > > using std::suspend_always;
> > > 
> > > struct promise_table {
> > >   __externref_t[] get_return_object();
> > >   suspend_always initial_suspend();
> > >   suspend_always final_suspend() noexcept;
> > >   void return_value(__externref_t[]);
> > >   void unhandled_exception();
> > > };
> > > 
> > > template 
> > > struct std::coroutine_traits<__externref_t[], T...> { using promise_type 
> > > = promise_table; };
> > > 
> > > static __externref_t table[0];
> > > __externref_t[] func() {
> > >   co_return table; // Cannot return a WebAssembly table?
> > > }
> > > ```
> > > Perhaps something along these lines?
> > But you cannot write promise_table because a table cannot be an argument in 
> > return_value. Also, you cannot return a table in get_return_object. Doesn't 
> > this invalidate straight away the use of a table with co-routines?
> Ah! Yeah, I think that does. Okay, let's punt on coroutines, that's turning 
> out to be a slog.
OK - thanks.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-29 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added inline comments.



Comment at: llvm/test/Transforms/InstCombine/fsh.ll:664
+; CHECK-NEXT:[[T1:%.*]] = and i32 [[A:%.*]], -65536
+; CHECK-NEXT:[[T2:%.*]] = call i32 @llvm.fshl.i32(i32 [[T1]], i32 [[T1]], 
i32 16)
 ; CHECK-NEXT:ret i32 [[T2]]

pmatos wrote:
> nikic wrote:
> > We still want to simplify this case. Could possibly be done by checking 
> > whether all demanded bits are zero for one of the operands in the rotate 
> > case.
> Ah, yes,  right. That should be just a simple shift right. Will see how to 
> still allow that change. Thanks.
I am still looking into the best way to handle this case. The issue is that we 
only know if the demanded bits are zero when analyzing the uses of the value. 
This is done in SimplifyDemandedBits which in turn calls 
SimplifyDemandedUseBits, but we cannot call these functions to obtain demanded 
bits because they'll change the instruction straightaway.  I was seeing if 
there was a way to do the checks inside the block of code already changed, but 
I don't think that'll be possible. I might have to add a check to 
SimplifyDemandedUseBits to only simplify in this specific case we want.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-26 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added inline comments.



Comment at: llvm/test/Transforms/InstCombine/fsh.ll:664
+; CHECK-NEXT:[[T1:%.*]] = and i32 [[A:%.*]], -65536
+; CHECK-NEXT:[[T2:%.*]] = call i32 @llvm.fshl.i32(i32 [[T1]], i32 [[T1]], 
i32 16)
 ; CHECK-NEXT:ret i32 [[T2]]

nikic wrote:
> We still want to simplify this case. Could possibly be done by checking 
> whether all demanded bits are zero for one of the operands in the rotate case.
Ah, yes,  right. That should be just a simple shift right. Will see how to 
still allow that change. Thanks.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-26 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 526044.
pmatos added a comment.

Update the patch by removing target specific changes in CGBuiltin. 
Leave fshl/fshr unchanged for rotates. This actually fixes a todo in fshl/r 
test.

@nikic What do you think of the current patch?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

Files:
  clang/test/CodeGen/WebAssembly/wasm-rotate.c
  llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
  llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
  llvm/test/Transforms/InstCombine/fsh.ll

Index: llvm/test/Transforms/InstCombine/fsh.ll
===
--- llvm/test/Transforms/InstCombine/fsh.ll
+++ llvm/test/Transforms/InstCombine/fsh.ll
@@ -440,12 +440,10 @@
   ret <2 x i32> %r
 }
 
-; TODO: Don't let SimplifyDemandedBits split up a rotate - keep the same operand.
-
 define i32 @rotl_common_demanded(i32 %a0) {
 ; CHECK-LABEL: @rotl_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i32 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[A0]], i32 8)
+; CHECK-NEXT:[[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 8)
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %x = xor i32 %a0, 2
@@ -456,7 +454,7 @@
 define i33 @rotr_common_demanded(i33 %a0) {
 ; CHECK-LABEL: @rotr_common_demanded(
 ; CHECK-NEXT:[[X:%.*]] = xor i33 [[A0:%.*]], 2
-; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[A0]], i33 25)
+; CHECK-NEXT:[[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[X]], i33 25)
 ; CHECK-NEXT:ret i33 [[R]]
 ;
   %x = xor i33 %a0, 2
@@ -662,7 +660,8 @@
 
 define i32 @fshl_mask_args_same1(i32 %a) {
 ; CHECK-LABEL: @fshl_mask_args_same1(
-; CHECK-NEXT:[[T2:%.*]] = lshr i32 [[A:%.*]], 16
+; CHECK-NEXT:[[T1:%.*]] = and i32 [[A:%.*]], -65536
+; CHECK-NEXT:[[T2:%.*]] = call i32 @llvm.fshl.i32(i32 [[T1]], i32 [[T1]], i32 16)
 ; CHECK-NEXT:ret i32 [[T2]]
 ;
   %t1 = and i32 %a, 4294901760 ; 0x
@@ -718,7 +717,7 @@
 define <2 x i32> @fshr_mask_args_same_vector2(<2 x i32> %a, <2 x i32> %b) {
 ; CHECK-LABEL: @fshr_mask_args_same_vector2(
 ; CHECK-NEXT:[[T1:%.*]] = and <2 x i32> [[A:%.*]], 
-; CHECK-NEXT:[[T3:%.*]] = lshr exact <2 x i32> [[T1]], 
+; CHECK-NEXT:[[T3:%.*]] = call <2 x i32> @llvm.fshl.v2i32(<2 x i32> [[T1]], <2 x i32> [[T1]], <2 x i32> )
 ; CHECK-NEXT:ret <2 x i32> [[T3]]
 ;
   %t1 = and <2 x i32> %a, 
Index: llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
@@ -0,0 +1,46 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: sed 's/iX/i32/g' %s | llc --mtriple=wasm32-unknown-unknown | FileCheck --check-prefix=I32 %s
+; RUN: sed 's/iX/i64/g' %s | llc --mtriple=wasm64-unknown-unknown | FileCheck --check-prefix=I64 %s
+
+declare iX @llvm.fshl.iX(iX, iX, iX)
+declare iX @llvm.fshr.iX(iX, iX, iX)
+
+define iX @testLeft(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testLeft:
+; I32: .functype testLeft (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotl
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testLeft:
+; I64: .functype testLeft (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotl
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshl.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
+
+define iX @testRight(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testRight:
+; I32: .functype testRight (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotr
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testRight:
+; I64: .functype testRight (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotr
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.fshr.iX(iX %0, iX %0, iX %1)
+  ret iX %3
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===
--- llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -924,11 +924,13 @@
 if (II->getIntrinsicID() == Intrinsic::fshr)
   ShiftAmt = BitWidth - ShiftAmt;
 
-APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
-APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
-if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
-SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
-  return I;
+if (I->getOperand(0) != I->getOperan

[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-24 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

In D150670#4368238 , @pmatos wrote:

> In D150670#4352163 , @nikic wrote:
>
>> 1. Say that we prefer preserving rotates over "simplifying" funnel shifts 
>> (ending up with the rot2 pattern). Basically by skipping the optimization at 
>> https://github.com/llvm/llvm-project/blob/7f54b38e28b3b66195de672848f2b5366d0d51e3/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp#L927-L931
>>  if both fsh operands are the same. Assuming this doesn't cause test 
>> regressions, I think this would be acceptable to do. From a backend 
>> perspective, even for targets that have a native funnel shift (aarch64, 
>> x86), the difference between the rot1/rot2 patterns looks pretty neutral.

OK, I just re-read your comment above and I am starting to assume that what you 
mean is skipping the optimization for all targets if the funnel shift is a 
rotate (i.e. same first two operands). Is this correct?

> I am surprised this option is viable for example. This was my initial thought 
> to avoid the rotate, but I assumed adding something like :
>
>   if (!getTarget().getTriple().isWasm()) {
> APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
> APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
> if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
> SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
>   return I;
>   }
>
> would not be well received. Also, I cannot find precedent for doing this.




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-24 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

In D150670#4352163 , @nikic wrote:

> 1. Say that we prefer preserving rotates over "simplifying" funnel shifts 
> (ending up with the rot2 pattern). Basically by skipping the optimization at 
> https://github.com/llvm/llvm-project/blob/7f54b38e28b3b66195de672848f2b5366d0d51e3/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp#L927-L931
>  if both fsh operands are the same. Assuming this doesn't cause test 
> regressions, I think this would be acceptable to do. From a backend 
> perspective, even for targets that have a native funnel shift (aarch64, x86), 
> the difference between the rot1/rot2 patterns looks pretty neutral.

I am surprised this option is viable for example. This was my initial thought 
to avoid the rotate, but I assumed adding something like :

  if (!getTarget().getTriple().isWasm()) {
APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1) ||
SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1))
  return I;
  }

would not be well received. Also, I cannot find precedent for doing this.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-24 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

In D150670#4352094 , @craig.topper 
wrote:

>> Preventing the simplification means adding target specific code in 
>> instcombine which seems even worse than adding it here given as @dschuff 
>> pointed out, there's precedent with x86.
>
> How harmful is it to avoid breaking rotate patterns even if the target 
> doesn't support rotate?

Hi Craig, I thought initially your question was for Nikita but it's apparently 
for me. I am sorry but I am not sure I understand your question. Could you 
please rephrase?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-05-23 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:2288
+argument is the index to which to store the value into, and the
+third argument is a value of reference type to store in the table.
+It returns nothing.

aaron.ballman wrote:
> This sounds like any reference type will work, e.g.,
> ```
> static __externref_t table[0];
> void func(int i) {
>   int &ref = i;
>   __builtin_wasm_table_set(table, i, ref);
> }
> ```
> so might want to say "value of ``_externref_t`` type" instead?
Any reference type will work, i.e. externref or funcref. You can also store 
funcrefs in a wasm table. But of course, it needs to be well-typed. You cannot 
store a funcref value in an externref table and vice-versa.



Comment at: clang/docs/LanguageExtensions.rst:2321
+This builtin function returns the size of the WebAssembly table.
+Takes as argument the table and returns an integer with the current
+table size.

aaron.ballman wrote:
> Returns an `int`? `size_t`? Something else?
Good point, should actually be size_t. Will change that and clarify in the 
documentation.



Comment at: clang/docs/LanguageExtensions.rst:2340
+It takes three arguments. The first argument is the WebAssembly table 
+to grow. The second argument is the reference typed value to store in 
+the new table entries (the initialization value), and the third argument

aaron.ballman wrote:
> Same suggestion here as above regarding arbitrary reference types.
Same situation as above. These builtins can get any reference type, as long as 
they match the table element type.



Comment at: clang/docs/LanguageExtensions.rst:2360-2361
+
+This builtin function sets all the entries of a WebAssembly table to a given 
+reference typed value. It takes four arguments. The first argument is 
+the WebAssembly table, the second argument is the index that starts the 

aaron.ballman wrote:
> Same suggestion here as above regarding arbitrary reference types.
Same as above.



Comment at: clang/docs/LanguageExtensions.rst:2364-2365
+range, the third argument is the value to set in the new entries, and 
+the fourth and the last argument is the size of the range. It returns 
+nothing.
+

aaron.ballman wrote:
> What happens if the range is invalid for the table size? e.g., the user never 
> called `__builtin_wasm_table_grow` before calling `__builtin_wasm_table_fill`?
The host executing the WebAssembly instance will trap. This is part of the 
WebAssembly spec.



Comment at: clang/docs/LanguageExtensions.rst:2385
+source index from there the copy starts, and the fifth and last argument
+is the number of elements to copy. It returns nothing.
+

aaron.ballman wrote:
> Similar question here as above -- what happens when the range given is 
> invalid for either one or both of the table arguments?
Trap on the host.



Comment at: clang/test/SemaCXX/wasm-refs-and-tables.cpp:35
+task<__externref_t[]> g() {
+  co_return table;
+}

aaron.ballman wrote:
> pmatos wrote:
> > @aaron.ballman I tried and failed to create a good testcase for co_return. 
> > However creating coroutines seems to be an stdlib thing which I am not sure 
> > how to test here. Do you have any suggestions here?
> ```
> #include "Inputs/std-coroutine.h"
> 
> using std::suspend_always;
> 
> struct promise_table {
>   __externref_t[] get_return_object();
>   suspend_always initial_suspend();
>   suspend_always final_suspend() noexcept;
>   void return_value(__externref_t[]);
>   void unhandled_exception();
> };
> 
> template 
> struct std::coroutine_traits<__externref_t[], T...> { using promise_type = 
> promise_table; };
> 
> static __externref_t table[0];
> __externref_t[] func() {
>   co_return table; // Cannot return a WebAssembly table?
> }
> ```
> Perhaps something along these lines?
But you cannot write promise_table because a table cannot be an argument in 
return_value. Also, you cannot return a table in get_return_object. Doesn't 
this invalidate straight away the use of a table with co-routines?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-05-23 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 524710.
pmatos marked 8 inline comments as done.
pmatos added a comment.

Address remaining comments.

Make table.size builtin return size_t. 
Still remaining to be address is co_return on tables.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-table-ped.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI && WebAssembly::isWebAssemblyReferenceType(
+ PTI->getPointerOperand()->getType())) &&
+!(ITP && WebAssembly::isWebAssemblyReferenceType(ITP->getDestTy(
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1203,7 +1203,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  WebAssembly::isWebAssemblyFuncrefType(CLI.CB->getCalledOperand()->getType())) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -18,6 +18,7 @@
 #include "MCTargetDesc/WebAssemblyMCTypeUtilities.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/WasmAddressSpaces.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/MC/MCSymbolWasm.h"
 
@@ -27,41 +28,21 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
+/// Return true if this is a WebAssembly Externref Type.
+inline bool isWebAssemblyExternrefType(const Type *Ty) {
+  return Ty->getPointerAddressSp

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-05-19 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

In D139010#4350869 , @tlively wrote:

> It looks like the LLVM-side changes are generally moving Wasm type 
> classification functions to a more global location. Since no other backend 
> should care about these things, it would be better if we could get away 
> without these changes.

@tlively Fortunately, this is not needed anymore. Thanks for pointing it out. 
At some point it was due to dependencies from Clang code which used the 
predicates from LLVM and we couldn't include the WebAssembly backend there so 
it was easier to have them in llvm Type.h. But that code was refactored and I 
could move the LLVM predicates back to the backend files. How does it look like 
now?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-05-19 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 523741.
pmatos added a comment.

Remove modifications from Type.h and move them to WebAssembly files.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-table-ped.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI && WebAssembly::isWebAssemblyReferenceType(
+ PTI->getPointerOperand()->getType())) &&
+!(ITP && WebAssembly::isWebAssemblyReferenceType(ITP->getDestTy(
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1203,7 +1203,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  WebAssembly::isWebAssemblyFuncrefType(CLI.CB->getCalledOperand()->getType())) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -18,6 +18,7 @@
 #include "MCTargetDesc/WebAssemblyMCTypeUtilities.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/WasmAddressSpaces.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/MC/MCSymbolWasm.h"
 
@@ -27,41 +28,21 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
+/// Return true if this is a WebAssembly Externref Type.
+inline bool isWebAssemblyExternrefType(const Type *Ty) {
+  return Ty->getPointerAddressSpace() ==
+ WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
 }
-inline bool

[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-19 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

@nikic Thank you for the thorough suggestions above. I will have to look at 
this closer next week and will work on an alternative solution.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-18 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

In D150670#4351147 , @nikic wrote:

> Lowering to a rotate intrinsic only "solves" this for wasm and will at the 
> same time make these rotates completely opaque to optimization -- heck, it 
> looks like we don't even support constant folding for these intrinsics 
> (https://llvm.godbolt.org/z/hMWG16b9W).

Another thing wrt this optimization regard is that Wasm is slightly different 
from other targets in that it's not natively executed but instead executed 
through a VM or passed through binaryen for further optimization. I just tested 
this and emcc which passes the resulting file through binaryen performs this 
optimization. I imagine V8 won't have problems with this code either, therefore 
the missing optimization in llvm is not problematic for the target.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-17 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

In D150670#4351147 , @nikic wrote:

> This doesn't looks like a wasm specific problem. You get essentially the same 
> issue on any target that has a rotate instruction but no funnel shift 
> instruction. Here are just a couple examples: https://godbolt.org/z/8v6nfaax9

Yes, I am indeed aware this is not specific to wasm. What's specific to wasm 
afaiu is that the code generated is much worse when expanding fshl. That's what 
I mentioned in the bug discussion here: 
https://github.com/llvm/llvm-project/issues/62703#issuecomment-1548474310

> I believe this needs to be either solved by preventing demanded bits 
> simplifications that break a rotate pattern (though I'm not sure if that 
> would break any other optimizations we care about) or by adding a special 
> case for this in the backend when lowering FSH to ROT.

Preventing the simplification means adding target specific code in instcombine 
which seems even worse than adding it here given as @dschuff 
pointed out, there's precedent with x86.

> Lowering to a rotate intrinsic only "solves" this for wasm and will at the 
> same time make these rotates completely opaque to optimization -- heck, it 
> looks like we don't even support constant folding for these intrinsics 
> (https://llvm.godbolt.org/z/hMWG16b9W).

I just added the intrinsics, so those optimizations were not added yet.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-17 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

Ready for review.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-17 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 523149.
pmatos added a comment.

Generate rotates for 64bits as well. Add tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/WebAssembly/wasm-rotate.c
  llvm/include/llvm/IR/IntrinsicsWebAssembly.td
  llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
  llvm/test/CodeGen/WebAssembly/rotate-i3264.ll

Index: llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/rotate-i3264.ll
@@ -0,0 +1,46 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: sed 's/iX/i32/g' %s | llc --mtriple=wasm32-unknown-unknown | FileCheck --check-prefix=I32 %s
+; RUN: sed 's/iX/i64/g' %s | llc --mtriple=wasm64-unknown-unknown | FileCheck --check-prefix=I64 %s
+
+declare iX @llvm.wasm.rotl.iX(iX, iX) nounwind
+declare iX @llvm.wasm.rotr.iX(iX, iX) nounwind
+
+define iX @testLeft(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testLeft:
+; I32: .functype testLeft (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotl
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testLeft:
+; I64: .functype testLeft (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotl
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.wasm.rotl.iX(iX %0, iX %1)
+  ret iX %3
+}
+
+define iX @testRight(iX noundef %0, iX noundef %1) {
+; I32-LABEL: testRight:
+; I32: .functype testRight (i32, i32) -> (i32)
+; I32-NEXT:  # %bb.0:
+; I32-NEXT:local.get 0
+; I32-NEXT:local.get 1
+; I32-NEXT:i32.rotr
+; I32-NEXT:# fallthrough-return
+;
+; I64-LABEL: testRight:
+; I64: .functype testRight (i64, i64) -> (i64)
+; I64-NEXT:  # %bb.0:
+; I64-NEXT:local.get 0
+; I64-NEXT:local.get 1
+; I64-NEXT:i64.rotr
+; I64-NEXT:# fallthrough-return
+  %3 = call iX @llvm.wasm.rotr.iX(iX %0, iX %1)
+  ret iX %3
+}
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
===
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
@@ -107,6 +107,16 @@
 def : Pat<(rotl I64:$lhs, (and I64:$rhs, 63)), (ROTL_I64 I64:$lhs, I64:$rhs)>;
 def : Pat<(rotr I64:$lhs, (and I64:$rhs, 63)), (ROTR_I64 I64:$lhs, I64:$rhs)>;
 
+// Lower the rotate intrinsic to a rotate instruction
+def : Pat<(int_wasm_rotl_i32 I32:$lhs, I32:$rhs),
+  (ROTL_I32 I32:$lhs, I32:$rhs)>;
+def : Pat<(int_wasm_rotr_i32 I32:$lhs, I32:$rhs),
+  (ROTR_I32 I32:$lhs, I32:$rhs)>;
+def : Pat<(int_wasm_rotl_i64 I64:$lhs, I64:$rhs),
+  (ROTL_I64 I64:$lhs, I64:$rhs)>;
+def : Pat<(int_wasm_rotr_i64 I64:$lhs, I64:$rhs),
+  (ROTR_I64 I64:$lhs, I64:$rhs)>;
+
 defm SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond),
 (outs), (ins),
 [(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))],
Index: llvm/include/llvm/IR/IntrinsicsWebAssembly.td
===
--- llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -341,4 +341,22 @@
 [],
 [IntrReadMem]>;
 
+//===--===//
+// Rotate Intrinsics
+// These are lowered from the target independent intrinsics to avoid
+// funnel shift optimizations
+//===--===//
+
+def int_wasm_rotl_i32 : 
+  DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_wasm_rotr_i32 : 
+  DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_wasm_rotl_i64 : 
+  DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+
+def int_wasm_rotr_i64 : 
+  DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+
 } // TargetPrefix = "wasm"
Index: clang/test/CodeGen/WebAssembly/wasm-rotate.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-rotate.c
@@ -0,0 +1,53 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -o - -emit-llvm %s | FileCheck --check-prefix=WEBASSEMBLY32 %s
+// RUN: %clang_cc1 -triple wasm64-unknown-unknown -o - -emit-llvm %s | FileCheck --check-prefix=WEBASSEMBLY64 %s
+
+// WEBASSEMBLY32-LABEL: define i32 @test32
+// WEBASSEMBLY32-SAME: (i32 noundef [[X:%.*]]) #[[ATTR

[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-17 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

In D150670#4347150 , @dschuff wrote:

> FWIW X86 seems to do something similar elsewhere in this file 
> (https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGBuiltin.cpp#L985-L986),
>  although it doesn't seem common otherwise. I think I'd be OK with this 
> approach (and it does seem better than trying to mess with instcombine or a 
> new TTI hook or something)

Oh - I missed that X86 bit. That gives me some confidence that this approach 
makes sense. I will work on a new patch with 64bit support and tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-16 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a reviewer: spatel.
pmatos added a comment.
Herald added a subscriber: StephenFan.

Adding Sanjay as a reviewer since he implemented the clang emitRotate which we 
patched.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-16 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

Proposal to fix https://github.com/llvm/llvm-project/issues/62703

This not ready to land yet but it should open a discussion on if this is a good 
fix for this issue.
If we want to go this route we need: support for 64bits, tests.

A quick summary of why this is needed. The function :

  inline u32 bswap(u32 x) {
  return __builtin_rotateleft32((x & 0xFF00FF00), 8) 
  | __builtin_rotateright32((x & 0x00FF00FF), 8);
}

generates really poor code in WebAssembly. A rotate should be generated but 
instead we get quite a large amount of code just to set up constants and 
perform a shift. The issue is that the rotateleft is lowered to a fshl(%and, 
%and, 8). During instcombine, the second argument is simplified since %and is 
the result of a bitwise operation. However, this results in the wasm backend 
not being able to generate the rotate since the first and second arguments to 
the fshl are not any longer the same. The generated code is:

  bswap:  # @bswap
.functype   bswap (i32) -> (i32)
  # %bb.0:# %entry
local.get   0
i32.const   24
i32.shl
local.get   0
i32.const   65280
i32.and
i32.const   8
i32.shl
i32.or
local.get   0
i32.const   8
i32.shr_u
i32.const   65280
i32.and
local.get   0
i32.const   24
i32.shr_u
i32.or
i32.or
  # fallthrough-return
end_function

With the fix this becomes:

  bswap:  # @bswap
.functype   bswap (i32) -> (i32)
  # %bb.0:# %entry
local.get   0
i32.const   16711935
i32.and
i32.const   8
i32.rotr
local.get   0
i32.const   -16711936
i32.and
i32.const   8
i32.rotl
i32.or
  # fallthrough-return
end_function

The alternative way to implement something like this would be to block the 
instcombine on fshl/fshr instructions for the wasm backend, however adding 
target dependent stuff to instcombine feels even more icky than this patch. I 
welcome suggestions on how to improve the patch, since the hack in `emitRotate` 
is also not great, and I have not seen other places lowering a generic builtin 
into a target specific intrinsic.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150670/new/

https://reviews.llvm.org/D150670

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D150670: [WebAssembly] Disable generation of fshl/fshr for rotates

2023-05-16 Thread Paulo Matos via Phabricator via cfe-commits
pmatos created this revision.
pmatos added reviewers: dschuff, tlively.
Herald added subscribers: asb, wingo, ecnelises, sunfish, hiraditya, 
jgravelle-google, sbc100.
Herald added a project: All.
pmatos requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, aheejin.
Herald added projects: clang, LLVM.

This commits overrides the default lowering of rotates to fshl/fshr.
It lowers the rotate straight to a target dependent rotate intrinsic.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150670

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  llvm/include/llvm/IR/IntrinsicsWebAssembly.td
  llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td


Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
===
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
@@ -107,6 +107,12 @@
 def : Pat<(rotl I64:$lhs, (and I64:$rhs, 63)), (ROTL_I64 I64:$lhs, I64:$rhs)>;
 def : Pat<(rotr I64:$lhs, (and I64:$rhs, 63)), (ROTR_I64 I64:$lhs, I64:$rhs)>;
 
+// Lower the rotate intrinsic to a rotate instruction
+def : Pat<(int_wasm_rotl_i32 I32:$lhs, I32:$rhs),
+  (ROTL_I32 I32:$lhs, I32:$rhs)>;
+def : Pat<(int_wasm_rotr_i32 I32:$lhs, I32:$rhs),
+  (ROTR_I32 I32:$lhs, I32:$rhs)>;
+
 defm SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond),
 (outs), (ins),
 [(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))],
Index: llvm/include/llvm/IR/IntrinsicsWebAssembly.td
===
--- llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -341,4 +341,16 @@
 [],
 [IntrReadMem]>;
 
+//===--===//
+// Rotate Intrinsics
+// These are lowered from the target independent intrinsics to avoid
+// funnel shift optimizations
+//===--===//
+
+def int_wasm_rotl_i32 : 
+  DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], 
[IntrNoMem]>;
+
+def int_wasm_rotr_i32 : 
+  DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], 
[IntrNoMem]>;
+
 } // TargetPrefix = "wasm"
Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -2120,6 +2120,15 @@
   llvm::Type *Ty = Src->getType();
   ShiftAmt = Builder.CreateIntCast(ShiftAmt, Ty, false);
 
+  // For WebAssembly we want to generate the target-specific rotate builtin, 
+  // rather than generating fshl/fshr intrinsics.
+  if (getTarget().getTriple().isWasm()) {
+unsigned IID = IsRotateRight ? Intrinsic::wasm_rotr_i32
+ : Intrinsic::wasm_rotl_i32;
+llvm::Function *F = CGM.getIntrinsic(IID);
+return RValue::get(Builder.CreateCall(F, { Src, ShiftAmt }));
+  }
+
   // Rotate is a special case of LLVM funnel shift - 1st 2 args are the same.
   unsigned IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl;
   Function *F = CGM.getIntrinsic(IID, Ty);


Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
===
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
@@ -107,6 +107,12 @@
 def : Pat<(rotl I64:$lhs, (and I64:$rhs, 63)), (ROTL_I64 I64:$lhs, I64:$rhs)>;
 def : Pat<(rotr I64:$lhs, (and I64:$rhs, 63)), (ROTR_I64 I64:$lhs, I64:$rhs)>;
 
+// Lower the rotate intrinsic to a rotate instruction
+def : Pat<(int_wasm_rotl_i32 I32:$lhs, I32:$rhs),
+  (ROTL_I32 I32:$lhs, I32:$rhs)>;
+def : Pat<(int_wasm_rotr_i32 I32:$lhs, I32:$rhs),
+  (ROTR_I32 I32:$lhs, I32:$rhs)>;
+
 defm SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond),
 (outs), (ins),
 [(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))],
Index: llvm/include/llvm/IR/IntrinsicsWebAssembly.td
===
--- llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -341,4 +341,16 @@
 [],
 [IntrReadMem]>;
 
+//===--===//
+// Rotate Intrinsics
+// These are lowered from the target independent intrinsics to avoid
+// funnel shift optimizations
+//===--===//
+
+def int_wasm_rotl_i32 : 
+  DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_wasm_rotr_i32 : 
+  DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-05-15 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked an inline comment as done.
pmatos added a comment.

@tlively @aaron.ballman pinging both to get final reviews on the LLVM and Clang 
parts respectively. It would be great to have this merged soon.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-27 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked an inline comment as done.
pmatos added a comment.

I think we are almost there. @aaron.ballman what do you think?




Comment at: clang/test/Sema/wasm-refs-and-tables.c:81
+
+  funcref_t func = __builtin_wasm_ref_null_func(0); // expected-error {{too 
many arguments to function call, expected 0, have 1}}
+

aaron.ballman wrote:
> Shouldn't this be in builtins-wasm.c instead?
Moved.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-27 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 517535.
pmatos added a comment.

Add documentation for table builtins.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-table-ped.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1203,7 +1203,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -27,43 +27,6 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(const Type *Ty) {
-  return isFuncrefType(Ty) || isExternrefType(Ty);
-}
-
 // Convert StringRef to ValType / HealType / BlockType
 
 MVT parseMVT(StringRef Type);
Index: llvm/lib/Target/We

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-27 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added inline comments.



Comment at: clang/test/SemaCXX/wasm-refs-and-tables.cpp:35
+task<__externref_t[]> g() {
+  co_return table;
+}

@aaron.ballman I tried and failed to create a good testcase for co_return. 
However creating coroutines seems to be an stdlib thing which I am not sure how 
to test here. Do you have any suggestions here?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-27 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 517525.
pmatos marked an inline comment as done.
pmatos added a comment.

Quick fixup of test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-table-ped.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1203,7 +1203,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -27,43 +27,6 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(const Type *Ty) {
-  return isFuncrefType(Ty) || isExternrefType(Ty);
-}
-
 // Convert StringRef to ValType / HealType / BlockType
 
 MVT parseMVT(StringRef Type);
I

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-27 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked an inline comment as done.
pmatos added inline comments.



Comment at: clang/test/Sema/wasm-refs-and-tables.c:17
+static __externref_t t6[] = {0}; // expected-error {{only zero-length 
WebAssembly tables are currently supported}}
+__externref_t t7[0]; // expected-error {{WebAssembly table must be 
static}}
+static __externref_t t8[0][0];   // expected-error {{multi-dimensional arrays 
of WebAssembly references are not allowed}}

aaron.ballman wrote:
> pmatos wrote:
> > aaron.ballman wrote:
> > > So why is `extern __externref_t r2;` allowed? Is it because it's not an 
> > > array declaration?
> > I am not sure I understand the question. The externref value can be 
> > declared in another module and here we just define that. Array declarations 
> > of externref just define tables of externref values.
> Thanks, that helps explain my confusion (boy, I *really* do not like these 
> types; they are quite unintuitive). What was confusing me here is that 
> `__externref_t t7[0];` fails because the declaration doesn't declare a static 
> identifier (yet, in C, it doesn't declare *anything at all* because it an 
> array of zero elements of a sizeless type) while `extern __externref_t r2;` 
> is fine despite not declaring a static identifier (yet, in C, it also doesn't 
> declare *anything at all* because it's a sizeless type). I don't think 
> there's anything to be done about this, the design is what it is in the 
> WebAssembly standard, but all of my discomfort stems around how deeply weird 
> this design is (and it shows with just how much effort we have to go to in 
> order to restrict all the various ways you can use these identifiers).
Yes, I understand. 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-27 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 517521.
pmatos marked 2 inline comments as done.
pmatos added a comment.

Update a few more tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-table-ped.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1203,7 +1203,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -27,43 +27,6 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(const Type *Ty) {
-  return isFuncrefType(Ty) || isExternrefType(Ty);
-}
-
 // Convert StringRef to ValType / HealType / BlockType
 
 MVT parseMVT(StringRef Type

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-27 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 2 inline comments as done.
pmatos added inline comments.



Comment at: clang/include/clang/Basic/BuiltinsWebAssembly.def:205-210
+TARGET_BUILTIN(__builtin_wasm_table_set,  "viii", "t", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_table_get,  "iii", "t", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_table_size, "ii", "nt", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_table_grow, "", "nt", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_table_fill, "v", "t", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_table_copy, "vi", "t", "reference-types")

aaron.ballman wrote:
> All of these should be documented in `docs/LanguageExtensions.rst` (you can 
> make a Web Assembly section if one doesn't already exist; we've historically 
> been bad about documenting our builtins).
Working on this - thanks for the reminder.



Comment at: clang/test/SemaCXX/wasm-refs-and-tables.cpp:6-7
+
+// Using c++11 to test dynamic exception specifications (which are not 
+// allowed in c++17).
+

aaron.ballman wrote:
> Much of this file is the same test coverage as in the C case; I'd recommend 
> combining the .c and .cpp files into one test with two RUN lines, and use 
> `-verify=whatever` to distinguish between C vs C++ vs both diagnostic 
> behaviors. The C++ specific code can then be split into a much smaller 
> .cpp-specific file.
I have don't this know. I was not aware we could pass an argument to verify - 
thanks.



Comment at: clang/test/SemaCXX/wasm-refs-and-tables.cpp:14
+
+__externref_t *t1;   // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
+__externref_t **t2;  // expected-error {{pointer to WebAssembly 
reference type is not allowed}}

aaron.ballman wrote:
> Anywhere you'd testing pointer behavior for C++, you should have a test with 
> an lvalue reference as well. I presume those will behave the same as 
> pointers? It'd probably be wise to have tests for rvalue references as well.
Here I guess you're talking about testing __externref_t &. However, this might 
be outside the scope of the patch which deals only with tables.

I could add further lvalue and rvalue reference tests to externref and funcref 
in another patch. What do you think?



Comment at: clang/test/SemaCXX/wasm-refs-and-tables.cpp:16-17
+__externref_t **t2;  // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
+__externref_t **t3;  // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
+static __externref_t t4[3];  // expected-error {{only zero-length 
WebAssembly tables are currently supported}}
+static __externref_t t5[];   // expected-error {{only zero-length 
WebAssembly tables are currently supported}}

aaron.ballman wrote:
> pmatos wrote:
> > aaron.ballman wrote:
> > > This seems really... confused. We can't form a pointer to the type, but 
> > > we can form an array of the type (which decays into a pointer when you 
> > > sneeze near it, and it's not clear whether that should be allowed or not) 
> > > so long as it's a zero-length array (which is an extension in C and C++, 
> > > so do we need to silence pedantic warnings in WASM for this?).
> > As it stands, tables are declared as static arrays of size zero. Then to 
> > access them we need to use builtins. No subscripting, no comparison, no 
> > pointer decay, etc. No passing into functions, returning from functions, 
> > etc. Nothing besides using them as arguments to wasm_table... builtins.
> Okay, that's less confused now, thank you! What should the `-pedantic` 
> behavior be for this:
> ```
> static __externref_t table[0];
> ```
> I presume you don't want the usual "zero size arrays are an extension" 
> warning?
I have fixed this but unsure how to best merge it with the remainder of the 
tests, so created a new test file.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-27 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 517478.
pmatos marked 6 inline comments as done.
pmatos added a comment.

Complete fixing tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1203,7 +1203,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -27,43 +27,6 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(const Type *Ty) {
-  return isFuncrefType(Ty) || isExternrefType(Ty);
-}
-
 // Convert StringRef to ValType / HealType / BlockType
 
 MVT parseMVT(StringRef Type);
Index: llvm/lib/Target/WebAssembly/Utils/We

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-26 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

Thanks for the comments - I am working on addressing these at the moment.
The LLVM part of the patch is just some refactoring and therefore should be 
pretty trivial, pinging @tlively in case he has some time.




Comment at: clang/test/Sema/wasm-refs-and-tables.c:17
+static __externref_t t6[] = {0}; // expected-error {{only zero-length 
WebAssembly tables are currently supported}}
+__externref_t t7[0]; // expected-error {{WebAssembly table must be 
static}}
+static __externref_t t8[0][0];   // expected-error {{multi-dimensional arrays 
of WebAssembly references are not allowed}}

aaron.ballman wrote:
> So why is `extern __externref_t r2;` allowed? Is it because it's not an array 
> declaration?
I am not sure I understand the question. The externref value can be declared in 
another module and here we just define that. Array declarations of externref 
just define tables of externref values.



Comment at: clang/test/Sema/wasm-refs-and-tables.c:48
+void illegal_argument_4(__externref_t ***table);// expected-error 
{{pointer to WebAssembly reference type is not allowed}}
+void illegal_argument_5(__externref_t (*table)[0]); // expected-error {{cannot 
form a pointer to a WebAssembly table}}
+

aaron.ballman wrote:
> How about:
> ```
> void foo(__externref_t table[0]);
> ```
> I'd expect this to also not be allowed (that's just a fancy spelling for a 
> weird pointer).
That's correct, that's not allowed. Added the test case.



Comment at: clang/test/Sema/wasm-refs-and-tables.c:104
+  table[0] = ref; // expected-error {{cannot subscript a 
WebAssembly table}}
+
+  return ref;

aaron.ballman wrote:
> Please don't hate me, but... what about:
> ```
> int i = 0;
> __externref_t oh_no_vlas[i];
> ```
> 
:) Test added.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-26 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 517166.
pmatos marked 3 inline comments as done.
pmatos added a comment.

Fix Wasm table tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1203,7 +1203,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -27,43 +27,6 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(const Type *Ty) {
-  return isFuncrefType(Ty) || isExternrefType(Ty);
-}
-
 // Convert StringRef to ValType / HealType / BlockType
 
 MVT parseMVT(StringRef Type);
Index: llvm/lib/Target/WebAssembly/Utils/Web

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-04-21 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked an inline comment as done.
pmatos added inline comments.



Comment at: clang/test/Sema/builtins-wasm.c:12-13
+  __builtin_wasm_table_size(table, table);// expected-error {{too 
many arguments to function call, expected 1, have 2}}
+  void *a = __builtin_wasm_table_size(table); // expected-error 
{{incompatible integer to pointer conversion initializing 'void *' with an 
expression of type 'int'}}
+  __externref_t b = __builtin_wasm_table_size(table); // expected-error 
{{initializing '__externref_t' with an expression of incompatible type 'int'}}
+  int c = __builtin_wasm_table_size(table);

aaron.ballman wrote:
> Instead of relying on assignment diagnostics to test the return type of the 
> call, why not use the language? (Same can be used for the other, similar 
> tests.)
> ```
> #define EXPR_HAS_TYPE(expr, type) _Generic((expr), type : 1, default : 0)
> 
> _Static_assert(EXPR_HAS_TYPE(__builtin_wasm_table_size(table), int), "");
> ```
OK - I will apply those changes. I hadn't seen this way of doing this before. 
Thanks.



Comment at: clang/test/Sema/builtins-wasm.c:21
+  __builtin_wasm_table_grow(ref, ref, size); // expected-error 
{{1st argument must be a WebAssembly table}}
+  __builtin_wasm_table_grow(table, table, size); // expected-error 
{{2nd argument must match the element type of the WebAssembly table in the 1st 
argument}}
+  __builtin_wasm_table_grow(table, ref, table);  // expected-error 
{{3rd argument must be an integer}}

aaron.ballman wrote:
> I can't make sense of this diagnostic -- what is the element type of the web 
> assembly table in the 1st argument? Why is the second argument needed at all 
> if it needs to be derived from the type of the first argument and these 
> things don't represent values (due to being zero-sized)?
The element type needs to be a reference type. Either an externref or a 
funcref. So, if we have a table of externref, the second element needs to have 
that type because it's the element we are growing the table with. The element 
is needed because it's what we'll use to fill the table with.

Well... they do represent values, just not values that exist on webassembly 
module. They are host values. They are for example javascript strings, or 
numbers, or objects of any kind. They are just opaque in the webassembly module 
but if retrieved by the javascript side they are just normal sized objects.



Comment at: clang/test/Sema/builtins-wasm.c:32
+  __builtin_wasm_table_fill(table, table, ref, nelem);   // 
expected-error {{2nd argument must be an integer}}
+  __builtin_wasm_table_fill(table, index, index, ref);   // 
expected-error {{3rd argument must match the element type of the WebAssembly 
table in the 1st argument}}
+  __builtin_wasm_table_fill(table, index, ref, table);   // 
expected-error {{4th argument must be an integer}}

aaron.ballman wrote:
> Similar question here about the third argument.
Exactly the same story as above.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-03-28 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

@aaron.ballman Any further comments on this?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-03-20 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added inline comments.



Comment at: clang/test/SemaCXX/wasm-refs-and-tables.cpp:16-17
+__externref_t **t2;  // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
+__externref_t **t3;  // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
+static __externref_t t4[3];  // expected-error {{only zero-length 
WebAssembly tables are currently supported}}
+static __externref_t t5[];   // expected-error {{only zero-length 
WebAssembly tables are currently supported}}

aaron.ballman wrote:
> This seems really... confused. We can't form a pointer to the type, but we 
> can form an array of the type (which decays into a pointer when you sneeze 
> near it, and it's not clear whether that should be allowed or not) so long as 
> it's a zero-length array (which is an extension in C and C++, so do we need 
> to silence pedantic warnings in WASM for this?).
As it stands, tables are declared as static arrays of size zero. Then to access 
them we need to use builtins. No subscripting, no comparison, no pointer decay, 
etc. No passing into functions, returning from functions, etc. Nothing besides 
using them as arguments to wasm_table... builtins.



Comment at: clang/test/SemaCXX/wasm-refs-and-tables.cpp:88
+  varargs(1, table);  // expected-error {{cannot use WebAssembly 
table as a function parameter}}
+  table == 1; // expected-error {{invalid operands to 
binary expression ('__attribute__((address_space(1))) __externref_t[0]' and 
'int')}}
+  1 >= table; // expected-error {{invalid operands to 
binary expression ('int' and '__attribute__((address_space(1))) 
__externref_t[0]')}}

aaron.ballman wrote:
> 
No comparisons are allowed - I have added a few tests to that effect.



Comment at: clang/test/SemaCXX/wasm-refs-and-tables.cpp:95
+  table ? : other_table;  // expected-error {{cannot use a WebAssembly 
table within a branch of a conditional expression}}
+  (void *)table;  // expected-error {{cannot cast from a 
WebAssembly table}}
+  void *u;

aaron.ballman wrote:
> 
(void)table; is allowed.



Comment at: clang/test/SemaCXX/wasm-refs-and-tables.cpp:102
+
+  table[0];
+  table[0] = ref;

aaron.ballman wrote:
> This involves array to pointer decay, so we're forming a pointer to the table 
> here. Why is this pointer fine but others are not?
I have disallowed this to avoid the problems you mention. Table set happens 
only through the builtin wasm_table_set.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-03-20 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 506552.
pmatos marked 4 inline comments as done.
pmatos added a comment.

Address concerns about table subscripting. Add warnings for that.

Address a few other smaller comments like testing for table comparisons.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -27,43 +27,6 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(const Type *Ty) {
-  return isFuncrefType(Ty) || isExternrefType(Ty);
-}
-
 // Convert String

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-03-20 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 506521.
pmatos added a comment.

Remove references to table subscript. Simplify patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -27,43 +27,6 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(const Type *Ty) {
-  return isFuncrefType(Ty) || isExternrefType(Ty);
-}
-
 // Convert StringRef to ValType / HealType / BlockType
 
 MVT parseMVT(StringRef Type);
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
===

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-03-20 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 506499.
pmatos added a comment.

Rebase on main.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -27,43 +27,6 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(const Type *Ty) {
-  return isFuncrefType(Ty) || isExternrefType(Ty);
-}
-
 // Convert StringRef to ValType / HealType / BlockType
 
 MVT parseMVT(StringRef Type);
Index: llvm/lib/Target/

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-03-17 Thread Paulo Matos via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG8d0c88975212: [clang][WebAssembly] Initial support for 
reference type funcref in clang (authored by pmatos).

Changed prior to commit:
  https://reviews.llvm.org/D128440?vs=501081&id=506134#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-funcref.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/SemaCXX/wasm-funcref.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/wasm-funcref.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fsyntax-only -verify -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
+
+// Testing that funcrefs work on template aliases
+// expected-no-diagnostics
+
+using IntIntFuncref = int(*)(int) __funcref;
+using DoubleQual = IntIntFuncref __funcref;
+
+int get(int);
+
+IntIntFuncref getFuncref() {
+return get;
+}
Index: clang/test/Sema/wasm-refs.c
===
--- clang/test/Sema/wasm-refs.c
+++ clang/test/Sema/wasm-refs.c
@@ -46,6 +46,8 @@
 __externref_t ***illegal_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
 
 void varargs(int, ...);
+typedef void (*__funcref funcref_t)();
+typedef void (*__funcref __funcref funcref_fail_t)(); // expected-warning {{attribute '__funcref' is already applied}}
 
 __externref_t func(__externref_t ref) {
   &ref; // expected-error {{cannot take address of WebAssembly reference}}
@@ -67,5 +69,7 @@
   _Alignof(__externref_t ***);   // expected-error {{pointer to WebAssembly reference type is not allowed}};
   varargs(1, ref);   // expected-error {{cannot pass expression of type '__externref_t' to variadic function}}
 
+  funcref_t func = __builtin_wasm_ref_null_func(0); // expected-error {{too many arguments to function call, expected 0, have 1}}
+
   return ref;
 }
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of '__funcref' keyword outside the W

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-03-17 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 3 inline comments as done.
pmatos added a comment.

Thanks all for the comments, fixed and will soon land after running a check-all.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-03-08 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

@erichkeane @aaron.ballman any further comments on this?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-02-28 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 501143.
pmatos marked an inline comment as done.
pmatos added a comment.

Address comments regarding tables and remove some unused code.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -27,43 +27,6 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(const Type *Ty) {
-  return isFuncrefType(Ty) || isExternrefType(Ty);
-}
-
 // Convert StringRef to

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-02-28 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 3 inline comments as done.
pmatos added inline comments.



Comment at: clang/include/clang/AST/Stmt.h:456
 
-  class ArrayOrMatrixSubscriptExprBitfields {
+  class AMTSubscriptExprBitfields {
 friend class ArraySubscriptExpr;

aaron.ballman wrote:
> I am not certain what `AMT` stands for -- you might need some comments to 
> explain what this stands for.
Ah yes,  somehow I missed this. I renamed this at some point with an 
application in mind and then didn't use it. So renamed back.

AMT was supposed to be Array / Matrix / Table.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:11827
+def err_wasm_builtin_arg_must_be_integer_type : Error <
+  "%ordinal0 argument must be an integer">;
 } // end of sema component.

aaron.ballman wrote:
> pmatos wrote:
> > asb wrote:
> > > aaron.ballman wrote:
> > > > I'm a bit shocked by the number of new diagnostics for this type as it 
> > > > seems incredibly restrictive and like the rules are going to be hard to 
> > > > understand. For example, you cannot use this type in an exception 
> > > > specification despite that being a compile-time property. Can you use 
> > > > it within a conditional explicit clause 
> > > > (https://godbolt.org/z/sn3G8xE3T)? It must be static, but can it be 
> > > > thread local?
> > > > 
> > > > Basically, it seems like this type is unlike basically any other type 
> > > > and we're going to have to carry a significant amount of extra code 
> > > > around to handle all the edge cases and those edge cases look a bit 
> > > > like whack-a-mole in practice.
> > > The whack-a-mole aspect of disallowing table uses is something I'm not 
> > > fond of eitherbut I'm not sure I see a better approach. Do you have 
> > > any alternatives in mind?
> > A couple concrete answers in addition to what @asb already said.
> > 
> > * I don't think we can use tables at the moment in conditional explicit 
> > clause. Indeed it doesn't make sense since there's no what, at the moment, 
> > to statically initialize the table.
> > * Tables are thread local. Indeed, threads in WebAssembly share only linear 
> > memory so anything that's not in linear memory is thread local. This is 
> > true for tables but also for all reference types.
> > The whack-a-mole aspect of disallowing table uses is something I'm not fond 
> > of eitherbut I'm not sure I see a better approach. Do you have any 
> > alternatives in mind?
> 
> I don't have good ideas off the top of my head, but this is a lot of overhead 
> for the feature so my default idea is "don't add this type to the compiler" 
> which may not help all that much. Do you have evidence that this type is 
> necessary, will have enough uses in the wild to justify adding it, and is not 
> possible to make it more regular?
> > The whack-a-mole aspect of disallowing table uses is something I'm not fond 
> > of eitherbut I'm not sure I see a better approach. Do you have any 
> > alternatives in mind?
> 
> I don't have good ideas off the top of my head, but this is a lot of overhead 
> for the feature so my default idea is "don't add this type to the compiler" 
> which may not help all that much. Do you have evidence that this type is 
> necessary, will have enough uses in the wild to justify adding it, and is not 
> possible to make it more regular?

A table is a container for reference types - i.e. externref, funcref and others 
in the future and an essential part of WebAssembly. I don't see how we can 
compile down to tables unless we enforce these constraints at this level. I 
wish there was a way of providing the same functionality without needing to add 
all these extra checks (and would welcome alternate suggestions!), but this is 
the only path forwards we've been able to find..




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-02-28 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 501110.
pmatos marked an inline comment as done.
pmatos added a comment.

Address the comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -27,43 +27,6 @@
 
 namespace WebAssembly {
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(co

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-28 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 501081.
pmatos added a comment.

Add forgotten comment to test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-funcref.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/SemaCXX/wasm-funcref.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/wasm-funcref.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fsyntax-only -verify -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
+
+// Testing that funcrefs work on template aliases
+// expected-no-diagnostics
+
+using IntIntFuncref = int(*)(int) __funcref;
+using DoubleQual = IntIntFuncref __funcref;
+
+int get(int);
+
+IntIntFuncref getFuncref() {
+return get;
+}
\ No newline at end of file
Index: clang/test/Sema/wasm-refs.c
===
--- clang/test/Sema/wasm-refs.c
+++ clang/test/Sema/wasm-refs.c
@@ -46,6 +46,8 @@
 __externref_t ***illegal_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
 
 void varargs(int, ...);
+typedef void (*__funcref funcref_t)();
+typedef void (*__funcref __funcref funcref_fail_t)(); // expected-warning {{attribute '__funcref' is already applied}}
 
 __externref_t func(__externref_t ref) {
   &ref; // expected-error {{cannot take address of WebAssembly reference}}
@@ -67,5 +69,7 @@
   _Alignof(__externref_t ***);   // expected-error {{pointer to WebAssembly reference type is not allowed}};
   varargs(1, ref);   // expected-error {{cannot pass expression of type '__externref_t' to variadic function}}
 
+  funcref_t func = __builtin_wasm_ref_null_func(0); // expected-error {{too many arguments to function call, expected 0, have 1}}
+
   return ref;
 }
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*fn_t)(int);
+
+static fn_funcref_t nullFuncref = 0;
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===
--- /d

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-28 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 501075.
pmatos marked 3 inline comments as done.
pmatos added a comment.

Patch with all outstanding comments addressed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-funcref.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/SemaCXX/wasm-funcref.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/wasm-funcref.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fsyntax-only -verify -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
+
+// Testing that funcrefs work on template aliases
+using IntIntFuncref = int(*)(int) __funcref;
+using DoubleQual = IntIntFuncref __funcref;
+
+int get(int);
+
+IntIntFuncref getFuncref() {
+return get;
+}
\ No newline at end of file
Index: clang/test/Sema/wasm-refs.c
===
--- clang/test/Sema/wasm-refs.c
+++ clang/test/Sema/wasm-refs.c
@@ -46,6 +46,8 @@
 __externref_t ***illegal_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
 
 void varargs(int, ...);
+typedef void (*__funcref funcref_t)();
+typedef void (*__funcref __funcref funcref_fail_t)(); // expected-warning {{attribute '__funcref' is already applied}}
 
 __externref_t func(__externref_t ref) {
   &ref; // expected-error {{cannot take address of WebAssembly reference}}
@@ -67,5 +69,7 @@
   _Alignof(__externref_t ***);   // expected-error {{pointer to WebAssembly reference type is not allowed}};
   varargs(1, ref);   // expected-error {{cannot pass expression of type '__externref_t' to variadic function}}
 
+  funcref_t func = __builtin_wasm_ref_null_func(0); // expected-error {{too many arguments to function call, expected 0, have 1}}
+
   return ref;
 }
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*fn_t)(int);
+
+static fn_funcref_t nullFuncref = 0;
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-28 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 4 inline comments as done.
pmatos added a comment.

Thanks @aaron.ballman . I think I have now address all outstanding comments.




Comment at: clang/include/clang/Basic/Attr.td:4129
+  let Documentation = [WebAssemblyExportNameDocs];
+  let Subjects = SubjectList<[TypedefName], ErrorDiag>;
+}

aaron.ballman wrote:
> pmatos wrote:
> > aaron.ballman wrote:
> > > erichkeane wrote:
> > > > pmatos wrote:
> > > > > erichkeane wrote:
> > > > > > pmatos wrote:
> > > > > > > erichkeane wrote:
> > > > > > > > Note that it seems this is likely not going to work correctly 
> > > > > > > > on template type aliases!  You probably want to make sure that 
> > > > > > > > is acceptable to you.
> > > > > > > Documentation says about Subject:
> > > > > > > 
> > > > > > > ```
> > > > > > >   // The things to which an attribute can appertain
> > > > > > >   SubjectList Subjects;
> > > > > > > ```
> > > > > > > 
> > > > > > > Given this can be attached to function pointer types, is the 
> > > > > > > subject then just Type ?
> > > > > > IIRC, the list of subjects are the Decls and Stmt types that are 
> > > > > > possibly allowed.  I don't thnk it would be just 'Type' there.
> > > > > > 
> > > > > > As you have it, it is only allowed on TypedefNameDecl.
> > > > > > 
> > > > > > See the SubsetSubject's at the top of this file for some examples 
> > > > > > on how you could constrain a special matcher to only work on 
> > > > > > function pointer decls.
> > > > > Good point @erichkeane . What do you think of FunctionPointer 
> > > > > implementation here?
> > > > That seems acceptable to me.
> > > That makes sense to me as well, but FWIW, type attributes don't currently 
> > > have much of any tablegen automation (unlike decl and stmt attributes), 
> > > so the subject list isn't strictly necessary here. But it's still 
> > > appreciated because 1) it's documentation, and 2) we want to tablegen 
> > > more and this helps us with that goal.
> > @erichkeane Yes, you're right. Something like 
> > 
> > ```
> > using IntIntFuncref = int(*)(int) __funcref;
> > ```
> > 
> > doesn't work. Why is this not accepted? Is it due to the Subjects listed?
> Not due to the subjects -- keyword attributes require manual parsing and type 
> attributes require manual processing (we don't tablegen as much as I'd like 
> for type attributes). But that code should be accepted (you should add a test 
> case for it as well).
Seems to be fine now.  Test added.



Comment at: clang/include/clang/Basic/AttrDocs.td:6930
+def WebAssemblyFuncrefDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{

aaron.ballman wrote:
> `DocCatType`, right?
Yes.



Comment at: clang/test/Sema/wasm-refs.c:50
+typedef void (*__funcref funcref_t)();
+typedef void (*__funcref __funcref funcref_fail_t)(); // expected-warning 
{{attribute '__funcref' is already applied}}
 

aaron.ballman wrote:
> Should we also test two-level application of the qualifier, as in?
> ```
> using uh_oh = funcref_t __funcref;
> ```
Double qualification shouldn't be an issue - adding this to 
`SemaCXX/wasm-funcref.cpp`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-02-15 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 497633.
pmatos added a comment.

Rebased on current HEAD.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -45,43 +45,6 @@
   Multivalue = 0x,
 };
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRefType(const 

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-15 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 497632.
pmatos added a comment.

Rebased on current HEAD.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/Sema/wasm-refs.c
===
--- clang/test/Sema/wasm-refs.c
+++ clang/test/Sema/wasm-refs.c
@@ -46,6 +46,8 @@
 __externref_t ***illegal_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
 
 void varargs(int, ...);
+typedef void (*__funcref funcref_t)();
+typedef void (*__funcref __funcref funcref_fail_t)(); // expected-warning {{attribute '__funcref' is already applied}}
 
 __externref_t func(__externref_t ref) {
   &ref; // expected-error {{cannot take address of WebAssembly reference}}
@@ -67,5 +69,7 @@
   _Alignof(__externref_t ***);   // expected-error {{pointer to WebAssembly reference type is not allowed}};
   varargs(1, ref);   // expected-error {{cannot pass expression of type '__externref_t' to variadic function}}
 
+  funcref_t func = __builtin_wasm_ref_null_func(0); // expected-error {{too many arguments to function call, expected 0, have 1}}
+
   return ref;
 }
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*fn_t)(int);
+
+static fn_funcref_t nullFuncref = 0;
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-funcref.c
@@ -0,0 +1,99 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef void (*__funcref funcref_t)();
+typedef int (*__funcref fn_funcref_t)(int);
+typedef int (*fn_t)(int);
+
+// Null funcref builtin call
+// CHECK-LABEL: @get_null(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t get_null() {
+  return __builtin_wasm_ref_null

[PATCH] D122215: [WebAssembly] Initial support for reference type externref in clang

2023-02-15 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 497630.
pmatos added a comment.

Rebased against HEAD. Waiting for @vitalybuka go ahead to land.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122215/new/

https://reviews.llvm.org/D122215

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/AST/TypeProperties.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/WebAssemblyReferenceTypes.def
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/module.modulemap
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/MicrosoftMangle.cpp
  clang/lib/AST/NSAPI.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypeLoc.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/lib/CodeGen/CodeGenTypes.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Index/USRGeneration.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTCommon.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/test/CodeGen/WebAssembly/wasm-externref.c
  clang/test/CodeGen/builtins-wasm.c
  clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
  clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp
  clang/tools/libclang/CIndex.cpp
  llvm/include/llvm/IR/Type.h
  llvm/include/llvm/Transforms/Utils.h
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/IR/Type.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/lib/Transforms/Utils/Mem2Reg.cpp

Index: llvm/lib/Transforms/Utils/Mem2Reg.cpp
===
--- llvm/lib/Transforms/Utils/Mem2Reg.cpp
+++ llvm/lib/Transforms/Utils/Mem2Reg.cpp
@@ -74,15 +74,19 @@
 struct PromoteLegacyPass : public FunctionPass {
   // Pass identification, replacement for typeid
   static char ID;
+  bool ForcePass; /// If true, forces pass to execute, instead of skipping.
 
-  PromoteLegacyPass() : FunctionPass(ID) {
+  PromoteLegacyPass() : FunctionPass(ID), ForcePass(false) {
+initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
+  }
+  PromoteLegacyPass(bool IsForced) : FunctionPass(ID), ForcePass(IsForced) {
 initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
   }
 
   // runOnFunction - To run this pass, first we calculate the alloca
   // instructions that are safe for promotion, then we promote each one.
   bool runOnFunction(Function &F) override {
-if (skipFunction(F))
+if (!ForcePass && skipFunction(F))
   return false;
 
 DominatorTree &DT = getAnalysis().getDomTree();
@@ -96,6 +100,7 @@
 AU.addRequired();
 AU.setPreservesCFG();
   }
+
 };
 
 } // end anonymous namespace
@@ -111,6 +116,6 @@
 false, false)
 
 // createPromoteMemoryToRegister - Provide an entry point to create this pass.
-FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
-  return new PromoteLegacyPass();
+FunctionPass *llvm::createPromoteMemoryToRegisterPass(bool IsForced) {
+  return new PromoteLegacyPass(IsForced);
 }
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -16,6 +16,7 @@
 #include "TargetInfo/WebAssemblyTargetInfo.h"
 #include "Utils/WebAssemblyUtilities.h"
 #include "WebAssembly.h"
+#include "WebAssemblyISelLowering.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblyTargetObjectFile.h"
 #include "WebAssemblyTargetTransformInfo.h"
@@ -464,6 +465,14 @@
 }
 
 void WebAssemblyPassConfig::addISelPrepare() {
+  WebAssemblyTargetMachine *WasmTM = static_cast(TM);
+  const WebAssemblySubtarget *Subtarget = WasmTM
+->getSubtargetImpl(std::string(WasmTM->getTargetCPU()),
+   std::string(WasmTM->getTargetFeatureString()));
+  if(Subtarget->hasReferenceTypes()) {
+// We need to remove allocas for reference types
+addPass(createPromoteMemoryToRegisterPass(true));
+  }
   // Lower atomics and TLS if necessary
   addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
 
Index: llvm/lib/IR/Type.cpp
===
--- llvm/lib/IR/Type.cpp
+++ llvm/lib/IR/Type.cpp
@@ -306,6 +306,18 @@
   return getInt64Ty(C)->getPointerTo(AS);
 }
 
+Type *Type::getWasm_Externr

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-14 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 2 inline comments as done.
pmatos added a comment.

@aaron.ballman I have finished addressing all the concerns on this patch. Do 
you have any further comments?




Comment at: clang/lib/Sema/SemaType.cpp:7289-7290
+  QualType Pointee = Type->getPointeeType();
+  Pointee = S.Context.getAddrSpaceQualType(
+  S.Context.removeAddrSpaceQualType(Pointee), ASIdx);
+  Type = State.getAttributedType(A, Type, S.Context.getPointerType(Pointee));

aaron.ballman wrote:
> aaron.ballman wrote:
> > What happens when the user's function already has an explicitly specified 
> > address space?
> Still wondering about this as well.
We'll just be overriding the address space in this case. Although, I am not 
sure something like this can happen in Wasm given there's only one linear 
memory.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-13 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 2 inline comments as done.
pmatos added inline comments.



Comment at: clang/lib/Sema/SemaType.cpp:7269
+  }
+  Attrs[NewAttrKind] = true;
+

aaron.ballman wrote:
> aaron.ballman wrote:
> > This seems like it's not used.
> Still wondering about this
That's correct - removed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-13 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 497004.
pmatos added a comment.

Remove unnecessary code.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/Sema/wasm-refs.c
===
--- clang/test/Sema/wasm-refs.c
+++ clang/test/Sema/wasm-refs.c
@@ -46,6 +46,8 @@
 __externref_t ***illegal_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
 
 void varargs(int, ...);
+typedef void (*__funcref funcref_t)();
+typedef void (*__funcref __funcref funcref_fail_t)(); // expected-warning {{attribute '__funcref' is already applied}}
 
 __externref_t func(__externref_t ref) {
   &ref; // expected-error {{cannot take address of WebAssembly reference}}
@@ -67,5 +69,7 @@
   _Alignof(__externref_t ***);   // expected-error {{pointer to WebAssembly reference type is not allowed}};
   varargs(1, ref);   // expected-error {{cannot pass expression of type '__externref_t' to variadic function}}
 
+  funcref_t func = __builtin_wasm_ref_null_func(0); // expected-error {{too many arguments to function call, expected 0, have 1}}
+
   return ref;
 }
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*fn_t)(int);
+
+static fn_funcref_t nullFuncref = 0;
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-funcref.c
@@ -0,0 +1,99 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef void (*__funcref funcref_t)();
+typedef int (*__funcref fn_funcref_t)(int);
+typedef int (*fn_t)(int);
+
+// Null funcref builtin call
+// CHECK-LABEL: @get_null(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t get_null() {
+  return __builtin_wasm_ref_null

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-13 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 497002.
pmatos marked 2 inline comments as done.
pmatos added a comment.

Further refinement of the patch with more diagnostics tested.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/Sema/wasm-refs.c
===
--- clang/test/Sema/wasm-refs.c
+++ clang/test/Sema/wasm-refs.c
@@ -46,6 +46,8 @@
 __externref_t ***illegal_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
 
 void varargs(int, ...);
+typedef void (*__funcref funcref_t)();
+typedef void (*__funcref __funcref funcref_fail_t)(); // expected-warning {{attribute '__funcref' is already applied}}
 
 __externref_t func(__externref_t ref) {
   &ref; // expected-error {{cannot take address of WebAssembly reference}}
@@ -67,5 +69,7 @@
   _Alignof(__externref_t ***);   // expected-error {{pointer to WebAssembly reference type is not allowed}};
   varargs(1, ref);   // expected-error {{cannot pass expression of type '__externref_t' to variadic function}}
 
+  funcref_t func = __builtin_wasm_ref_null_func(0); // expected-error {{too many arguments to function call, expected 0, have 1}}
+
   return ref;
 }
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of '__funcref' keyword outside the WebAssembly triple}}
+typedef int (*fn_t)(int);
+
+static fn_funcref_t nullFuncref = 0;
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-funcref.c
@@ -0,0 +1,99 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef void (*__funcref funcref_t)();
+typedef int (*__funcref fn_funcref_t)(int);
+typedef int (*fn_t)(int);
+
+// Null funcref builtin call
+// CHECK-LABEL: @get_null(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrsp

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-13 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 4 inline comments as done.
pmatos added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:6696
+bool Sema::BuiltinWasmRefNullFunc(CallExpr *TheCall) {
+  if (TheCall->getNumArgs() != 0)
+return true;

erichkeane wrote:
> Does this diagnose?  Should we be emitting an error here?
I think it makes sense. Will add a test as well for the diagnostic.



Comment at: clang/lib/Sema/SemaChecking.cpp:6557-6561
+  // Therefore we need to change the types of the DeclRefExpr (stored in FDecl)
+  // and regenerate a straight up CallExpr on the modified FDecl.
+  // returning
+  // CallExpr
+  // `- FunctionDecl

aaron.ballman wrote:
> Why would we need to do this?? And what do we do when there is no 
> `FunctionDecl` to get back to (because it's a call expression through a 
> function pointer, for example)?
I have added a test to check this situation.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-13 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 496937.
pmatos marked 5 inline comments as done.
pmatos added a comment.

Addressed a few comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of __funcref keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of __funcref keyword outside the WebAssembly triple}}
+typedef int (*fn_t)(int);
+
+static fn_funcref_t nullFuncref = 0;
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-funcref.c
@@ -0,0 +1,84 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef void (*__funcref funcref_t)();
+typedef int (*__funcref fn_funcref_t)(int);
+typedef int (*fn_t)(int);
+
+// Null funcref builtin call
+// CHECK-LABEL: @get_null(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t get_null() {
+  return __builtin_wasm_ref_null_func();
+}
+
+// Call to null funcref builtin but requires cast since
+// default return value for builtin is a funcref with function type () -> ().
+// CHECK-LABEL: @get_null_ii(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+fn_funcref_t get_null_ii() {
+  return (fn_funcref_t) __builtin_wasm_ref_null_func();
+}
+
+// Identity function for funcref.
+// CHECK-LABEL: @identity(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[FN_ADDR:%.*]] = alloca ptr addrspace(20), align 4
+// CHECK-NEXT:store ptr addrspace(20) [[FN:%.*]], ptr [[FN_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load ptr addrspace(20), ptr [[FN_ADDR]], align 4
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t identity(funcref_t fn) {
+  return fn;
+}
+
+void helper(funcref_t);
+
+// Pass funcref ref as an argument to a helper function.
+// CHECK-LABEL: @handle(
+// CHECK-NEXT:  entry:
+

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-13 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 6 inline comments as done.
pmatos added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:6552-6555
+  // The call we get looks like
+  // CallExpr
+  // `- ImplicitCastExpr
+  //   `- DeclRefExpr

tlively wrote:
> How do these parts correspond to the original source code?
If I understand your question correctly, this is just the semantic checks for 
each of the builtins.



Comment at: clang/lib/Sema/SemaChecking.cpp:6564
+  // Prepare FDecl type
+  QualType Pointee = Context.getFunctionType(Context.VoidTy, {}, {});
+  QualType Type = Context.getPointerType(Pointee);

aaron.ballman wrote:
> Why are you guaranteed this function returns void?
I think this question is not relevant anymore given the current code, right? 
The wasm ref null builtin will always return the null funcref.



Comment at: clang/lib/Sema/SemaChecking.cpp:6704-6710
+  // Therefore we need to change the types of the DeclRefExpr (stored in FDecl)
+  // and regenerate a straight up CallExpr on the modified FDecl.
+  // returning
+  // CallExpr
+  // `- FunctionDecl
+
+  // Prepare FDecl type

aaron.ballman wrote:
> These comments no longer seem to match the code -- nothing creates a 
> `FunctionDecl` here.
Right - fixed.



Comment at: clang/lib/Sema/SemaChecking.cpp:6708
+  // CallExpr
+  // `- FunctionDecl
+

erichkeane wrote:
> All those comments don't really seem relevant here, and are not really 
> correct.  The only thing SemaChecking should do is either modify its 
> arguments (though you don't have any), or set its return type.  
Right, these comments can be removed. I fixed these.



Comment at: clang/lib/Sema/SemaType.cpp:7340
+  attr::Kind NewAttrKind = A->getKind();
+  QualType Desugared = Type;
+  const auto *AT = dyn_cast(Type);

erichkeane wrote:
> This name seems misleading... should you be desugaring 'Type' to store it in 
> 'Desugared'?
> 
> Also, I see that this value is never used, so why do the copy init?  ALSO, 
> why is it called Desugared, when it never seems to get a Desugared type?  
Bad naming due to earlier code. I have simplified this code now.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-01 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 493919.
pmatos marked an inline comment as done.
pmatos added a comment.

Address some of the pending comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/SemaCXX/wasm-funcref.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/SemaCXX/wasm-funcref.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/wasm-funcref.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fsyntax-only -verify -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
+
+// Testing that funcrefs work on template aliases
+using IntIntFuncref = int(*)(int);// __funcref;
+
+int get(int);
+
+IntIntFuncref getFuncref() {
+return get;
+}
\ No newline at end of file
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of __funcref keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of __funcref keyword outside the WebAssembly triple}}
+typedef int (*fn_t)(int);
+
+static fn_funcref_t nullFuncref = 0;
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-funcref.c
@@ -0,0 +1,84 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef void (*__funcref funcref_t)();
+typedef int (*__funcref fn_funcref_t)(int);
+typedef int (*fn_t)(int);
+
+// Null funcref builtin call
+// CHECK-LABEL: @get_null(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t get_null() {
+  return __builtin_wasm_ref_null_func();
+}
+
+// Call to null funcref builtin but requires cast since
+// default return value for builtin is a funcref with function type () -> ().
+// CHECK-LABEL: @get_null_ii(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+fn_funcref_t get_null_ii() {
+  return (fn_funcref_t) __builtin_wasm_ref_n

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-01 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked an inline comment as done.
pmatos added inline comments.



Comment at: clang/include/clang/Basic/Attr.td:4129
+  let Documentation = [WebAssemblyExportNameDocs];
+  let Subjects = SubjectList<[TypedefName], ErrorDiag>;
+}

aaron.ballman wrote:
> erichkeane wrote:
> > pmatos wrote:
> > > erichkeane wrote:
> > > > pmatos wrote:
> > > > > erichkeane wrote:
> > > > > > Note that it seems this is likely not going to work correctly on 
> > > > > > template type aliases!  You probably want to make sure that is 
> > > > > > acceptable to you.
> > > > > Documentation says about Subject:
> > > > > 
> > > > > ```
> > > > >   // The things to which an attribute can appertain
> > > > >   SubjectList Subjects;
> > > > > ```
> > > > > 
> > > > > Given this can be attached to function pointer types, is the subject 
> > > > > then just Type ?
> > > > IIRC, the list of subjects are the Decls and Stmt types that are 
> > > > possibly allowed.  I don't thnk it would be just 'Type' there.
> > > > 
> > > > As you have it, it is only allowed on TypedefNameDecl.
> > > > 
> > > > See the SubsetSubject's at the top of this file for some examples on 
> > > > how you could constrain a special matcher to only work on function 
> > > > pointer decls.
> > > Good point @erichkeane . What do you think of FunctionPointer 
> > > implementation here?
> > That seems acceptable to me.
> That makes sense to me as well, but FWIW, type attributes don't currently 
> have much of any tablegen automation (unlike decl and stmt attributes), so 
> the subject list isn't strictly necessary here. But it's still appreciated 
> because 1) it's documentation, and 2) we want to tablegen more and this helps 
> us with that goal.
@erichkeane Yes, you're right. Something like 

```
using IntIntFuncref = int(*)(int) __funcref;
```

doesn't work. Why is this not accepted? Is it due to the Subjects listed?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-02-01 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 11 inline comments as done.
pmatos added inline comments.



Comment at: clang/lib/Basic/Targets/DirectX.h:45
 3, // hlsl_groupshared
+// Wasm address space values for this map are dummy
+20, // wasm_funcref

erichkeane wrote:
> pmatos wrote:
> > erichkeane wrote:
> > > Also apply to the rest of the targets.  Also, why is there only 1 added 
> > > here?  I thought we had 2 address spaces for Wasm?
> > Externref is a type in clang, doesn't need its own address space in clang, 
> > only when it's lowered to a opaque type in llvm it gets its own address 
> > space.
> Please fix the comment in my suggestion.
> 
> Also, your explanation doesn't make it clear to me why you added TWO entries 
> to this list for other targets, but only 1 here.
I have now fixed that. We just need one address space.



Comment at: clang/lib/Basic/Targets/WebAssembly.h:44-45
+0,  // ptr64
+10, // wasm_externref,
+20, // wasm_funcref
+};

erichkeane wrote:
> aaron.ballman wrote:
> > I'm not super familiar with the address space maps, but this sets of my 
> > spidey senses. All of the other address space maps end with:
> > 
> > ptr64, hlsl_groupshared, wasm_funcref
> > 
> > but this one is ending with:
> > 
> > ptr64, wasm_externref, wasm_funcref
> > 
> > which makes me think something's amiss here. Thoughts?
> That DEFINITELY looks suspicious to me as well, I noted above too, but either 
> we need to specify we're re-using the `hlsl_groupshared` for `wasm_externref` 
> address space (at which point, i wonder: why not re-use a different address 
> space?), or correct this.
Fixed this now. We only need the address space for funcref. The address space 
for externref is now necessary as it's its own type.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122215: [WebAssembly] Initial support for reference type externref in clang

2023-01-31 Thread Paulo Matos via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGeb66833d1957: [clang][WebAssembly] Initial support for 
reference type externref in clang (authored by pmatos).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122215/new/

https://reviews.llvm.org/D122215

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/AST/TypeProperties.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/WebAssemblyReferenceTypes.def
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/module.modulemap
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/MicrosoftMangle.cpp
  clang/lib/AST/NSAPI.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypeLoc.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/lib/CodeGen/CodeGenTypes.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Index/USRGeneration.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTCommon.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/test/CodeGen/WebAssembly/wasm-externref.c
  clang/test/CodeGen/builtins-wasm.c
  clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
  clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp
  clang/tools/libclang/CIndex.cpp
  llvm/include/llvm/IR/Type.h
  llvm/include/llvm/Transforms/Utils.h
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/IR/Type.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/lib/Transforms/Utils/Mem2Reg.cpp

Index: llvm/lib/Transforms/Utils/Mem2Reg.cpp
===
--- llvm/lib/Transforms/Utils/Mem2Reg.cpp
+++ llvm/lib/Transforms/Utils/Mem2Reg.cpp
@@ -74,15 +74,19 @@
 struct PromoteLegacyPass : public FunctionPass {
   // Pass identification, replacement for typeid
   static char ID;
+  bool ForcePass; /// If true, forces pass to execute, instead of skipping.
 
-  PromoteLegacyPass() : FunctionPass(ID) {
+  PromoteLegacyPass() : FunctionPass(ID), ForcePass(false) {
+initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
+  }
+  PromoteLegacyPass(bool IsForced) : FunctionPass(ID), ForcePass(IsForced) {
 initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
   }
 
   // runOnFunction - To run this pass, first we calculate the alloca
   // instructions that are safe for promotion, then we promote each one.
   bool runOnFunction(Function &F) override {
-if (skipFunction(F))
+if (!ForcePass && skipFunction(F))
   return false;
 
 DominatorTree &DT = getAnalysis().getDomTree();
@@ -96,6 +100,7 @@
 AU.addRequired();
 AU.setPreservesCFG();
   }
+
 };
 
 } // end anonymous namespace
@@ -111,6 +116,6 @@
 false, false)
 
 // createPromoteMemoryToRegister - Provide an entry point to create this pass.
-FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
-  return new PromoteLegacyPass();
+FunctionPass *llvm::createPromoteMemoryToRegisterPass(bool IsForced) {
+  return new PromoteLegacyPass(IsForced);
 }
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -16,6 +16,7 @@
 #include "TargetInfo/WebAssemblyTargetInfo.h"
 #include "Utils/WebAssemblyUtilities.h"
 #include "WebAssembly.h"
+#include "WebAssemblyISelLowering.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblyTargetObjectFile.h"
 #include "WebAssemblyTargetTransformInfo.h"
@@ -464,6 +465,14 @@
 }
 
 void WebAssemblyPassConfig::addISelPrepare() {
+  WebAssemblyTargetMachine *WasmTM = static_cast(TM);
+  const WebAssemblySubtarget *Subtarget = WasmTM
+->getSubtargetImpl(std::string(WasmTM->getTargetCPU()),
+   std::string(WasmTM->getTargetFeatureString()));
+  if(Subtarget->hasReferenceTypes()) {
+// We need to remove allocas for reference types
+addPass(createPromoteMemoryToRegisterPass(true));
+  }
   // Lower atomics and TLS if necessary
   addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
 
Index: llvm/lib/IR/Type.cpp
===
--- llvm/lib/IR/Type.

[PATCH] D122215: [WebAssembly] Initial support for reference type externref in clang

2023-01-31 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 493633.
pmatos added a comment.

Address last comment before landing.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122215/new/

https://reviews.llvm.org/D122215

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/AST/TypeProperties.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/WebAssemblyReferenceTypes.def
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/module.modulemap
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/MicrosoftMangle.cpp
  clang/lib/AST/NSAPI.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypeLoc.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/lib/CodeGen/CodeGenTypes.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Index/USRGeneration.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTCommon.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/test/CodeGen/WebAssembly/wasm-externref.c
  clang/test/CodeGen/builtins-wasm.c
  clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
  clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp
  clang/tools/libclang/CIndex.cpp
  llvm/include/llvm/IR/Type.h
  llvm/include/llvm/Transforms/Utils.h
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/IR/Type.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/lib/Transforms/Utils/Mem2Reg.cpp

Index: llvm/lib/Transforms/Utils/Mem2Reg.cpp
===
--- llvm/lib/Transforms/Utils/Mem2Reg.cpp
+++ llvm/lib/Transforms/Utils/Mem2Reg.cpp
@@ -74,15 +74,19 @@
 struct PromoteLegacyPass : public FunctionPass {
   // Pass identification, replacement for typeid
   static char ID;
+  bool ForcePass; /// If true, forces pass to execute, instead of skipping.
 
-  PromoteLegacyPass() : FunctionPass(ID) {
+  PromoteLegacyPass() : FunctionPass(ID), ForcePass(false) {
+initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
+  }
+  PromoteLegacyPass(bool IsForced) : FunctionPass(ID), ForcePass(IsForced) {
 initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
   }
 
   // runOnFunction - To run this pass, first we calculate the alloca
   // instructions that are safe for promotion, then we promote each one.
   bool runOnFunction(Function &F) override {
-if (skipFunction(F))
+if (!ForcePass && skipFunction(F))
   return false;
 
 DominatorTree &DT = getAnalysis().getDomTree();
@@ -96,6 +100,7 @@
 AU.addRequired();
 AU.setPreservesCFG();
   }
+
 };
 
 } // end anonymous namespace
@@ -111,6 +116,6 @@
 false, false)
 
 // createPromoteMemoryToRegister - Provide an entry point to create this pass.
-FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
-  return new PromoteLegacyPass();
+FunctionPass *llvm::createPromoteMemoryToRegisterPass(bool IsForced) {
+  return new PromoteLegacyPass(IsForced);
 }
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -16,6 +16,7 @@
 #include "TargetInfo/WebAssemblyTargetInfo.h"
 #include "Utils/WebAssemblyUtilities.h"
 #include "WebAssembly.h"
+#include "WebAssemblyISelLowering.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblyTargetObjectFile.h"
 #include "WebAssemblyTargetTransformInfo.h"
@@ -464,6 +465,14 @@
 }
 
 void WebAssemblyPassConfig::addISelPrepare() {
+  WebAssemblyTargetMachine *WasmTM = static_cast(TM);
+  const WebAssemblySubtarget *Subtarget = WasmTM
+->getSubtargetImpl(std::string(WasmTM->getTargetCPU()),
+   std::string(WasmTM->getTargetFeatureString()));
+  if(Subtarget->hasReferenceTypes()) {
+// We need to remove allocas for reference types
+addPass(createPromoteMemoryToRegisterPass(true));
+  }
   // Lower atomics and TLS if necessary
   addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
 
Index: llvm/lib/IR/Type.cpp
===
--- llvm/lib/IR/Type.cpp
+++ llvm/lib/IR/Type.cpp
@@ -306,6 +306,18 @@
   return getInt64Ty(C)->getPointerTo(AS);
 }
 
+Type *Type::getWasm_ExternrefTy(LLVMContext &C) {
+  /

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-30 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 493264.
pmatos added a comment.

Rebase on main and fix a test diagnostic expectation.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -45,43 +45,6 @@
   Multivalue = 0x,
 };
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-01-30 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 493251.
pmatos added a comment.

Rebase on main.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of __funcref keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of __funcref keyword outside the WebAssembly triple}}
+typedef int (*fn_t)(int);
+
+static fn_funcref_t nullFuncref = 0;
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-funcref.c
@@ -0,0 +1,84 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef void (*__funcref funcref_t)();
+typedef int (*__funcref fn_funcref_t)(int);
+typedef int (*fn_t)(int);
+
+// Null funcref builtin call
+// CHECK-LABEL: @get_null(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t get_null() {
+  return __builtin_wasm_ref_null_func();
+}
+
+// Call to null funcref builtin but requires cast since
+// default return value for builtin is a funcref with function type () -> ().
+// CHECK-LABEL: @get_null_ii(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+fn_funcref_t get_null_ii() {
+  return (fn_funcref_t) __builtin_wasm_ref_null_func();
+}
+
+// Identity function for funcref.
+// CHECK-LABEL: @identity(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[FN_ADDR:%.*]] = alloca ptr addrspace(20), align 4
+// CHECK-NEXT:store ptr addrspace(20) [[FN:%.*]], ptr [[FN_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load ptr addrspace(20), ptr [[FN_ADDR]], align 4
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t identity(funcref_t fn) {
+  return fn;
+}
+
+void helper(funcref_t);
+
+// Pass funcref ref as an argument to a helper function.
+// CHECK-LABEL: @handle(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[

[PATCH] D122215: [WebAssembly] Initial support for reference type externref in clang

2023-01-30 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 493226.
pmatos added a comment.

Rebase on main.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122215/new/

https://reviews.llvm.org/D122215

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/AST/TypeProperties.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/WebAssemblyReferenceTypes.def
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/module.modulemap
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/MicrosoftMangle.cpp
  clang/lib/AST/NSAPI.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypeLoc.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/lib/CodeGen/CodeGenTypes.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Index/USRGeneration.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTCommon.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/test/CodeGen/WebAssembly/wasm-externref.c
  clang/test/CodeGen/builtins-wasm.c
  clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
  clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp
  clang/tools/libclang/CIndex.cpp
  llvm/include/llvm/IR/Type.h
  llvm/include/llvm/Transforms/Utils.h
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/IR/Type.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/lib/Transforms/Utils/Mem2Reg.cpp

Index: llvm/lib/Transforms/Utils/Mem2Reg.cpp
===
--- llvm/lib/Transforms/Utils/Mem2Reg.cpp
+++ llvm/lib/Transforms/Utils/Mem2Reg.cpp
@@ -74,15 +74,19 @@
 struct PromoteLegacyPass : public FunctionPass {
   // Pass identification, replacement for typeid
   static char ID;
+  bool ForcePass; /// If true, forces pass to execute, instead of skipping.
 
-  PromoteLegacyPass() : FunctionPass(ID) {
+  PromoteLegacyPass() : FunctionPass(ID), ForcePass(false) {
+initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
+  }
+  PromoteLegacyPass(bool IsForced) : FunctionPass(ID), ForcePass(IsForced) {
 initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
   }
 
   // runOnFunction - To run this pass, first we calculate the alloca
   // instructions that are safe for promotion, then we promote each one.
   bool runOnFunction(Function &F) override {
-if (skipFunction(F))
+if (!ForcePass && skipFunction(F))
   return false;
 
 DominatorTree &DT = getAnalysis().getDomTree();
@@ -96,6 +100,7 @@
 AU.addRequired();
 AU.setPreservesCFG();
   }
+
 };
 
 } // end anonymous namespace
@@ -111,6 +116,6 @@
 false, false)
 
 // createPromoteMemoryToRegister - Provide an entry point to create this pass.
-FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
-  return new PromoteLegacyPass();
+FunctionPass *llvm::createPromoteMemoryToRegisterPass(bool IsForced) {
+  return new PromoteLegacyPass(IsForced);
 }
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -16,6 +16,7 @@
 #include "TargetInfo/WebAssemblyTargetInfo.h"
 #include "Utils/WebAssemblyUtilities.h"
 #include "WebAssembly.h"
+#include "WebAssemblyISelLowering.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblyTargetObjectFile.h"
 #include "WebAssemblyTargetTransformInfo.h"
@@ -464,6 +465,14 @@
 }
 
 void WebAssemblyPassConfig::addISelPrepare() {
+  WebAssemblyTargetMachine *WasmTM = static_cast(TM);
+  const WebAssemblySubtarget *Subtarget = WasmTM
+->getSubtargetImpl(std::string(WasmTM->getTargetCPU()),
+   std::string(WasmTM->getTargetFeatureString()));
+  if(Subtarget->hasReferenceTypes()) {
+// We need to remove allocas for reference types
+addPass(createPromoteMemoryToRegisterPass(true));
+  }
   // Lower atomics and TLS if necessary
   addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
 
Index: llvm/lib/IR/Type.cpp
===
--- llvm/lib/IR/Type.cpp
+++ llvm/lib/IR/Type.cpp
@@ -306,6 +306,18 @@
   return getInt64Ty(C)->getPointerTo(AS);
 }
 
+Type *Type::getWasm_ExternrefTy(LLVMContext &C) {
+  // opaque pointer in a

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-24 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

@aaron.ballman Thanks for all the comments, I have now finished addressing 
those. What do you think of the current patch?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-24 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 491790.
pmatos added a comment.

Add missing newline at end of file.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -45,43 +45,6 @@
   Multivalue = 0x,
 };
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRef

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-24 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked an inline comment as done.
pmatos added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:11827
+def err_wasm_builtin_arg_must_be_integer_type : Error <
+  "%ordinal0 argument must be an integer">;
 } // end of sema component.

asb wrote:
> aaron.ballman wrote:
> > I'm a bit shocked by the number of new diagnostics for this type as it 
> > seems incredibly restrictive and like the rules are going to be hard to 
> > understand. For example, you cannot use this type in an exception 
> > specification despite that being a compile-time property. Can you use it 
> > within a conditional explicit clause (https://godbolt.org/z/sn3G8xE3T)? It 
> > must be static, but can it be thread local?
> > 
> > Basically, it seems like this type is unlike basically any other type and 
> > we're going to have to carry a significant amount of extra code around to 
> > handle all the edge cases and those edge cases look a bit like whack-a-mole 
> > in practice.
> The whack-a-mole aspect of disallowing table uses is something I'm not fond 
> of eitherbut I'm not sure I see a better approach. Do you have any 
> alternatives in mind?
A couple concrete answers in addition to what @asb already said.

* I don't think we can use tables at the moment in conditional explicit clause. 
Indeed it doesn't make sense since there's no what, at the moment, to 
statically initialize the table.
* Tables are thread local. Indeed, threads in WebAssembly share only linear 
memory so anything that's not in linear memory is thread local. This is true 
for tables but also for all reference types.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-24 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 491784.
pmatos added a comment.

Simplify and add tests for remaining diagnostics


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -45,43 +45,6 @@
   Multivalue = 0x,
 };
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inli

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-24 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 491707.
pmatos added a comment.

Further tests for use of tables in conditional branches.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -45,43 +45,6 @@
   Multivalue = 0x,
 };
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-23 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 491608.
pmatos added a comment.

Finish fixing tests after dianostic message changes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -45,43 +45,6 @@
   Multivalue = 0x,
 };
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-i

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-23 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 491468.
pmatos added a comment.

Fix some tests whose diagnostics changed


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -45,43 +45,6 @@
   Multivalue = 0x,
 };
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool 

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-23 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 491353.
pmatos marked 7 inline comments as done.
pmatos added a comment.

Address more comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -45,43 +45,6 @@
   Multivalue = 0x,
 };
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTE

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-23 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 2 inline comments as done.
pmatos added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:11797
+def err_typecheck_wasm_table_must_have_zero_length : Error<
+  "only zero-length WebAssembly tables are currently supported">;
+def err_wasm_table_in_function : Error<

aaron.ballman wrote:
> Do you plan to support non-zero-length tables in the near future? I'm 
> wondering if this should be reworded to remove the "currently supported" 
> phrasing.
Yes, the next phase of this work is to implement this together with element 
section to initialize tables.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-18 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 490208.
pmatos added a comment.

Remove some unnecessary diagnostics.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -45,43 +45,6 @@
   Multivalue = 0x,
 };
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
-}
-inline bool isRe

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-18 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 5 inline comments as done.
pmatos added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2171-2176
 def err_reference_bind_to_vector_element : Error<
   "%select{non-const|volatile}0 reference cannot bind to vector element">;
 def err_reference_bind_to_matrix_element : Error<
   "%select{non-const|volatile}0 reference cannot bind to matrix element">;
+def err_reference_bind_to_table_element : Error<
+  "%select{non-const|volatile}0 reference cannot bind to table element">;

aaron.ballman wrote:
> We should combine these diagnostics with a `%select` rather than keep 
> duplicating the same message.
> 
> This is unused and untested.
Right - this is no longer needed.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:3035-3040
 def err_attribute_invalid_vector_type : Error<"invalid vector element type 
%0">;
 def err_attribute_invalid_bitint_vector_type : Error<
   "'_BitInt' vector element width must be %select{a power of 2|"
   "at least as wide as 'CHAR_BIT'}0">;
 def err_attribute_invalid_matrix_type : Error<"invalid matrix element type 
%0">;
+def err_attribute_invalid_wasm_table_type : Error<"invalid table element type 
%0">;

aaron.ballman wrote:
> We should probably combine these as well.
> 
> This is unused and untested.
Sigh - again. Apologies. This was an initial patch that used matrix subscript 
to create a table subscript patch but was dropped and therefore is unused.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-01-16 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added inline comments.



Comment at: clang/include/clang/Basic/Attr.td:4129
+  let Documentation = [WebAssemblyExportNameDocs];
+  let Subjects = SubjectList<[TypedefName], ErrorDiag>;
+}

erichkeane wrote:
> pmatos wrote:
> > erichkeane wrote:
> > > Note that it seems this is likely not going to work correctly on template 
> > > type aliases!  You probably want to make sure that is acceptable to you.
> > Documentation says about Subject:
> > 
> > ```
> >   // The things to which an attribute can appertain
> >   SubjectList Subjects;
> > ```
> > 
> > Given this can be attached to function pointer types, is the subject then 
> > just Type ?
> IIRC, the list of subjects are the Decls and Stmt types that are possibly 
> allowed.  I don't thnk it would be just 'Type' there.
> 
> As you have it, it is only allowed on TypedefNameDecl.
> 
> See the SubsetSubject's at the top of this file for some examples on how you 
> could constrain a special matcher to only work on function pointer decls.
Good point @erichkeane . What do you think of FunctionPointer implementation 
here?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-01-16 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 489552.
pmatos added a comment.

Add new Attr Subject Function Pointer for __funcref attribute.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of __funcref keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of __funcref keyword outside the WebAssembly triple}}
+typedef int (*fn_t)(int);
+
+static fn_funcref_t nullFuncref = 0;
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-funcref.c
@@ -0,0 +1,84 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef void (*__funcref funcref_t)();
+typedef int (*__funcref fn_funcref_t)(int);
+typedef int (*fn_t)(int);
+
+// Null funcref builtin call
+// CHECK-LABEL: @get_null(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t get_null() {
+  return __builtin_wasm_ref_null_func();
+}
+
+// Call to null funcref builtin but requires cast since
+// default return value for builtin is a funcref with function type () -> ().
+// CHECK-LABEL: @get_null_ii(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+fn_funcref_t get_null_ii() {
+  return (fn_funcref_t) __builtin_wasm_ref_null_func();
+}
+
+// Identity function for funcref.
+// CHECK-LABEL: @identity(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[FN_ADDR:%.*]] = alloca ptr addrspace(20), align 4
+// CHECK-NEXT:store ptr addrspace(20) [[FN:%.*]], ptr [[FN_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load ptr addrspace(20), ptr [[FN_ADDR]], align 4
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t identity(funcref_t fn) {
+  return fn;
+}
+
+void helper(funcref_t);
+
+// Pass funcref ref as an argument to a helper function.
+// CHECK-LABEL: @handle

[PATCH] D122215: [WebAssembly] Initial support for reference type externref in clang

2023-01-16 Thread Paulo Matos via Phabricator via cfe-commits
pmatos added a comment.

I feel like the latest patch addresses all concerns until now. What do you 
think?




Comment at: clang/include/clang/Basic/WebAssemblyReferenceTypes.def:16
+//
+//  - Name is the name of the builtin type.  MangledName is the mangled name.
+//

aaron.ballman wrote:
> aaron.ballman wrote:
> > What kind of mangling is this name? Itanium? Microsoft? Something else?
> Still wondering about this.
This is just a generic name to base the actual mangling on tbh.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122215/new/

https://reviews.llvm.org/D122215

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122215: [WebAssembly] Initial support for reference type externref in clang

2023-01-16 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 489520.
pmatos marked 7 inline comments as done.
pmatos added a comment.

Rebase on main.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122215/new/

https://reviews.llvm.org/D122215

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/AST/TypeProperties.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/WebAssemblyReferenceTypes.def
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/module.modulemap
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/MicrosoftMangle.cpp
  clang/lib/AST/NSAPI.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypeLoc.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/lib/CodeGen/CodeGenTypes.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Index/USRGeneration.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTCommon.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/test/CodeGen/WebAssembly/wasm-externref.c
  clang/test/CodeGen/builtins-wasm.c
  clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
  clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp
  clang/tools/libclang/CIndex.cpp
  llvm/include/llvm/IR/Type.h
  llvm/include/llvm/Transforms/Utils.h
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/IR/Type.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/lib/Transforms/Utils/Mem2Reg.cpp

Index: llvm/lib/Transforms/Utils/Mem2Reg.cpp
===
--- llvm/lib/Transforms/Utils/Mem2Reg.cpp
+++ llvm/lib/Transforms/Utils/Mem2Reg.cpp
@@ -74,15 +74,19 @@
 struct PromoteLegacyPass : public FunctionPass {
   // Pass identification, replacement for typeid
   static char ID;
+  bool ForcePass; /// If true, forces pass to execute, instead of skipping.
 
-  PromoteLegacyPass() : FunctionPass(ID) {
+  PromoteLegacyPass() : FunctionPass(ID), ForcePass(false) {
+initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
+  }
+  PromoteLegacyPass(bool IsForced) : FunctionPass(ID), ForcePass(IsForced) {
 initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
   }
 
   // runOnFunction - To run this pass, first we calculate the alloca
   // instructions that are safe for promotion, then we promote each one.
   bool runOnFunction(Function &F) override {
-if (skipFunction(F))
+if (!ForcePass && skipFunction(F))
   return false;
 
 DominatorTree &DT = getAnalysis().getDomTree();
@@ -96,6 +100,7 @@
 AU.addRequired();
 AU.setPreservesCFG();
   }
+
 };
 
 } // end anonymous namespace
@@ -111,6 +116,6 @@
 false, false)
 
 // createPromoteMemoryToRegister - Provide an entry point to create this pass.
-FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
-  return new PromoteLegacyPass();
+FunctionPass *llvm::createPromoteMemoryToRegisterPass(bool IsForced) {
+  return new PromoteLegacyPass(IsForced);
 }
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -16,6 +16,7 @@
 #include "TargetInfo/WebAssemblyTargetInfo.h"
 #include "Utils/WebAssemblyUtilities.h"
 #include "WebAssembly.h"
+#include "WebAssemblyISelLowering.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblyTargetObjectFile.h"
 #include "WebAssemblyTargetTransformInfo.h"
@@ -464,6 +465,14 @@
 }
 
 void WebAssemblyPassConfig::addISelPrepare() {
+  WebAssemblyTargetMachine *WasmTM = static_cast(TM);
+  const WebAssemblySubtarget *Subtarget = WasmTM
+->getSubtargetImpl(std::string(WasmTM->getTargetCPU()),
+   std::string(WasmTM->getTargetFeatureString()));
+  if(Subtarget->hasReferenceTypes()) {
+// We need to remove allocas for reference types
+addPass(createPromoteMemoryToRegisterPass(true));
+  }
   // Lower atomics and TLS if necessary
   addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
 
Index: llvm/lib/IR/Type.cpp
===
--- llvm/lib/IR/Type.cpp
+++ llvm/lib/IR/Type.cpp
@@ -306,6 +306,18 @@
   return getInt64Ty(C)->getPointerTo(AS);
 }
 
+Type *Type::getWasm_ExternrefTy(LL

[PATCH] D139010: [clang][WebAssembly] Implement support for table types and builtins

2023-01-16 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 489468.
pmatos added a comment.

Updating tests after some changes to previous diagnostics.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139010/new/

https://reviews.llvm.org/D139010

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/TypeBitCodes.def
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/builtins-table.c
  clang/test/CodeGen/WebAssembly/table.c
  clang/test/Sema/builtins-wasm.c
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs-and-tables.cpp
  clang/test/SemaCXX/wasm-refs.cpp
  llvm/include/llvm/CodeGen/WasmAddressSpaces.h
  llvm/include/llvm/IR/Type.h
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp

Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp
@@ -62,8 +62,9 @@
   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::isRefType(PTI->getPointerOperand()->getType())) &&
-!(ITP && WebAssembly::isRefType(ITP->getDestTy(
+if (!(PTI &&
+  PTI->getPointerOperand()->getType()->isWebAssemblyReferenceType()) &&
+!(ITP && ITP->getDestTy()->isWebAssemblyReferenceType()))
   continue;
 
 UndefValue *U = UndefValue::get(I->getType());
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1202,7 +1202,7 @@
   // Lastly, if this is a call to a funcref we need to add an instruction
   // table.set to the chain and transform the call.
   if (CLI.CB &&
-  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
+  CLI.CB->getCalledOperand()->getType()->isWebAssemblyFuncrefType()) {
 // In the absence of function references proposal where a funcref call is
 // lowered to call_ref, using reference types we generate a table.set to set
 // the funcref to a special table used solely for this purpose, followed by
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
===
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
@@ -45,43 +45,6 @@
   Multivalue = 0x,
 };
 
-enum WasmAddressSpace : unsigned {
-  // Default address space, for pointers to linear memory (stack, heap, data).
-  WASM_ADDRESS_SPACE_DEFAULT = 0,
-  // A non-integral address space for pointers to named objects outside of
-  // 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,
-};
-
-inline bool isDefaultAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_DEFAULT;
-}
-inline bool isWasmVarAddressSpace(unsigned AS) {
-  return AS == WASM_ADDRESS_SPACE_VAR;
-}
-inline bool isValidAddressSpace(unsigned AS) {
-  return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
-}
-inline bool isFuncrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
-}
-inline bool isExternrefType(const Type *Ty) {
-  return isa(Ty) &&
- Ty->getPointerAddressSpace() ==
- WasmAdd

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-01-13 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 489031.
pmatos marked 2 inline comments as done.
pmatos added a comment.

Address a few comments, add new test for funcref keyword diagnostic.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

Files:
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/AddressSpaces.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Basic/TargetInfo.cpp
  clang/lib/Basic/Targets/DirectX.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Basic/Targets/SPIR.h
  clang/lib/Basic/Targets/TCE.h
  clang/lib/Basic/Targets/WebAssembly.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Format/FormatToken.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/WebAssembly/wasm-funcref.c
  clang/test/Parser/wasm-funcref.c
  clang/test/SemaTemplate/address_space-dependent.cpp

Index: clang/test/SemaTemplate/address_space-dependent.cpp
===
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@
 
 template 
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388587)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}}
 }
 
 template 
@@ -101,7 +101,7 @@
   car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
-  correct<0x7FFFEA>();
+  correct<0x7FFFE9>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
Index: clang/test/Parser/wasm-funcref.c
===
--- /dev/null
+++ clang/test/Parser/wasm-funcref.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -fsyntax-only -verify %s
+
+// Test that we trigger an error at parse time if using keyword funcref
+// while not using a wasm triple.
+typedef void (*__funcref funcref_t)(); // expected-error {{invalid use of __funcref keyword outside the WebAssembly triple}}
+typedef int (*__funcref fn_funcref_t)(int);// expected-error {{invalid use of __funcref keyword outside the WebAssembly triple}}
+typedef int (*fn_t)(int);
+
+static fn_funcref_t nullFuncref = 0;
Index: clang/test/CodeGen/WebAssembly/wasm-funcref.c
===
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-funcref.c
@@ -0,0 +1,84 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s
+
+typedef void (*__funcref funcref_t)();
+typedef int (*__funcref fn_funcref_t)(int);
+typedef int (*fn_t)(int);
+
+// Null funcref builtin call
+// CHECK-LABEL: @get_null(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t get_null() {
+  return __builtin_wasm_ref_null_func();
+}
+
+// Call to null funcref builtin but requires cast since
+// default return value for builtin is a funcref with function type () -> ().
+// CHECK-LABEL: @get_null_ii(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.ref.null.func()
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+fn_funcref_t get_null_ii() {
+  return (fn_funcref_t) __builtin_wasm_ref_null_func();
+}
+
+// Identity function for funcref.
+// CHECK-LABEL: @identity(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[FN_ADDR:%.*]] = alloca ptr addrspace(20), align 4
+// CHECK-NEXT:store ptr addrspace(20) [[FN:%.*]], ptr [[FN_ADDR]], align 4
+// CHECK-NEXT:[[TMP0:%.*]] = load ptr addrspace(20), ptr [[FN_ADDR]], align 4
+// CHECK-NEXT:ret ptr addrspace(20) [[TMP0]]
+//
+funcref_t identity(funcref_t fn) {
+  return fn;
+}
+
+void helper(funcref_t);
+
+// Pass funcref ref as an argument to a helper function.
+// CHECK-LABEL: @handle(
+// CHECK-NEXT:  

[PATCH] D122215: [WebAssembly] Initial support for reference type externref in clang

2023-01-13 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 489005.
pmatos added a comment.

Rename test that still had tables in its name.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122215/new/

https://reviews.llvm.org/D122215

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/AST/TypeProperties.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/WebAssemblyReferenceTypes.def
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/module.modulemap
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/MicrosoftMangle.cpp
  clang/lib/AST/NSAPI.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypeLoc.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/lib/CodeGen/CodeGenTypes.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Index/USRGeneration.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTCommon.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/test/CodeGen/WebAssembly/wasm-externref.c
  clang/test/CodeGen/builtins-wasm.c
  clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
  clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
  clang/test/Sema/wasm-refs.c
  clang/test/SemaCXX/wasm-refs.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp
  clang/tools/libclang/CIndex.cpp
  llvm/include/llvm/IR/Type.h
  llvm/include/llvm/Transforms/Utils.h
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/IR/Type.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/lib/Transforms/Utils/Mem2Reg.cpp

Index: llvm/lib/Transforms/Utils/Mem2Reg.cpp
===
--- llvm/lib/Transforms/Utils/Mem2Reg.cpp
+++ llvm/lib/Transforms/Utils/Mem2Reg.cpp
@@ -74,15 +74,19 @@
 struct PromoteLegacyPass : public FunctionPass {
   // Pass identification, replacement for typeid
   static char ID;
+  bool ForcePass; /// If true, forces pass to execute, instead of skipping.
 
-  PromoteLegacyPass() : FunctionPass(ID) {
+  PromoteLegacyPass() : FunctionPass(ID), ForcePass(false) {
+initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
+  }
+  PromoteLegacyPass(bool IsForced) : FunctionPass(ID), ForcePass(IsForced) {
 initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
   }
 
   // runOnFunction - To run this pass, first we calculate the alloca
   // instructions that are safe for promotion, then we promote each one.
   bool runOnFunction(Function &F) override {
-if (skipFunction(F))
+if (!ForcePass && skipFunction(F))
   return false;
 
 DominatorTree &DT = getAnalysis().getDomTree();
@@ -96,6 +100,7 @@
 AU.addRequired();
 AU.setPreservesCFG();
   }
+
 };
 
 } // end anonymous namespace
@@ -111,6 +116,6 @@
 false, false)
 
 // createPromoteMemoryToRegister - Provide an entry point to create this pass.
-FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
-  return new PromoteLegacyPass();
+FunctionPass *llvm::createPromoteMemoryToRegisterPass(bool IsForced) {
+  return new PromoteLegacyPass(IsForced);
 }
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -16,6 +16,7 @@
 #include "TargetInfo/WebAssemblyTargetInfo.h"
 #include "Utils/WebAssemblyUtilities.h"
 #include "WebAssembly.h"
+#include "WebAssemblyISelLowering.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblyTargetObjectFile.h"
 #include "WebAssemblyTargetTransformInfo.h"
@@ -464,6 +465,14 @@
 }
 
 void WebAssemblyPassConfig::addISelPrepare() {
+  WebAssemblyTargetMachine *WasmTM = static_cast(TM);
+  const WebAssemblySubtarget *Subtarget = WasmTM
+->getSubtargetImpl(std::string(WasmTM->getTargetCPU()),
+   std::string(WasmTM->getTargetFeatureString()));
+  if(Subtarget->hasReferenceTypes()) {
+// We need to remove allocas for reference types
+addPass(createPromoteMemoryToRegisterPass(true));
+  }
   // Lower atomics and TLS if necessary
   addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
 
Index: llvm/lib/IR/Type.cpp
===
--- llvm/lib/IR/Type.cpp
+++ llvm/lib/IR/Type.cpp
@@ -306,6 +306,18 @@
   return getInt64Ty(C)->getPointerTo(AS);
 }
 
+Type *Type::getWasm_ExternrefTy(LLVMContext 

[PATCH] D122215: [WebAssembly] Initial support for reference type externref in clang

2023-01-13 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 488999.
pmatos added a comment.

Fix tests after changing name mangling and error messages.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122215/new/

https://reviews.llvm.org/D122215

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/AST/TypeProperties.td
  clang/include/clang/Basic/BuiltinsWebAssembly.def
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/WebAssemblyReferenceTypes.def
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/module.modulemap
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/MicrosoftMangle.cpp
  clang/lib/AST/NSAPI.cpp
  clang/lib/AST/PrintfFormatString.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypeLoc.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/lib/CodeGen/CodeGenTypes.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/CodeGen/TargetInfo.h
  clang/lib/Index/USRGeneration.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTCommon.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/test/CodeGen/WebAssembly/wasm-externref.c
  clang/test/CodeGen/builtins-wasm.c
  clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
  clang/test/CodeGenCXX/wasm-reftypes-typeinfo.cpp
  clang/test/Sema/wasm-refs-and-tables.c
  clang/test/SemaCXX/wasm-refs.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp
  clang/tools/libclang/CIndex.cpp
  llvm/include/llvm/IR/Type.h
  llvm/include/llvm/Transforms/Utils.h
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/IR/Type.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/lib/Transforms/Utils/Mem2Reg.cpp

Index: llvm/lib/Transforms/Utils/Mem2Reg.cpp
===
--- llvm/lib/Transforms/Utils/Mem2Reg.cpp
+++ llvm/lib/Transforms/Utils/Mem2Reg.cpp
@@ -74,15 +74,19 @@
 struct PromoteLegacyPass : public FunctionPass {
   // Pass identification, replacement for typeid
   static char ID;
+  bool ForcePass; /// If true, forces pass to execute, instead of skipping.
 
-  PromoteLegacyPass() : FunctionPass(ID) {
+  PromoteLegacyPass() : FunctionPass(ID), ForcePass(false) {
+initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
+  }
+  PromoteLegacyPass(bool IsForced) : FunctionPass(ID), ForcePass(IsForced) {
 initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
   }
 
   // runOnFunction - To run this pass, first we calculate the alloca
   // instructions that are safe for promotion, then we promote each one.
   bool runOnFunction(Function &F) override {
-if (skipFunction(F))
+if (!ForcePass && skipFunction(F))
   return false;
 
 DominatorTree &DT = getAnalysis().getDomTree();
@@ -96,6 +100,7 @@
 AU.addRequired();
 AU.setPreservesCFG();
   }
+
 };
 
 } // end anonymous namespace
@@ -111,6 +116,6 @@
 false, false)
 
 // createPromoteMemoryToRegister - Provide an entry point to create this pass.
-FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
-  return new PromoteLegacyPass();
+FunctionPass *llvm::createPromoteMemoryToRegisterPass(bool IsForced) {
+  return new PromoteLegacyPass(IsForced);
 }
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -16,6 +16,7 @@
 #include "TargetInfo/WebAssemblyTargetInfo.h"
 #include "Utils/WebAssemblyUtilities.h"
 #include "WebAssembly.h"
+#include "WebAssemblyISelLowering.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblyTargetObjectFile.h"
 #include "WebAssemblyTargetTransformInfo.h"
@@ -464,6 +465,14 @@
 }
 
 void WebAssemblyPassConfig::addISelPrepare() {
+  WebAssemblyTargetMachine *WasmTM = static_cast(TM);
+  const WebAssemblySubtarget *Subtarget = WasmTM
+->getSubtargetImpl(std::string(WasmTM->getTargetCPU()),
+   std::string(WasmTM->getTargetFeatureString()));
+  if(Subtarget->hasReferenceTypes()) {
+// We need to remove allocas for reference types
+addPass(createPromoteMemoryToRegisterPass(true));
+  }
   // Lower atomics and TLS if necessary
   addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
 
Index: llvm/lib/IR/Type.cpp
===
--- llvm/lib/IR/Type.cpp
+++ llvm/lib/IR/Type.cpp
@@ -306,6 +306,18 @@
   return getInt64Ty(C)->getPointerTo(AS);
 }
 
+Type *Type::getWasm_E

[PATCH] D128440: [WebAssembly] Initial support for reference type funcref in clang

2023-01-13 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 15 inline comments as done.
pmatos added inline comments.



Comment at: clang/include/clang/Basic/Attr.td:4129
+  let Documentation = [WebAssemblyExportNameDocs];
+  let Subjects = SubjectList<[TypedefName], ErrorDiag>;
+}

erichkeane wrote:
> Note that it seems this is likely not going to work correctly on template 
> type aliases!  You probably want to make sure that is acceptable to you.
Documentation says about Subject:

```
  // The things to which an attribute can appertain
  SubjectList Subjects;
```

Given this can be attached to function pointer types, is the subject then just 
Type ?



Comment at: clang/include/clang/Basic/AttrDocs.td:6855
+Clang supports the ``__funcref`` attribute for the WebAssembly target. 
+This attribute may be attached to a function pointer declaration, where it 
modifies 
+its underlying representation to be a WebAssembly ``funcref``.

erichkeane wrote:
> This says 'function pointer declaration', but you have it's subject as 
> Typedef?
That's a mistake due to how things worked in an earlier revision. Thanks for 
spotting. 



Comment at: clang/include/clang/Basic/TokenKinds.def:666
+// WebAssembly Type Extension
+KEYWORD(__funcref , KEYALL)
+

erichkeane wrote:
> aaron.ballman wrote:
> > pmatos wrote:
> > > aaron.ballman wrote:
> > > > Why is this a keyword in all language modes?
> > > I might have misread the docs but this keyword should be available for 
> > > both C and C++. Maybe I want `KEYC99 | KEYCXX` ?
> > I was thinking this keyword would only work for a web assembly target, so 
> > we'd likely want to add `KEYWEBASM` or something to the list like we have 
> > for `KEYALTIVEC`. But now I'm second-guessing that instinct and am 
> > wondering what behavior we want here.
> > 
> > 1) Parse the keyword in all language modes and for all targets, give an 
> > ignored attribute warning if the target isn't web assembly
> > 2) Parse the keyword in all language modes and for all targets, give a 
> > parse time diagnostic (error?) if the target isn't web assembly
> > 3) Only expose the keyword if the target is web assembly, otherwise it 
> > parses as an identifier and you get the usual parse errors
> > 
> > My original thinking was that we wanted #3, but on reflection both #1 and 
> > #2 seem reasonable to me. Do you have a preference? I think I prefer either 
> > 2 or 3 over 1 because this involves the type system (errors are usually a 
> > better approach in that case).
> I don't think #1 is acceptable for the keyword, we shouldn't ignore keywords 
> like we do attributes.  Doing an ignored warning in SemaDeclAttr.td for the 
> ATTRIBUTE is fine, but keyword form needs to be an error.
> 
> My preference is #2, an error if we encounter it during parsing and we're not 
> in WebAsm target.
Thanks for the comments, I have now updated this with an implementation of 
option 2 and added a diagnostic test.



Comment at: clang/lib/Basic/Targets/DirectX.h:45
 3, // hlsl_groupshared
+// Wasm address space values for this map are dummy
+20, // wasm_funcref

erichkeane wrote:
> Also apply to the rest of the targets.  Also, why is there only 1 added here? 
>  I thought we had 2 address spaces for Wasm?
Externref is a type in clang, doesn't need its own address space in clang, only 
when it's lowered to a opaque type in llvm it gets its own address space.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128440/new/

https://reviews.llvm.org/D128440

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   >