This is an archive of the discontinued LLVM Phabricator instance.

Implementation of global.get/set for reftypes in LLVM IR
ClosedPublic

Authored by pmatos on Jan 26 2021, 12:50 AM.

Details

Summary

This change implements new DAG notes GLOBAL_GET/GLOBAL_SET, and
lowering methods for load and stores of reference types from IR
globals. Once the lowering creates the new nodes, tablegen pattern
matches those and converts them to Wasm global.get/set.

Diff Detail

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
pmatos updated this revision to Diff 319273.Jan 26 2021, 5:20 AM

Fix getLegalType for simple MVTs

pmatos updated this revision to Diff 320521.Feb 1 2021, 10:41 AM

Attempt to specify externref as a pointer type with a fixed size of 32, instead of opaque.

This doesn't work properly yet as visitLoad fails to getConstant for an externref because externref is not an integer - as in the MVT::externref is not defined as an integer externref.

Requires some more investigation and experimentation.

pmatos updated this revision to Diff 331355.Mar 17 2021, 1:25 PM

Complete patch ready for review.

Includes testcases, handles externref and funcrefs.
Also handles lowering of a call of a funcref by lowering to a table.set + call_indirect.

A few data points on the patch. Externrefs live in address space 1 and funcrefs in address space 3. Externref globals live in address space 2 and funcref globals live in address space 4.

On global.set, global.get:

  • The patch creates new nodes for global.get and set. These nodes are create during lowering of loads (generating global.get) and stores (generating global.set).
  • Selection happens through a Pattern that creates the respective GLOBAL_SET/GET_EXTERNREF/FUNCREF.

On lowering of funcref calls:

  • A new node for table set is created. This is created during the call lowering and added to the chain of the call. Later on it's selected through a Pattern and the instruction TABLE_SET_FUNCREF is generated.

On middle end store/load optimizations: LLVM didn't like too much optimizing stores and loads of 0 size, therefore some optimization skipping was put in place so that we don't try to optimize loads and stores when the VT is sizeless.

pmatos updated this revision to Diff 331366.Mar 17 2021, 1:41 PM

Remove commented code that shouldn't be there in the first place.

Why are IR-level changes needed if these are generated during lowering?
Will this play well with typeless pointers?

Why are IR-level changes needed if these are generated during lowering?
Will this play well with typeless pointers?

Are you talking here about the changes in Codegen/? Many of the load/store optimizations expect a size for the pointee and when there's none LLVM crashes. All of the changes here is to skip optimizations that wouldn't work on sizeless pointees. I haven't tested this on typeless pointers, but I can say that only the size is checked therefore unless the typeless pointers point to a sizeless pointee, then nothing should change.

wingo added a comment.Mar 19 2021, 2:45 AM

Really neat patch, glad to finally see codegen for externref!!! Comments are a bunch of nits / questions, really -- I am not an LLVM expert so please take them with a salt lick.

llvm/include/llvm/CodeGen/ValueTypes.h
213–215

Should this return false when isZeroSized() ?

llvm/lib/CodeGen/MachineOperand.cpp
1166–1167

Perhaps add isZeroSized predicate here, for readability.

Generally speaking, it might be nice to add assert(!isZeroSized()) to the implementation of all relevant getSize() methods, just to make sure you (and future developers) are alerted when they fail to explicitly handle the externref case.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
4105 ↗(On Diff #331366)

isZeroSized. or !hasSize ? Dunno.

4118 ↗(On Diff #331366)

Comments like this make me think there is a property that we're currently calling "zero sized" but which probably has a better name. Anyway just a thought.

llvm/lib/IR/LLVMContextImpl.cpp
35 ↗(On Diff #331366)

Probably something we don't want clang-format to do?

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
1358

Symbolic names for address spaces needed here and below

1386

What is an externref store? A store of an externref value?

2383

What is this?

2394

What does alignment mean in the context of reference types? We can't spill them to the stack. Are you just specifying a least common denominator here? Comment needed in any case.

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
48

Need a big comment somewhere describing the relationship between address spaces and reftypes. Use symbolic names instead of 1 and 3 ?

llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
110 ↗(On Diff #331366)

This would not be the case for the call_ref table, right? Rather it would have fixed size 1 and be defined as comdat.

llvm/test/CodeGen/WebAssembly/externref-globalget.ll
5

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.

llvm/test/CodeGen/WebAssembly/funcref-call.ll
18

We should clear the table entry after the call, to prevent hidden GC roots. It's overhead now but I would make it unconditional, in anticipation of call_ref.

Why are IR-level changes needed if these are generated during lowering?
Will this play well with typeless pointers?

Are you talking here about the changes in Codegen/? Many of the load/store optimizations expect a size for the pointee and when there's none LLVM crashes. All of the changes here is to skip optimizations that wouldn't work on sizeless pointees. I haven't tested this on typeless pointers, but I can say that only the size is checked therefore unless the typeless pointers point to a sizeless pointee, then nothing should change.

I think this is referring to the changes in IR/ and Bitcode/ and llvm-c/. I am also surprised that there are changes in those locations. What motivated them?

tlively added inline comments.Mar 19 2021, 10:51 AM
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
1388–1389

This seems a little strange. Why not allow 0? Once we support user-defined tables and not just individual globals, will this need to allow any non-negative offset?

2394

I would also expect Align(1) to make more sense here, since table slot indices do not need to be divisible by any particular alignment.

llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
86–92 ↗(On Diff #331366)

Is this used anywhere?

llvm/test/CodeGen/WebAssembly/externref-globalget.ll
5

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.

llvm/test/CodeGen/WebAssembly/externref-undef.ll
14–15

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.

wingo added inline comments.Mar 22 2021, 1:53 AM
llvm/test/CodeGen/WebAssembly/externref-globalget.ll
5

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.

pmatos added inline comments.Mar 22 2021, 11:33 AM
llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
86–92 ↗(On Diff #331366)

Thanks for pointing this one out - I will remove this.

pmatos updated this revision to Diff 332547.Mar 23 2021, 12:41 AM

Small fixes:

  • Set Align(1) for reference types
  • Remove unused node
  • Make webassembly target description string dependent on feature string (fixes clang tests)
pmatos updated this revision to Diff 332548.Mar 23 2021, 12:44 AM

Reformat patch with clang-format-diff.py

Once again, are the changes to the LLVM IR (LLVMTypeKind & friends) actually needed?
I'm not seeing any usages of that in the tests.

Once again, are the changes to the LLVM IR (LLVMTypeKind & friends) actually needed?
I'm not seeing any usages of that in the tests.

Hi, I was going refer to those in a separate comment. My apologies for the delay.
Those were required to get this to work due to a call in SelectionDAGBuilder.cpp (current like 9966) to VT.getTypeForEVT. This requires me to create a type for the EVT externref and funcref. This forced the change to ValueTypes.cpp. Once you create the Type for externref and funcref the other changes come along either by necessity or to avoid warnings that certain cases were not handled in switches.

pmatos added inline comments.Mar 23 2021, 5:37 AM
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
1386

That should say externref global stores.

llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
110 ↗(On Diff #331366)

I refactored that. Comdat is being set in getOrCreateFuncrefCallTableSymbol

Once again, are the changes to the LLVM IR (LLVMTypeKind & friends) actually needed?
I'm not seeing any usages of that in the tests.

Hi, I was going refer to those in a separate comment. My apologies for the delay.
Those were required to get this to work due to a call in SelectionDAGBuilder.cpp (current like 9966) to VT.getTypeForEVT. This requires me to create a type for the EVT externref and funcref. This forced the change to ValueTypes.cpp. Once you create the Type for externref and funcref the other changes come along either by necessity or to avoid warnings that certain cases were not handled in switches.

It would make sense for VT.getTypeForEVT to return the appropriate address space pointer types that we are lowering to externref and funcref, right?

Once again, are the changes to the LLVM IR (LLVMTypeKind & friends) actually needed?
I'm not seeing any usages of that in the tests.

Hi, I was going refer to those in a separate comment. My apologies for the delay.
Those were required to get this to work due to a call in SelectionDAGBuilder.cpp (current like 9966) to VT.getTypeForEVT. This requires me to create a type for the EVT externref and funcref. This forced the change to ValueTypes.cpp. Once you create the Type for externref and funcref the other changes come along either by necessity or to avoid warnings that certain cases were not handled in switches.

It would make sense for VT.getTypeForEVT to return the appropriate address space pointer types that we are lowering to externref and funcref, right?

Unsure here to be honest because it's not clear to me where this TypeForEVT fits in the optimizations done by LLVM, but I can give it a try to use the type we are loweing to instead of creating a new one specifically for externref and funcref.

pmatos marked 2 inline comments as done.Apr 13 2021, 7:14 AM
pmatos added inline comments.
llvm/include/llvm/CodeGen/ValueTypes.h
213–215

I agree that this should probably return false in that case.

llvm/lib/CodeGen/MachineOperand.cpp
1166–1167

Cannot really use isZeroSized here because this is for MachineMemOperands - we defined isZeroSized for VTs.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
4105 ↗(On Diff #331366)

Sounds like I should have used isZeroSized here.

4118 ↗(On Diff #331366)

but isn't the property really if it's zero sized? we don't want to mention any target dependent property here like reference type, so this feels like the most generic name.

llvm/lib/IR/LLVMContextImpl.cpp
35 ↗(On Diff #331366)

right - wonder how to stop clang-format to not do this.

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
1388–1389

This is for globals, so Offset is undef. I guess once we do tables, we'll need to enable other offsets here.

2383

At some point in an load/store optimization this is called and the default implementation crashes on opaque types, so we need to override this. Although we could use here isZeroSized().

pmatos updated this revision to Diff 337143.Apr 13 2021, 7:26 AM

Clarify many of the issues requested in previous review comments.

pmatos updated this revision to Diff 337379.Apr 14 2021, 2:27 AM

Fix table name for funcref calls

Are there any further comments to this patch before landing?

wingo added inline comments.Apr 19 2021, 2:24 AM
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
1490

Given that this node defines one value, the chain, should this be MVT::other?

sbc100 added inline comments.Apr 19 2021, 9:41 AM
llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
120 ↗(On Diff #337379)

The other names in this file seem to either use UPPER_SNAKE_CASE or CamelCase. Any reason these new one use lower_snake_case?

llvm/test/CodeGen/WebAssembly/externref-inttoptr.ll
12

Missing newline at EOF here and in externref-ptrtoint.ll

I'm still not comfortable approving this patch with changes to llvm-c/, Bitcode/, or IR/. If those changes can't be backed out, this will require an RFC on llvm-dev, but I would be surprised if that were necessary.

I'm still not comfortable approving this patch with changes to llvm-c/, Bitcode/, or IR/. If those changes can't be backed out, this will require an RFC on llvm-dev, but I would be surprised if that were necessary.

I understand - I will look into a workaround to avoid the call of getTypeForEVT I mentioned earlier on.

Apparently getTypeForEVT in LowerArguments is only necessary to call the getABIAlignmentForCallingConv. I was thinking that since reference types really are pointers to different address spaces we could return their TypeForEVT as being int32. That will then return as the alignment for reference types the default alignment for int32. This should help with avoiding us touching middle end code. I will experiment in this direction.

Apparently getTypeForEVT in LowerArguments is only necessary to call the getABIAlignmentForCallingConv. I was thinking that since reference types really are pointers to different address spaces we could return their TypeForEVT as being int32. That will then return as the alignment for reference types the default alignment for int32. This should help with avoiding us touching middle end code. I will experiment in this direction.

Why not return the original pointer to opaque type, i.e. PointerType::get(StructType::create(Context), 1)?

pmatos updated this revision to Diff 340553.Apr 26 2021, 9:14 AM

Use PointerType to avoid defining types for externref and funcref.

pmatos added inline comments.Apr 26 2021, 11:59 PM
llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
120 ↗(On Diff #337379)

@sbc100 I think it's quite mixed in this file at least. In the beginning of the file we have def regPlusImm followed by def or_is_add. These are for PatFrags. I modelled these after @tlively 's SIMD SDTypeProfile that uses: def wasm_load_splat_t for example.

pmatos updated this revision to Diff 340734.Apr 27 2021, 12:03 AM

Take care of some syntax linting/style comments

pmatos updated this revision to Diff 340740.Apr 27 2021, 12:27 AM
pmatos marked an inline comment as done.

Add missing newlines at the end of test files

There are still two things missing:

  1. Clear the table entry after the call_indirect to avoid hidden GC roots as mentioned by @wingo
  2. Understand how to handle a ret %extern undef - comment by @tlively
wingo added inline comments.Apr 27 2021, 12:38 AM
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
69

should be just "if"

1131

Should this be TABLE_SET_FUNCREF and not just TABLE_SET ? Given that we're producing a DAG node that then needs to be selected, I would think the type-specific stuff could happen in the pattern-matching.

1490

Pretty sure this comment still applies

pmatos added inline comments.Apr 27 2021, 12:39 AM
llvm/test/CodeGen/WebAssembly/externref-undef.ll
14–15

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.

pmatos updated this revision to Diff 340750.Apr 27 2021, 1:12 AM

Fix else if and VT type as suggested by @wingo.

pmatos marked 3 inline comments as done.Apr 27 2021, 1:15 AM
pmatos added inline comments.Apr 27 2021, 1:15 AM
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
1131

In this case, I think we cannot generate a TABLE_SET. I think the TABLE_SET you are referring to is the machine instruction defined in the backend which is not matched from here. From here, you can only match the nodes you create and that's WebAssemblyISD::TABLE_SET_FUNCREF. I am still not totally clear why this is, but I never had any luck generating the machine instructions defined in the backend directly from lowering so there might be a way but it's not straightforward. So we generate here the custom machine node we created and then we pattern match that in tablegen to generate the instruction.

1490

Sorry - I missed this. You're right, this should be MVT::Other.

pmatos updated this revision to Diff 340787.Apr 27 2021, 3:59 AM
pmatos marked an inline comment as done.

Make TABLE_SET node polymorphic. Deal with types through the Pats. One for funcref and one for externref.

pmatos added inline comments.Apr 27 2021, 7:41 AM
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
1131

Apologies I misunderstood your comment. We can make the node polymorphic and deal with the types in the Pat Frags. I will do that next.

This is looking really good!

llvm/lib/CodeGen/MachineOperand.cpp
1170

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.

llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
132–134

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?

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
1447

It would be good to mark these helper functions static.

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
59–61

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.

llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
1 ↗(On Diff #340787)

Unintentional whitespace change?

llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
130

This check should incorporate the CPU as well using getSubtargetImpl(CPU, FS)->hasReferenceTypes().

llvm/test/CodeGen/WebAssembly/externref-undef.ll
14–15

Ah, that makes sense.

sbc100 added inline comments.Apr 28 2021, 3:53 PM
llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
132–134

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.

wingo added inline comments.Apr 29 2021, 8:24 AM
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
4114 ↗(On Diff #340787)

Does this path actually fire for you? In my local tests, if you are loading from EXTERNREF_GLOBAL, then the EltVT ends up being i32.

pmatos updated this revision to Diff 342705.May 4 2021, 5:40 AM

Rebase this on D101608 from @wingo and clear table slot after call

pmatos updated this revision to Diff 342708.May 4 2021, 5:58 AM

Fix patch submitted to phab...

Herald added a project: Restricted Project. · View Herald TranscriptMay 4 2021, 5:58 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
pmatos updated this revision to Diff 342712.May 4 2021, 6:11 AM

Fix patch set... again!

pmatos updated this revision to Diff 342718.May 4 2021, 6:55 AM

Fix broken merge of table ins reordering commit

pmatos updated this revision to Diff 342729.May 4 2021, 7:29 AM

Removed extraneous changes to previous patches

wingo added inline comments.May 4 2021, 7:46 AM
clang/lib/Basic/Targets/WebAssembly.h
150 ↗(On Diff #342708)

This change is already in D101608; rebase?

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
4083 ↗(On Diff #342729)

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.

4257 ↗(On Diff #342729)

Can revert this too, as mentioned above.

llvm/lib/CodeGen/TargetLoweringBase.cpp
1709

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

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
2387

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

llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
15

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

19

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?

59

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.

pmatos marked an inline comment as done.May 5 2021, 1:30 AM
tlively added inline comments.May 5 2021, 2:44 PM
llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
15

I would be surprised if this were true!

19

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.

llvm/test/CodeGen/WebAssembly/externref-globalget.ll
5

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.

pmatos marked 7 inline comments as done.May 7 2021, 7:28 AM
pmatos added inline comments.
llvm/lib/CodeGen/MachineOperand.cpp
1170

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

llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
132–134

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.

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
59–61

Current set of patches should have addressed your concerns here.

llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
15

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.

19

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<i32> so I don't quite understand what we gain by changing this.

llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
130

What exactly do you mean here? Not sure what is the difference here. You mean adding something like : hasReferenceTypes(FS) || getSubtargetImpl(CPU, FS)->hasReferenceTypes()?

pmatos updated this revision to Diff 343685.May 7 2021, 8:04 AM
  • Simplifies some of code in the middle-end.
  • Removes setComdat and adds setWeak

Small improvements to address comments in review.

pmatos updated this revision to Diff 343695.May 7 2021, 8:48 AM

Making the linter happy...

wingo added inline comments.May 17 2021, 4:47 AM
llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
15

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.

pmatos updated this revision to Diff 346411.May 19 2021, 5:00 AM

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

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

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

llvm/lib/CodeGen/MachineOperand.cpp
1170

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.

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
558–559

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

llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
19

I would still expect to see a register for the result and immediate inputs for the table symbol and the table slot index here.

llvm/test/CodeGen/WebAssembly/externref-undef.ll
14–15

It would be good to add this explanation as a comment in the test file.

llvm/test/CodeGen/WebAssembly/funcref-call.ll
16

Missing a table element index here.

pmatos added a comment.Jun 1 2021, 8:07 AM

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

pmatos updated this revision to Diff 350599.Jun 8 2021, 7:06 AM

Fix details requested by @tlively in latest comemnts.

pmatos marked 6 inline comments as done.Jun 8 2021, 7:13 AM

Hopefully we are close to landing this. :)

llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
19

Not sure I understood everything properly as the only thing missing was the index in the register based version. I added that now.

llvm/test/CodeGen/WebAssembly/funcref-call.ll
16

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.

tlively accepted this revision.Jun 9 2021, 8:41 PM

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

llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
19

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.

llvm/test/CodeGen/WebAssembly/funcref-call.ll
16

Yep, sorry for the confusion.

This revision is now accepted and ready to land.Jun 9 2021, 8:41 PM
This revision was landed with ongoing or failed builds.Jun 10 2021, 1:08 AM
This revision was automatically updated to reflect the committed changes.
pmatos marked 2 inline comments as done.

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.

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

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

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.