This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Fix code generated for atomic operations in PIC mode
ClosedPublic

Authored by sbc100 on Dec 6 2020, 9:55 PM.

Details

Summary

The main this this test does is to add the IsNotPIC predicate to the all
the atomic instructions pattern that directly refer to tglobaladdr.

This is because in PIC mode we need to generate seperate instruciton
sequence (either a direct global.get, or __memory_base + offset) for
accessing global addresses.

As part of this change I noticed that many of the Requires attributes
added to the instruction in WebAssemblyInstrAtomics.td were not being
honored. This is because the wrapped in a `let Predicates =
[HasAtomics]` block and it seems that that outer wrapping overrides any
Requires on defs within it. As a workaround I removed the outer
let and added HasAtomics to all the inner Requires. I believe
that all the instrucitons that don't have Requires explcity bottom out
in ATOMIC_I and ATOMIC_NRI which have HasAtomics so this should
not remove this predicate from any patterns (at least that is the idea).

Diff Detail

Event Timeline

sbc100 created this revision.Dec 6 2020, 9:55 PM
sbc100 requested review of this revision.Dec 6 2020, 9:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 6 2020, 9:55 PM
sbc100 added a comment.EditedDec 6 2020, 9:59 PM

The alternative to this approach looks like implementing something
like PredicateControl in Mips.td where we can split the predicates
into groups so they don't clobber each other.

sbc100 updated this revision to Diff 309811.Dec 6 2020, 10:06 PM

add test

aheejin accepted this revision.Dec 7 2020, 11:18 AM

Oh, I see what you mean. LGTM and I don't think we need a more complicated approach at the moment.

This revision is now accepted and ready to land.Dec 7 2020, 11:18 AM
tlively accepted this revision.Dec 7 2020, 12:17 PM

"were being honored" => "were not being honored" in the patch description.

I believe that all the instrucitons that don't have Requires explcity bottom out in ATOMIC_I and ATOMIC_NRI which have HasAtomics so this should not remove this predicate from any patterns (at least that is the idea).

This might run into the issue that Requires don't seem to do anything on instruction definitions, so we need to have it on the Pats. The fix of removing the let Predicates = ... in favor of repeating the predicate for each pattern looks good, though.

sbc100 edited the summary of this revision. (Show Details)Dec 8 2020, 3:07 PM
sbc100 added a comment.Dec 8 2020, 3:14 PM

One side effect is that that defs in this file that use classes from the non-atomic memory file such as LoadPatImmOff and LoadPatImmOff will no longer have the HasAtomics as part of their Requires. Does this seems reasonble?

I think this means that if atomic load/store instructions make is as far as instruction selection in non-atomic build they will success. However in practice they should never get that far because we have the atomics lowering pass that should boil them all away.

This doesn't effect class that are defined in this file such as WaitPatNoOffset, and NotifyPatImmOff since we can add the HasAtomics there.

aheejin added inline comments.Dec 8 2020, 4:23 PM
llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td
232

Good point. Maybe we can restore these for load/store patterns? (This and similar Predicates below) These patterns don't seem to contain PIC related predicates anyway.

sbc100 added inline comments.Dec 8 2020, 5:10 PM
llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td
232

The do contain their own requires. See WebAssemblyInstrMemory.td:

``
multiclass LoadPatImmOff<ValueType ty, PatFrag kind, PatFrag operand,

                       string inst> {                                          
def : Pat<(ty (kind (operand I32:$addr, imm:$off))),                           
          (!cast<NI>(inst # "_A32") 0, imm:$off, I32:$addr)>,                  
      Requires<[HasAddr32]>;                                                   
def : Pat<(ty (kind (operand I64:$addr, imm:$off))),                           
          (!cast<NI>(inst # "_A64") 0, imm:$off, I64:$addr)>,                  
      Requires<[HasAddr64]>;

}

See HasAddr64 and HasAddr32.

This means that we can't wrap the call the uses of this multclass in WebAssemblyInstrAtomics.td in `let Predicates =`.   

So... what I'm proposing here is that we accept that these atomic patterns are available even without the atomics feature.   As I explained I don't think that will actually be a problem in practice because we should have lowered them all away anyway.
sbc100 marked an inline comment as not done.Dec 8 2020, 5:11 PM

Yeah I think that should be fine.

This revision was landed with ongoing or failed builds.Dec 8 2020, 6:49 PM
This revision was automatically updated to reflect the committed changes.