Previously, tblgen would reject patterns where one of its nested
instructions produced more than one result. These arise when the
instruction definition contains 'outs' as well as 'Defs'. This patch
fixes that by always taking the first result, which is how these
situations are handled in SelectionIDAG.
Details
Diff Detail
Event Timeline
It seems that patch does not handle cases of nested instructions, which is the case in our target where this fix is needed.
I've added a testcase now, as requested.
I mostly see this as making the behavior more opaque by changing based on the specific register classes involved, so I'm not in favor. What do others think?
I'm not yet familiar enough with instruction selection, so I'll leave the decision to others.
Reverse ping!
This is definitely useful for enabling more AMDGPU patterns to be imported.
@arsenm wrote:
I mostly see this as making the behavior more opaque by changing based on the specific register classes involved, so I'm not in favor.
I don't understand this objection. How does it depend on specific register classes? How is this patch morally different from ee3feef5aaaa which did the same thing at the top level of a pattern?
Summary:
situations are handled in SelectionIDAG.
Typo "SelectionDAG"
llvm/utils/TableGen/GlobalISelEmitter.cpp | ||
---|---|---|
301 | Typo "SelectionDAG" |
@foad : Just for info, unfortunately @ehjogab had to move on to another project (after having spent some time on migrating our downstream target to support GlobalISel).
I do not exactly remember the details about this particular patch (but it is included in our downstream branch). Anyway, I'd be happy to commandeer this patch and fix things such as the typo, if the solution can be accepted.
Long term I assume we should just have MIR patterns working for ISel, but as long as we rely on DAG patterns I believe this is a good change (we inevitably need to make some tradeoffs in this case anyway), can we land it or are there still some objections?
Long term I assume we should just have MIR patterns working for ISel, but as long as we rely on DAG patterns I believe this is a good change (we inevitably need to make some tradeoffs in this case anyway), can we land it or are there still some objections?
As far as I'm concerned, this is a reasonable default behavior, though we should probably emit a "warning" when the tablegen debug output is ON.
That said, @arsenm had objections, let's check with him.
Rebased.
Fixed spelling errors.
Moved the new test case into test/TableGen/GlobalISelEmitter-multiple-output.td instead of adding a new test/TableGen/GlobalISelEmitter-multi-output.td file as in earlier diff.
llvm/test/TableGen/GlobalISelEmitter-multiple-output.td | ||
---|---|---|
94 | If we change this into an instruction with two explicit outs it would still pass. I guess the intent with this patch was to handle the case with implicit defs. But then we still want it to fail when having multiple explicit outs. |
llvm/test/TableGen/GlobalISelEmitter-multiple-output.td | ||
---|---|---|
94 | Maybe we can do something like this to check the number of explicit defs: -static Expected<LLTCodeGen> getInstResultType(const TreePatternNode *Dst) { +static Expected<LLTCodeGen> getInstResultType(const TreePatternNode *Dst, + const CodeGenTarget &Target) { + assert(Dst->getOperator()->isSubClassOf("Instruction")); + CodeGenInstruction &InstInfo = Target.getInstruction(Dst->getOperator()); + + if (InstInfo.Operands.NumDefs != 1) + return failedImport("Dst pattern child is not having single result"); + ArrayRef<TypeSetByHwMode> ChildTypes = Dst->getExtTypes(); I'll continue experimenting with that a bit before updating this patch. |
Ping (again).
@Pierre-vh / @foad , can you perhaps have a look from the AMDGPU perspective? It sounded like you weren't against this earlier but now after my latest changes it also show the impact on AMDGPU lit tests.
It also sounded earlier that @qcolombet wasn't against this (but wanted to let @arsenm to chime in due to earlier objections). But that was over 2 months ago and still no comments, so I'd be happy if anyone from AMD could have a look.
@Pierre-vh / @foad , can you perhaps have a look from the AMDGPU perspective? It sounded like you weren't against this earlier but now after my latest changes it also show the impact on AMDGPU lit tests.
So the test diffs are due to some things being selected with newly imported tablegen patterns, instead of with C++ selection code? It's not clear to me exactly which patterns are now being imported.
Anyway the diffs look OK but I think we would want to follow up by seeing if we can improve some of the patterns, and/or remove some redundant C++.
llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-zext.mir | ||
---|---|---|
109 | Using S_BFE_U64 seems better here. Perhaps we can regain that by writing a better pattern. |
I guess one can run llvm-tblgen -gen-global-isel -warn-on-skipped-patterns lib/Target/AMDGPU/AMDGPU.td -I include/ -I lib/Target/AMDGPU/ with and without this patch to compare warning about patterns that can not be imported.
Such a comparison shows the following diffs regarding skipped patterns:
< lib/Target/AMDGPU/SOPInstructions.td:1587:1: warning: Skipped pattern: Dst pattern child has multiple results < lib/Target/AMDGPU/SOPInstructions.td:1689:1: warning: Skipped pattern: Dst pattern child has multiple results < lib/Target/AMDGPU/SOPInstructions.td:1696:1: warning: Skipped pattern: Dst pattern child has multiple results < lib/Target/AMDGPU/SIInstructions.td:1752:1: warning: Skipped pattern: Dst pattern child has multiple results > lib/Target/AMDGPU/SIInstructions.td:1752:1: warning: Skipped pattern: EXTRACT_SUBREG child #0 could not be coerced to a register class < lib/Target/AMDGPU/SIInstructions.td:1763:1: warning: Skipped pattern: Dst pattern child has multiple results > lib/Target/AMDGPU/SIInstructions.td:1763:1: warning: Skipped pattern: EXTRACT_SUBREG child #0 could not be coerced to a register class < lib/Target/AMDGPU/SIInstructions.td:1774:1: warning: Skipped pattern: Dst pattern child has multiple results > lib/Target/AMDGPU/SIInstructions.td:1774:1: warning: Skipped pattern: EXTRACT_SUBREG child #0 could not be coerced to a register class < lib/Target/AMDGPU/SIInstructions.td:1786:1: warning: Skipped pattern: Dst pattern child has multiple results < lib/Target/AMDGPU/SIInstructions.td:1796:1: warning: Skipped pattern: Dst pattern child has multiple results < lib/Target/AMDGPU/SIInstructions.td:1806:1: warning: Skipped pattern: Dst pattern child has multiple results < lib/Target/AMDGPU/SIInstructions.td:2350:1: warning: Skipped pattern: Dst pattern child has multiple results
Using S_BFE_U64 seems better here. Perhaps we can regain that by writing a better pattern.