[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

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

In D95425#2810027 , @DavidSpickett 
wrote:

> Also affecting riscv-v (riscvv?) so I've reverted the change.
>
> https://lab.llvm.org/buildbot/#/builders/67/builds/3087

Apologies for the breakages and thanks for reverting. I will take a look at it 
and if I need help, I will get back to you.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-06-10 Thread David Spickett via Phabricator via cfe-commits
DavidSpickett added a comment.

Also affecting riscv-v (riscvv?) so I've reverted the change.

https://lab.llvm.org/buildbot/#/builders/67/builds/3087


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-06-10 Thread David Spickett via Phabricator via cfe-commits
DavidSpickett added a comment.

Hi @pmatos, this has caused SVE related failures on our AArch64 bot (and 
probably others):
https://lab.llvm.org/buildbot/#/builders/43/builds/7187

Not an SVE expert myself but if you need help figuring it out I can find 
someone to help out I'm sure.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-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.
pmatos marked 2 inline comments as done.
Closed by commit rG31859f896cf9: Implementation of global.get/set for reftypes 
in LLVM IR (authored by pmatos).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

Files:
  clang/lib/Basic/Targets/WebAssembly.cpp
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/CodeGen/ValueTypes.h
  llvm/include/llvm/Support/MachineValueType.h
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/MachineOperand.cpp
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/lib/CodeGen/TargetLoweringBase.cpp
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISD.def
  llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
  llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/test/CodeGen/WebAssembly/externref-globalget.ll
  llvm/test/CodeGen/WebAssembly/externref-globalset.ll
  llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll
  llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll
  llvm/test/CodeGen/WebAssembly/externref-undef.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
  llvm/test/CodeGen/WebAssembly/funcref-call.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalset.ll

Index: llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define void @set_funcref_global(%funcref %g) {
+  ;; this generates a global.set of @funcref_global
+  store %funcref %g, %funcref addrspace(1)* @funcref_global
+  ret void
+}
+
+; CHECK-LABEL: set_funcref_global:
+; CHECK-NEXT: functype   set_funcref_global (funcref) -> ()
+; CHECK-NEXT: local.get  0
+; CHECK-NEXT: global.set funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define %funcref @return_funcref_global() {
+  ;; this generates a global.get of @funcref_global
+  %ref = load %funcref, %funcref addrspace(1)* @funcref_global
+  ret %funcref %ref
+}
+
+; CHECK-LABEL: return_funcref_global:
+; CHECK-NEXT: .functype   return_funcref_global () -> (funcref)
+; CHECK-NEXT: global.get funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-call.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-call.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type void ()
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+define void @call_funcref(%funcref %ref) {
+  call addrspace(20) void %ref() 
+  ret void
+}
+
+; CHECK-LABEL: call_funcref:
+; CHECK-NEXT: functype   call_funcref (funcref) -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: call_indirect __funcref_call_table, () -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: ref.null func
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: end_function
+
+; CHECK: .tabletype __funcref_call_table, funcref
Index: llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
@@ -0,0 +1,11 @@
+; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | 

[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-06-09 Thread Thomas Lively via Phabricator via cfe-commits
tlively accepted this revision.
tlively added a comment.
This revision is now accepted and ready to land.

Thanks for your patience through all the review! Let's get this landed :)




Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:19
  [],
  "table.get\t$res, $table",
  "table.get\t$table",

pmatos wrote:
> tlively wrote:
> > pmatos wrote:
> > > tlively wrote:
> > > > wingo wrote:
> > > > > Not something for this patch, but this is certainly bogus: surely we 
> > > > > mean `table.get\t$table, $i` and we have an i32 index argument?
> > > > Agree about the i32 index argument, but it is correct to have the 
> > > > result as part of the string for the register-based output format.
> > > Not sure I understand why this should be `$i` instead of `$table`. Isn't 
> > > `$table` represented as an index anyway? A `table32_op` is defined as 
> > > `Operand` so I don't quite understand what we gain by changing this.
> > I would still expect to see a register for the result and immediate inputs 
> > for the table symbol and the table slot index here.
> Not sure I understood everything properly as the only thing missing was the 
> index in the register based version. I added that now.
Ah, sorry about that. I was confused and was thinking that the table index was 
an immediate, but of course you're right that it is not.



Comment at: llvm/test/CodeGen/WebAssembly/funcref-call.ll:15
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0

pmatos wrote:
> tlively wrote:
> > Missing a table element index here.
> I am not sure whether that's the case. According to the spec, table.set only 
> gets a table. Two elements are popped from the stack: the index `i32.const 0` 
> and the value `local.get 0`.
Yep, sorry for the confusion.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-06-08 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 6 inline comments as done.
pmatos added a comment.

Hopefully we are close to landing this. :)




Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:19
  [],
  "table.get\t$res, $table",
  "table.get\t$table",

tlively wrote:
> pmatos wrote:
> > tlively wrote:
> > > wingo wrote:
> > > > Not something for this patch, but this is certainly bogus: surely we 
> > > > mean `table.get\t$table, $i` and we have an i32 index argument?
> > > Agree about the i32 index argument, but it is correct to have the result 
> > > as part of the string for the register-based output format.
> > Not sure I understand why this should be `$i` instead of `$table`. Isn't 
> > `$table` represented as an index anyway? A `table32_op` is defined as 
> > `Operand` so I don't quite understand what we gain by changing this.
> I would still expect to see a register for the result and immediate inputs 
> for the table symbol and the table slot index here.
Not sure I understood everything properly as the only thing missing was the 
index in the register based version. I added that now.



Comment at: llvm/test/CodeGen/WebAssembly/funcref-call.ll:15
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0

tlively wrote:
> Missing a table element index here.
I am not sure whether that's the case. According to the spec, table.set only 
gets a table. Two elements are popped from the stack: the index `i32.const 0` 
and the value `local.get 0`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-06-08 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 350599.
pmatos added a comment.

Fix details requested by @tlively in latest comemnts.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

Files:
  clang/lib/Basic/Targets/WebAssembly.cpp
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/CodeGen/ValueTypes.h
  llvm/include/llvm/Support/MachineValueType.h
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/MachineOperand.cpp
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/lib/CodeGen/TargetLoweringBase.cpp
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISD.def
  llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
  llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/test/CodeGen/WebAssembly/externref-globalget.ll
  llvm/test/CodeGen/WebAssembly/externref-globalset.ll
  llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll
  llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll
  llvm/test/CodeGen/WebAssembly/externref-undef.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
  llvm/test/CodeGen/WebAssembly/funcref-call.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalset.ll

Index: llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define void @set_funcref_global(%funcref %g) {
+  ;; this generates a global.set of @funcref_global
+  store %funcref %g, %funcref addrspace(1)* @funcref_global
+  ret void
+}
+
+; CHECK-LABEL: set_funcref_global:
+; CHECK-NEXT: functype   set_funcref_global (funcref) -> ()
+; CHECK-NEXT: local.get  0
+; CHECK-NEXT: global.set funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define %funcref @return_funcref_global() {
+  ;; this generates a global.get of @funcref_global
+  %ref = load %funcref, %funcref addrspace(1)* @funcref_global
+  ret %funcref %ref
+}
+
+; CHECK-LABEL: return_funcref_global:
+; CHECK-NEXT: .functype   return_funcref_global () -> (funcref)
+; CHECK-NEXT: global.get funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-call.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-call.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type void ()
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+define void @call_funcref(%funcref %ref) {
+  call addrspace(20) void %ref() 
+  ret void
+}
+
+; CHECK-LABEL: call_funcref:
+; CHECK-NEXT: functype   call_funcref (funcref) -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: call_indirect __funcref_call_table, () -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: ref.null func
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: end_function
+
+; CHECK: .tabletype __funcref_call_table, funcref
Index: llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
@@ -0,0 +1,11 @@
+; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+
+%extern = type opaque
+%externref = type %extern addrspace(10)*
+
+define void @store_extern(%externref %ref) {
+  

[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

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

@tlively thanks for the comments. I am currently taking some time off but I 
will address your concerns upon my return.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-24 Thread Thomas Lively via Phabricator via cfe-commits
tlively added a comment.

It would be good to add dedicated tests for table.get and table.set as well.




Comment at: llvm/lib/CodeGen/MachineOperand.cpp:1174
+  } else
+OS << ", opaque ";
   if (getAlign() != getBaseAlign())

pmatos wrote:
> tlively wrote:
> > Is there a test that demonstrates this printing? Also, I'm not sure 
> > specifically calling out zero-sized operands in the text dump is that 
> > useful. Can zero-sized operands still be given an alignment? If so, it 
> > might even be good to continue printing the alignment for them.
> The reason I changed this here is due to the call of getSize() crashing for 
> zeroSized arguments. I have not added test for the printing. I don't think 
> zero-sized operands can still be given an alignment. We are actually setting 
> the alignment to
Looks like this comment was cut off! I wonder if it would be better to skip 
printing `opaque` for now since we have no test of it/ Also, if another target 
comes along with a zero-sized type, I don't know whether "opaque" will 
necessarily describe it.



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp:558-559
 
+  // If this is a funcref call, to avoid hidden GC roots, we need to clear the
+  // table slot with ref.null upon call_indirect return.
+  if (IsIndirect && IsFuncrefCall) {

Can you add the .wat of the code being generated here to the comment?



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:19
  [],
  "table.get\t$res, $table",
  "table.get\t$table",

pmatos wrote:
> tlively wrote:
> > wingo wrote:
> > > Not something for this patch, but this is certainly bogus: surely we mean 
> > > `table.get\t$table, $i` and we have an i32 index argument?
> > Agree about the i32 index argument, but it is correct to have the result as 
> > part of the string for the register-based output format.
> Not sure I understand why this should be `$i` instead of `$table`. Isn't 
> `$table` represented as an index anyway? A `table32_op` is defined as 
> `Operand` so I don't quite understand what we gain by changing this.
I would still expect to see a register for the result and immediate inputs for 
the table symbol and the table slot index here.



Comment at: llvm/test/CodeGen/WebAssembly/externref-undef.ll:13-14
+; CHECK-LABEL: return_extern_undef:
+; CHECK-NEXT: functype   return_extern_undef () -> ()
+; CHECK-NEXT: end_function
+

tlively wrote:
> pmatos wrote:
> > tlively wrote:
> > > I would expect this to declare an externref local and return it 
> > > uninitialized or to return a ref.null. It would be good to at least add a 
> > > TODO comment for fixing this.
> > Returning a `ref.null` or an uninitialized externref would make more sense 
> > if the return type would be `%externref`. However, in this case this is an 
> > `%extern` value, which really is an opaque type and should never really 
> > happen.
> Ah, that makes sense.
It would be good to add this explanation as a comment in the test file.



Comment at: llvm/test/CodeGen/WebAssembly/funcref-call.ll:15
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0

Missing a table element index here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

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

@deadalnix @tlively @sbc100 anything missing here to get this landed?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

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

Rebase and update minor details and fix a few lint warnings...
Non-functional changes only.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

Files:
  clang/lib/Basic/Targets/WebAssembly.cpp
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/CodeGen/ValueTypes.h
  llvm/include/llvm/Support/MachineValueType.h
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/MachineOperand.cpp
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/lib/CodeGen/TargetLoweringBase.cpp
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISD.def
  llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
  llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/test/CodeGen/WebAssembly/externref-globalget.ll
  llvm/test/CodeGen/WebAssembly/externref-globalset.ll
  llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll
  llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll
  llvm/test/CodeGen/WebAssembly/externref-undef.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
  llvm/test/CodeGen/WebAssembly/funcref-call.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalset.ll

Index: llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define void @set_funcref_global(%funcref %g) {
+  ;; this generates a global.set of @funcref_global
+  store %funcref %g, %funcref addrspace(1)* @funcref_global
+  ret void
+}
+
+; CHECK-LABEL: set_funcref_global:
+; CHECK-NEXT: functype   set_funcref_global (funcref) -> ()
+; CHECK-NEXT: local.get  0
+; CHECK-NEXT: global.set funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define %funcref @return_funcref_global() {
+  ;; this generates a global.get of @funcref_global
+  %ref = load %funcref, %funcref addrspace(1)* @funcref_global
+  ret %funcref %ref
+}
+
+; CHECK-LABEL: return_funcref_global:
+; CHECK-NEXT: .functype   return_funcref_global () -> (funcref)
+; CHECK-NEXT: global.get funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-call.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-call.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type void ()
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+define void @call_funcref(%funcref %ref) {
+  call addrspace(20) void %ref() 
+  ret void
+}
+
+; CHECK-LABEL: call_funcref:
+; CHECK-NEXT: functype   call_funcref (funcref) -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: call_indirect __funcref_call_table, () -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: ref.null func
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: end_function
+
+; CHECK: .tabletype __funcref_call_table, funcref
Index: llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
@@ -0,0 +1,11 @@
+; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+
+%extern = type opaque
+%externref = type %extern addrspace(10)*
+
+define void 

[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-17 Thread Andy Wingo via Phabricator via cfe-commits
wingo added inline comments.



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:15
 multiclass TABLE {
+  let mayLoad = 1 in
   defm TABLE_GET_#rt : I<(outs rt:$res), (ins table32_op:$table),

pmatos wrote:
> tlively wrote:
> > wingo wrote:
> > > I think you may need `hasSideEffects = 0` for these annotations to have 
> > > an effect.
> > I would be surprised if this were true!
> Why would this be the case? If I remember correctly, I added `mayLoad` and 
> `mayStore` here so that lowering includes a chain. And this works without the 
> need for `hasSideEffects`. Unless you think this is required for other 
> reaons, but `mayLoad` works with it.
Yeah I misunderstood, I was thinking that `mayLoad` and `mayStore` were a 
subset of the side effect annotations of `hasSideEffects`, which defaults to 1 
effectively (grep for `guessInstructionProperties`).  But no, the side effects 
modelled here are the disjoint bits `mayLoad`, `mayStore`, and 
`hasSideEffects`; `mayRaiseFPException` would appear to be a subset of 
`hasSideEffects`.  Still, may best to explicitly set `hasSideEffects` to 1 for 
`table.get ` and `table.set` just as documentation that they can trap if the 
index is out-of-bounds.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-07 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 343695.
pmatos added a comment.

Making the linter happy...


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

Files:
  clang/lib/Basic/Targets/WebAssembly.cpp
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/CodeGen/ValueTypes.h
  llvm/include/llvm/Support/MachineValueType.h
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/MachineOperand.cpp
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/TargetLoweringBase.cpp
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISD.def
  llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
  llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/test/CodeGen/WebAssembly/externref-globalget.ll
  llvm/test/CodeGen/WebAssembly/externref-globalset.ll
  llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll
  llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll
  llvm/test/CodeGen/WebAssembly/externref-undef.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
  llvm/test/CodeGen/WebAssembly/funcref-call.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalset.ll

Index: llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define void @set_funcref_global(%funcref %g) {
+  ;; this generates a global.set of @funcref_global
+  store %funcref %g, %funcref addrspace(1)* @funcref_global
+  ret void
+}
+
+; CHECK-LABEL: set_funcref_global:
+; CHECK-NEXT: functype   set_funcref_global (funcref) -> ()
+; CHECK-NEXT: local.get  0
+; CHECK-NEXT: global.set funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define %funcref @return_funcref_global() {
+  ;; this generates a global.get of @funcref_global
+  %ref = load %funcref, %funcref addrspace(1)* @funcref_global
+  ret %funcref %ref
+}
+
+; CHECK-LABEL: return_funcref_global:
+; CHECK-NEXT: .functype   return_funcref_global () -> (funcref)
+; CHECK-NEXT: global.get funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-call.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-call.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type void ()
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+define void @call_funcref(%funcref %ref) {
+  call addrspace(20) void %ref() 
+  ret void
+}
+
+; CHECK-LABEL: call_funcref:
+; CHECK-NEXT: functype   call_funcref (funcref) -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: call_indirect __funcref_call_table, () -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: ref.null func
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: end_function
+
+; CHECK: .tabletype __funcref_call_table, funcref
Index: llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
@@ -0,0 +1,11 @@
+; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+
+%extern = type opaque
+%externref = type %extern addrspace(10)*
+
+define void 

[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-07 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 343685.
pmatos added a comment.

- Simplifies some of code in the middle-end.
- Removes setComdat and adds setWeak

Small improvements to address comments in review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

Files:
  clang/lib/Basic/Targets/WebAssembly.cpp
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/CodeGen/ValueTypes.h
  llvm/include/llvm/Support/MachineValueType.h
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/MachineOperand.cpp
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/TargetLoweringBase.cpp
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISD.def
  llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
  llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/test/CodeGen/WebAssembly/externref-globalget.ll
  llvm/test/CodeGen/WebAssembly/externref-globalset.ll
  llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll
  llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll
  llvm/test/CodeGen/WebAssembly/externref-undef.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
  llvm/test/CodeGen/WebAssembly/funcref-call.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalset.ll

Index: llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define void @set_funcref_global(%funcref %g) {
+  ;; this generates a global.set of @funcref_global
+  store %funcref %g, %funcref addrspace(1)* @funcref_global
+  ret void
+}
+
+; CHECK-LABEL: set_funcref_global:
+; CHECK-NEXT: functype   set_funcref_global (funcref) -> ()
+; CHECK-NEXT: local.get  0
+; CHECK-NEXT: global.set funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define %funcref @return_funcref_global() {
+  ;; this generates a global.get of @funcref_global
+  %ref = load %funcref, %funcref addrspace(1)* @funcref_global
+  ret %funcref %ref
+}
+
+; CHECK-LABEL: return_funcref_global:
+; CHECK-NEXT: .functype   return_funcref_global () -> (funcref)
+; CHECK-NEXT: global.get funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-call.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-call.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type void ()
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+define void @call_funcref(%funcref %ref) {
+  call addrspace(20) void %ref() 
+  ret void
+}
+
+; CHECK-LABEL: call_funcref:
+; CHECK-NEXT: functype   call_funcref (funcref) -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: call_indirect __funcref_call_table, () -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: ref.null func
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: end_function
+
+; CHECK: .tabletype __funcref_call_table, funcref
Index: llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
@@ -0,0 +1,11 @@
+; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s 

[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-07 Thread Paulo Matos via Phabricator via cfe-commits
pmatos marked 7 inline comments as done.
pmatos added inline comments.



Comment at: llvm/lib/CodeGen/MachineOperand.cpp:1174
+  } else
+OS << ", opaque ";
   if (getAlign() != getBaseAlign())

tlively wrote:
> Is there a test that demonstrates this printing? Also, I'm not sure 
> specifically calling out zero-sized operands in the text dump is that useful. 
> Can zero-sized operands still be given an alignment? If so, it might even be 
> good to continue printing the alignment for them.
The reason I changed this here is due to the call of getSize() crashing for 
zeroSized arguments. I have not added test for the printing. I don't think 
zero-sized operands can still be given an alignment. We are actually setting 
the alignment to



Comment at: llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp:132-134
+// Setting Comdat ensure only one table is left after linking when multiple
+// modules define the table.
+Sym->setComdat(true);

sbc100 wrote:
> tlively wrote:
> > Is this necessary given that the symbol is set to be undefined? Perhaps it 
> > would be better to make it defined here and also set comdat so that the 
> > linker doesn't need to do anything special to make sure it exists in the 
> > final binary. (Or possibly I'm misunderstanding what these settings mean!) 
> > @sbc100 wdyt?
> I think don't want this here.  Firstly I think this will mark the symbol as 
> being a comdat group symbol .. which is not the same thing as being part of a 
> comdat group ( which I think is that is indented here).Secondly, I don't 
> think it makes sense for an undefined symbol to be part of a comdat group.  I 
> think what you want here, if the symbol was defined is `setWeak()`.Given 
> that is not defined I dont think you even want that.
It seems I was mistaken - I thought that by setting it as Comdat, the linker 
would merge symbols from different compilation units if they existed. Maybe 
what I need is `Weak` then.



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h:59-61
+  // AS 2 : is an integral address space for globals of externref values
+  // AS 3 : is an non-integral address space for funcref values
+  // AS 4 : is an integral address spaces for globals of funcref values

tlively wrote:
> Why are the address spaces for globals integral? It doesn't make sense to do 
> arithmetic on the "address" of a global afaict. Does using getelementptr to 
> index tables in the global address space require the address space to be 
> integral? If so, that might be a good reason to make the address space 
> integral, but it might also be a good reason to put tables and globals in 
> different address spaces instead. Also, IMO it would be better to use just a 
> single address space for all globals; that way we could support globals with 
> other types like i32, i64, etc. without even more address spaces.
Current set of patches should have addressed your concerns here.



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:15
 multiclass TABLE {
+  let mayLoad = 1 in
   defm TABLE_GET_#rt : I<(outs rt:$res), (ins table32_op:$table),

tlively wrote:
> wingo wrote:
> > I think you may need `hasSideEffects = 0` for these annotations to have an 
> > effect.
> I would be surprised if this were true!
Why would this be the case? If I remember correctly, I added `mayLoad` and 
`mayStore` here so that lowering includes a chain. And this works without the 
need for `hasSideEffects`. Unless you think this is required for other reaons, 
but `mayLoad` works with it.



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:19
  [],
  "table.get\t$res, $table",
  "table.get\t$table",

tlively wrote:
> wingo wrote:
> > Not something for this patch, but this is certainly bogus: surely we mean 
> > `table.get\t$table, $i` and we have an i32 index argument?
> Agree about the i32 index argument, but it is correct to have the result as 
> part of the string for the register-based output format.
Not sure I understand why this should be `$i` instead of `$table`. Isn't 
`$table` represented as an index anyway? A `table32_op` is defined as 
`Operand` so I don't quite understand what we gain by changing this.



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp:129
+TT.isArch64Bit()
+? (hasReferenceTypes(FS)
+   ? "e-m:e-p:64:64-i64:64-n32:64-S128-ni:1:3"

tlively wrote:
> This check should incorporate the CPU as well using `getSubtargetImpl(CPU, 
> FS)->hasReferenceTypes()`.
What exactly do you mean here? Not sure what is the difference here. You mean 
adding something like : `hasReferenceTypes(FS) || 

[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-05 Thread Thomas Lively via Phabricator via cfe-commits
tlively added inline comments.



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:15
 multiclass TABLE {
+  let mayLoad = 1 in
   defm TABLE_GET_#rt : I<(outs rt:$res), (ins table32_op:$table),

wingo wrote:
> I think you may need `hasSideEffects = 0` for these annotations to have an 
> effect.
I would be surprised if this were true!



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:19
  [],
  "table.get\t$res, $table",
  "table.get\t$table",

wingo wrote:
> Not something for this patch, but this is certainly bogus: surely we mean 
> `table.get\t$table, $i` and we have an i32 index argument?
Agree about the i32 index argument, but it is correct to have the result as 
part of the string for the register-based output format.



Comment at: llvm/test/CodeGen/WebAssembly/externref-globalget.ll:4
+%extern = type opaque
+%externref = type %extern addrspace(1)* ;; addrspace 1 is nonintegral
+

wingo wrote:
> tlively wrote:
> > wingo wrote:
> > > A design document for how this works would really be helpful :)  So LLVM 
> > > is going to consider that any pointer to address space 1 has MVT 
> > > exterrnref at lowering-time?  It's interesting to go down this route 
> > > rather than adding a new `llvm::Type`.
> > We essentially consider changes to LLVM IR to be out of scope to the extent 
> > possible. If we only touch code in the WebAssembly backend and maybe fix a 
> > few bugs in target independent code, then we are comfortable signing off on 
> > patches within the team, but if we do anything non-trivial in target 
> > independent code, we need sign off from the wider LLVM community. Changes 
> > to LLVM IR would require a full-blown RFC process and I expect they would 
> > not be accepted.
> I guess my open question is really as regards the C mapping -- would the idea 
> be for the front-end to also specially recognize pointers in address space 1 
> ?  If there were a first-class IR type for these values, as is the case for 
> SVE, you'd have a straightforward answer.  More discussion in 
> https://docs.google.com/document/d/1aVX0tQChxA2Tlno2KmEUjdruLoNgpwzV5Kv335HvNmI/edit#heading=h.u50o9qhzzjy6.
I forget if we had or resolved this conversation elsewhere already, but I would 
expect clang to emit pointers in the correct address spaces, yes. The SVE folks 
had to go though multiple years of effort to add scalable vectors to LLVM IR 
because there was no existing way to model their semantics in IR such that they 
could implement all the vectorization optimizations they wanted. We are lucky 
that we can get away with using address space pointers directly without having 
to add new types to the IR.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-04 Thread Andy Wingo via Phabricator via cfe-commits
wingo added inline comments.



Comment at: clang/lib/Basic/Targets/WebAssembly.h:150
   : WebAssemblyTargetInfo(T, Opts) {
-resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128");
+resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128-ni:1");
   }

This change is already in D101608; rebase?



Comment at: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:4083
   EVT PtrVT = Ptr.getValueType();
+  EVT EltVT = PtrVT.getScalarType();
 

It turns out that all the changes here to `visitLoad` and `visitStore` are no 
longer needed.  The issue was that before we made `getPointerMemTy` virtual, it 
was hard-coded to return an integer of whatever the pointer bit size was.  But 
for externref and funcref values, where we're using pointers in non-default 
address spaces to represent opaque values, that's not what we want: an 
externref "in memory" isn't an i32.  Having made `getPointerMemTy` virtual and 
returning externref / funcref for those values, now we avoid the zero-extension 
paths, and even the ISD::ADD node doesn't cause us problems.



Comment at: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:4257
+// Skip ZExt or Trunc if a ValueVT is zero sized
+if (!ValueVTs[i].isZeroSized() && MemVTs[i] != ValueVTs[i])
   Val = DAG.getPtrExtOrTrunc(Val, dl, MemVTs[i]);

Can revert this too, as mentioned above.



Comment at: llvm/lib/CodeGen/TargetLoweringBase.cpp:1684
   Type *Ty = VT.getTypeForEVT(Context);
-  if (Alignment >= DL.getABITypeAlign(Ty)) {
+  if (!VT.isZeroSized() && Alignment >= DL.getABITypeAlign(Ty)) {
 // Assume that an access that meets the ABI-specified alignment is fast.

This one I would think that we want to return true, that the access is "fast", 
for access to zero-sized types.



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp:2347
+  return false;
+}

I just checked and it would seem that the `getPointerMemTy` change means that 
this override no longer appears to be needed.



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:15
 multiclass TABLE {
+  let mayLoad = 1 in
   defm TABLE_GET_#rt : I<(outs rt:$res), (ins table32_op:$table),

I think you may need `hasSideEffects = 0` for these annotations to have an 
effect.



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:19
  [],
  "table.get\t$res, $table",
  "table.get\t$table",

Not something for this patch, but this is certainly bogus: surely we mean 
`table.get\t$table, $i` and we have an i32 index argument?



Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:59
+  (TABLE_SET_EXTERNREF i32:$table, i32:$idx, externref:$r)>,
+  Requires<[HasReferenceTypes]>;
+

Consider changing to use the approach used for `GLOBAL_GET` from the parent 
commit, and folding these into the multiclass so that we don't have to repeat 
the code for externref and funcref.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

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


[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-04 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 342729.
pmatos added a comment.

Removed extraneous changes to previous patches


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

Files:
  clang/lib/Basic/Targets/WebAssembly.cpp
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/CodeGen/ValueTypes.h
  llvm/include/llvm/Support/MachineValueType.h
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/MachineOperand.cpp
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/TargetLoweringBase.cpp
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISD.def
  llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
  llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/test/CodeGen/WebAssembly/externref-globalget.ll
  llvm/test/CodeGen/WebAssembly/externref-globalset.ll
  llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll
  llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll
  llvm/test/CodeGen/WebAssembly/externref-undef.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
  llvm/test/CodeGen/WebAssembly/funcref-call.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalset.ll

Index: llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define void @set_funcref_global(%funcref %g) {
+  ;; this generates a global.set of @funcref_global
+  store %funcref %g, %funcref addrspace(1)* @funcref_global
+  ret void
+}
+
+; CHECK-LABEL: set_funcref_global:
+; CHECK-NEXT: functype   set_funcref_global (funcref) -> ()
+; CHECK-NEXT: local.get  0
+; CHECK-NEXT: global.set funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define %funcref @return_funcref_global() {
+  ;; this generates a global.get of @funcref_global
+  %ref = load %funcref, %funcref addrspace(1)* @funcref_global
+  ret %funcref %ref
+}
+
+; CHECK-LABEL: return_funcref_global:
+; CHECK-NEXT: .functype   return_funcref_global () -> (funcref)
+; CHECK-NEXT: global.get funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-call.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-call.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type void ()
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+define void @call_funcref(%funcref %ref) {
+  call addrspace(20) void %ref() 
+  ret void
+}
+
+; CHECK-LABEL: call_funcref:
+; CHECK-NEXT: functype   call_funcref (funcref) -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: call_indirect __funcref_call_table, () -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: ref.null func
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: end_function
+
+; CHECK: .tabletype __funcref_call_table, funcref
Index: llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
@@ -0,0 +1,11 @@
+; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+
+%extern = type opaque
+%externref = type %extern addrspace(10)*
+

[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-04 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 342718.
pmatos added a comment.

Fix broken merge of table ins reordering commit


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

Files:
  clang/lib/Basic/Targets/WebAssembly.cpp
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/CodeGen/ValueTypes.h
  llvm/include/llvm/Support/MachineValueType.h
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/MachineOperand.cpp
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/TargetLoweringBase.cpp
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISD.def
  llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
  llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/test/CodeGen/WebAssembly/externref-globalget.ll
  llvm/test/CodeGen/WebAssembly/externref-globalset.ll
  llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll
  llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll
  llvm/test/CodeGen/WebAssembly/externref-undef.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
  llvm/test/CodeGen/WebAssembly/funcref-call.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalset.ll

Index: llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define void @set_funcref_global(%funcref %g) {
+  ;; this generates a global.set of @funcref_global
+  store %funcref %g, %funcref addrspace(1)* @funcref_global
+  ret void
+}
+
+; CHECK-LABEL: set_funcref_global:
+; CHECK-NEXT: functype   set_funcref_global (funcref) -> ()
+; CHECK-NEXT: local.get  0
+; CHECK-NEXT: global.set funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define %funcref @return_funcref_global() {
+  ;; this generates a global.get of @funcref_global
+  %ref = load %funcref, %funcref addrspace(1)* @funcref_global
+  ret %funcref %ref
+}
+
+; CHECK-LABEL: return_funcref_global:
+; CHECK-NEXT: .functype   return_funcref_global () -> (funcref)
+; CHECK-NEXT: global.get funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-call.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-call.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type void ()
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+define void @call_funcref(%funcref %ref) {
+  call addrspace(20) void %ref() 
+  ret void
+}
+
+; CHECK-LABEL: call_funcref:
+; CHECK-NEXT: functype   call_funcref (funcref) -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: call_indirect __funcref_call_table, () -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: ref.null func
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: end_function
+
+; CHECK: .tabletype __funcref_call_table, funcref
Index: llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
@@ -0,0 +1,11 @@
+; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+
+%extern = type opaque
+%externref = type %extern addrspace(10)*
+

[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-04 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 342712.
pmatos added a comment.

Fix patch set... again!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

Files:
  clang/lib/Basic/Targets/WebAssembly.cpp
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/CodeGen/ValueTypes.h
  llvm/include/llvm/Support/MachineValueType.h
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/MachineOperand.cpp
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/TargetLoweringBase.cpp
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISD.def
  llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
  llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/test/CodeGen/WebAssembly/externref-globalget.ll
  llvm/test/CodeGen/WebAssembly/externref-globalset.ll
  llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll
  llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll
  llvm/test/CodeGen/WebAssembly/externref-undef.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
  llvm/test/CodeGen/WebAssembly/funcref-call.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalset.ll

Index: llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define void @set_funcref_global(%funcref %g) {
+  ;; this generates a global.set of @funcref_global
+  store %funcref %g, %funcref addrspace(1)* @funcref_global
+  ret void
+}
+
+; CHECK-LABEL: set_funcref_global:
+; CHECK-NEXT: functype   set_funcref_global (funcref) -> ()
+; CHECK-NEXT: local.get  0
+; CHECK-NEXT: global.set funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type opaque
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+@funcref_global = local_unnamed_addr addrspace(1) global %funcref undef
+
+define %funcref @return_funcref_global() {
+  ;; this generates a global.get of @funcref_global
+  %ref = load %funcref, %funcref addrspace(1)* @funcref_global
+  ret %funcref %ref
+}
+
+; CHECK-LABEL: return_funcref_global:
+; CHECK-NEXT: .functype   return_funcref_global () -> (funcref)
+; CHECK-NEXT: global.get funcref_global
+; CHECK-NEXT: end_function
+
+; CHECK: .globl funcref_global
Index: llvm/test/CodeGen/WebAssembly/funcref-call.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/funcref-call.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
+
+%func = type void ()
+%funcref = type %func addrspace(20)* ;; addrspace 20 is nonintegral
+
+define void @call_funcref(%funcref %ref) {
+  call addrspace(20) void %ref() 
+  ret void
+}
+
+; CHECK-LABEL: call_funcref:
+; CHECK-NEXT: functype   call_funcref (funcref) -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: call_indirect __funcref_call_table, () -> ()
+; CHECK-NEXT: i32.const 0
+; CHECK-NEXT: ref.null func
+; CHECK-NEXT: table.set __funcref_call_table
+; CHECK-NEXT: end_function
+
+; CHECK: .tabletype __funcref_call_table, funcref
Index: llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
@@ -0,0 +1,11 @@
+; RUN: not llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+
+%extern = type opaque
+%externref = type %extern addrspace(10)*
+
+define void 

[PATCH] D95425: Implementation of global.get/set for reftypes in LLVM IR

2021-05-04 Thread Paulo Matos via Phabricator via cfe-commits
pmatos updated this revision to Diff 342708.
pmatos added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Fix patch submitted to phab...


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95425

Files:
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/lib/Basic/Targets/WebAssembly.h
  clang/test/CodeGen/target-data.c
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/CodeGen/ValueTypes.h
  llvm/include/llvm/Support/MachineValueType.h
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/MachineOperand.cpp
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/TargetLoweringBase.cpp
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
  llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
  llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISD.def
  llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
  llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
  llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/test/CodeGen/WebAssembly/externref-globalget.ll
  llvm/test/CodeGen/WebAssembly/externref-globalset.ll
  llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll
  llvm/test/CodeGen/WebAssembly/externref-ptrtoint.ll
  llvm/test/CodeGen/WebAssembly/externref-undef.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-load.ll
  llvm/test/CodeGen/WebAssembly/externref-unsized-store.ll
  llvm/test/CodeGen/WebAssembly/funcref-call.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalget.ll
  llvm/test/CodeGen/WebAssembly/funcref-globalset.ll
  llvm/test/CodeGen/WebAssembly/global-get.ll
  llvm/test/CodeGen/WebAssembly/global-set.ll

Index: llvm/test/CodeGen/WebAssembly/global-set.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/global-set.ll
@@ -0,0 +1,57 @@
+; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false < %s | FileCheck %s
+
+@i32_global = local_unnamed_addr addrspace(1) global i32 undef
+@i64_global = local_unnamed_addr addrspace(1) global i64 undef
+@f32_global = local_unnamed_addr addrspace(1) global float undef
+@f64_global = local_unnamed_addr addrspace(1) global double undef
+
+define void @set_i32_global(i32 %v) {
+; CHECK-LABEL: set_i32_global:
+; CHECK-NEXT: functype   set_i32_global (i32) -> ()
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: global.set i32_global
+; CHECK-NEXT: end_function
+  store i32 %v, i32 addrspace(1)* @i32_global
+  ret void
+}
+
+define void @set_i64_global(i64 %v) {
+; CHECK-LABEL: set_i64_global:
+; CHECK-NEXT: functype   set_i64_global (i64) -> ()
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: global.set i64_global
+; CHECK-NEXT: end_function
+  store i64 %v, i64 addrspace(1)* @i64_global
+  ret void
+}
+
+define void @set_f32_global(float %v) {
+; CHECK-LABEL: set_f32_global:
+; CHECK-NEXT: functype   set_f32_global (f32) -> ()
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: global.set f32_global
+; CHECK-NEXT: end_function
+  store float %v, float addrspace(1)* @f32_global
+  ret void
+}
+
+define void @set_f64_global(double %v) {
+; CHECK-LABEL: set_f64_global:
+; CHECK-NEXT: functype   set_f64_global (f64) -> ()
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: global.set f64_global
+; CHECK-NEXT: end_function
+  store double %v, double addrspace(1)* @f64_global
+  ret void
+}
+
+;; LLVM doesn't yet declare proper WebAssembly globals for these values,
+;; instead placing them in linear memory.  To fix in a followup.
+; FIXME-CHECK: .globl i32_global
+; FIXME-CHECK: .globaltype i32_global, i32
+; FIXME-CHECK: .globl i64_global
+; FIXME-CHECK: .globaltype i64_global, i64
+; FIXME-CHECK: .globl f32_global
+; FIXME-CHECK: .globaltype f32_global, f32
+; FIXME-CHECK: .globl f64_global
+; FIXME-CHECK: .globaltype f64_global, f64
Index: llvm/test/CodeGen/WebAssembly/global-get.ll
===
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/global-get.ll
@@ -0,0 +1,54 @@
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false | FileCheck %s
+
+@i32_global = local_unnamed_addr addrspace(1) global i32 undef
+@i64_global = local_unnamed_addr addrspace(1) global i64 undef
+@f32_global = local_unnamed_addr addrspace(1) global float undef
+@f64_global = local_unnamed_addr addrspace(1) global double undef
+
+define i32 @return_i32_global() {
+; CHECK-LABEL: return_i32_global:
+; CHECK-NEXT: functype   return_i32_global () -> (i32)
+; CHECK-NEXT: global.get i32_global
+; CHECK-NEXT: end_function
+  %v = load i32, i32