This is an archive of the discontinued LLVM Phabricator instance.

[RFC][GlobalISel] convergence control tokens and intrinsics
Needs ReviewPublic

Authored by sameerds on Aug 16 2023, 11:28 PM.

Details

Summary

This is an early attempt and a call for feedback on adding support in GlobalISel
for convergence control tokens:

  • IRTranslator converts LLVM token type to LLT::token(), which is an alias for the s0 type. These show up as implicit uses on convergent operations.
  • Legalizer removes all implicit uses of convergence control tokens, since they are not meant to be translated to actual target instructions.
  • Machine verifier enforces the static rules of convergence control.

Diff Detail

Event Timeline

sameerds created this revision.Aug 16 2023, 11:28 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 16 2023, 11:28 PM
sameerds requested review of this revision.Aug 16 2023, 11:28 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 16 2023, 11:28 PM
sameerds added a subscriber: Restricted Project.
arsenm added inline comments.Aug 17 2023, 6:36 AM
llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
91

isEntryConvergenceToken

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
212–213

I think you should just bypass this assert, you're creating one special case that doesn't benefit from any of the type logic here

2463

Just directly create the token vreg

arsenm added inline comments.Aug 17 2023, 8:59 AM
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
133

Verifier should reject debug uses of tokens

arsenm added inline comments.Aug 17 2023, 12:34 PM
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
122–140

Wait, why is this here? Generic intrinsics shouldn't reach the legalizer, they should go through G_* instruction wrappers. If your intention was to default legalize to erase, those should be just in the default lower action

arsenm requested changes to this revision.Aug 18 2023, 5:39 AM
This revision now requires changes to proceed.Aug 18 2023, 5:39 AM
sameerds updated this revision to Diff 552221.Aug 21 2023, 10:50 PM
  • rebased
  • addressed some review comments
  • added machine verifier
sameerds marked 2 inline comments as done and 2 inline comments as done.Aug 21 2023, 10:52 PM
sameerds added inline comments.
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
2463

I didn't understand. In the LLVM IR, this is a token use, and the token definition was elsewhere. We still need to find that existing register, right?

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
122–140

I don't understand, mostly because I am quite unfamiliar with the backend. But in GlobalISel.cpp, the legalizer comes before selection. So this definitely hits the legalizer? By "default lower action", you mean somewhere in InstructionSelect::runOnMachineFunction() before it calls the target-specific virtual function InstructionSelector::select()?

133

The verifier (see the new patch) rejects any uses other than a call or an intrinsic.

sameerds edited the summary of this revision. (Show Details)Aug 21 2023, 10:55 PM

Bump! Waiting for more info on comments from @arsenm

arsenm added inline comments.Aug 29 2023, 4:48 AM
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
2463

Yes, you still need to update the map entry. But you don't need to go through the full getOrCreateVregs with all of the type handling

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
122–140

The legalizer shouldn't need to specially intercept intrinsics. A generic intrinsic should not pass the IRTranslator. These should be swapped to new G_* instructions which the ordinary legalizer can express rules. The default lower action for them can be to just erase (or we can let these pass to selection)

sameerds added inline comments.Aug 30 2023, 4:43 AM
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
122–140

The legalizer shouldn't need to specially intercept intrinsics. A generic intrinsic should not pass the IRTranslator.

That is confusing still. Isn't MachineIRBuilder::buildIntrinsic() how LLVM IR intrinsics get translated to G_INTRINSIC instances in GMIR?

These should be swapped to new G_* instructions which the ordinary legalizer can express rules. The default lower action for them can be to just erase (or we can let these pass to selection)

What I am looking for is a place that is common to all targets, where the convergence control intrinsics can be erased just before or during selection. Until that point, the G_INTRINSIC instances of the convergence control intrinsics is how tokens are produced in GMIR. The legalizer is very close to such a point. Why is it that the legalizer can express rules for G_* opcodes but not generic intrinsics?

Separately, I don't think there is value in creating new G_* opcodes for these intrinsics (yet).

sameerds added inline comments.
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
122–140

That is confusing still.

What I am looking for is a place that is common to all targets, where the convergence control intrinsics can be erased just before or during selection. Until that point, the G_INTRINSIC instances of the convergence control intrinsics is how tokens are produced in GMIR. The legalizer is very close to such a point. Why is it that the legalizer can express rules for G_* opcodes but not generic intrinsics?

Never mind! I spent some time looking at how GlobalISel works with help from @cdevadas , and I think I have some idea of what to do with tokens.

llvm/test/CodeGen/AMDGPU/verify-convergencectrl/region-nesting.mir