-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[TableGen][GISel] Learn to import patterns with physreg defs #120343
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[TableGen][GISel] Learn to import patterns with physreg defs #120343
Conversation
16c07cc to
c565ea4
Compare
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
8f8b945 to
1ca4d60
Compare
|
I'd like some help with "VReg has no regclass after selection" issue, I'm not sure how to fix it.
|
1ca4d60 to
54a0395
Compare
|
I'd expect an arbitrary copy from a physical register to be copied to/from a virtual register with class getMinimalPhysRegClass (or whatever the equivalent is in CodeGenRegisters. getRegClassForRegister?). ConstrainSelectedInstOperands won't work because that just uses the classes from the instruction definition, where generic pseudos like COPY do not have any available register class information. These need manual selection |
That's what I thought, too. It appears that In SelectionDAG, the choice of the class is done by InstrEmitter, and the logic is rather complicated. In the simplest case it just calls
I had to figure it out the hard way :( |
You can find the smallest allocatable class with with getAllocatableClass(getMinimalPhysRegClass()), and there's presumably a CodeGenRegisters equivalent too
No, there should be no need for a runtime or type check. The type based class logic in InstrEmitter is one of the issues with SelectionDAG we're trying to avoid. |
I think this is iterate through getRegisterClass(RegRecord)->getSuperClasses() until you find an allocatable one |
|
I'll give it a try, thanks. |
|
So I tried. The register class containing the register is the only register class containing this register, and it is not allocatable. That is, there are no sub- or super-classes containing this register to iterate over. I seem to need a "cross copy" register class. There is a This may not be a big issue, we could still have a notion of "cross copy" register class at TableGen level, which could be used in cases like this. The current idea is to first try |
Both of the AMDGPU cases look like hacks to me. In particular the SCC_CLASS handling does not do what we would want to do in globalisel. (I should probably try removing this but will likely never get around to it)
Some kind of fallback process makes sense to me. In tablegen getRegClassToRegister, find an allocatable superclass, and if one isn't available just find something you can copy to. The allocation processes later can adjust the exact classes anyway,= |
54a0395 to
5d3e267
Compare
|
CC @e-kud |
| def SCC_CLASS : SIRegisterClass<"AMDGPU", [i1], 1, (add SCC)> { | ||
| let CopyCost = -1; | ||
| let isAllocatable = 0; | ||
| let CrossCopyRegClass = SReg_32_XM0_XEXEC; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if this is correct. The class is the one returned by getCrossCopyRegClass in Wave32 case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this should use one of the flavors of SReg_32. SReg_32 itself should be fine
|
@arsenm Could you take a look at the failing test? |
0f169db to
f99334d
Compare
Not in GlobalISel. SIFixSGPRCopies is a giant hack for the DAG, half the reason we want globalisel is to delete it. It's probably a regbankselect bug
What was the pre-select MIR? |
| def SCC_CLASS : SIRegisterClass<"AMDGPU", [i1], 1, (add SCC)> { | ||
| let CopyCost = -1; | ||
| let isAllocatable = 0; | ||
| let CrossCopyRegClass = SReg_32_XM0_XEXEC; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this should use one of the flavors of SReg_32. SReg_32 itself should be fine
| // value means copying is extremely expensive or impossible. | ||
| int CopyCost = 1; | ||
|
|
||
| RegisterClass CrossCopyRegClass = ?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs documentation. Also this doesn't seem like the right terminology. It's more of a virtual register class to use for copies with an unallocatable physical register, not a general cross copy. Maybe AllocatableRegClass?
Before regbank-select: Before instruction-select: |
This change reduces the number of skipped patterns as follows:
It appears that some patterns were already importable, but the generated code was invalid (the result was discarded).
This used to happen with "standalone" patterns in which the source DAG has more results that the destination DAG, and the destination DAG's root instruction has implicit defs. The most common case is that the source DAG produces one result and the root instruction has no explicit defs (e.g.,
setccpatterns).This doesn't error out because we assume that
PatternToMatch::getDstRegs()returns non-empty set if any physical register defs are involved (and issue an error if this is the case), but the set is always empty for standalone patterns.While this patch correctly imports patterns with implicit defs, backends don't seem to be prepared to deal with them.
If, for example, the result of a generic instruction is copied into a physical register, we may end up with something like this:
The issue with this code is summarized here. In short, we are not constraining
%vregto a proper register class, which causes verification failure "VReg has no regclass after selection".This can be observed on
X86/GlobalISel/mul-scalar.lltest, which I "fixed" by disabling importing the pattern.