Skip to content

[AMDGPU][AsmParser] Some instructions are indistinguishable to AsmParser #69256

Open
@kosarev

Description

@kosarev

There are instructions in the AMDGPU backend that have identical mnemonics and operands:

$ grep 'BUFFER_ATOMIC_FCMPSWAP_OFFSET_.*gfx10' AMDGPUGenAsmMatcher.inc
  { 460 /* buffer_atomic_fcmpswap */, AMDGPU::BUFFER_ATOMIC_FCMPSWAP_OFFSET_RTN_gfx10, ConvertCustom_cvtMubufAtomic, AMFBS_isGFX6GFX7GFX10Plus_isGFX10Only, { MCK_AV_64, MCK_off, MCK_SReg_128, MCK_SCSrcB32, MCK_Offset, MCK_CPol }, },
  { 460 /* buffer_atomic_fcmpswap */, AMDGPU::BUFFER_ATOMIC_FCMPSWAP_OFFSET_gfx10, ConvertCustom_cvtMubufAtomic, AMFBS_isGFX6GFX7GFX10Plus_isGFX10Only, { MCK_AV_64, MCK_off, MCK_SReg_128, MCK_SCSrcB32, MCK_Offset, MCK_CPol }, },

Note that both the instructions have { MCK_AV_64, MCK_off, MCK_SReg_128, MCK_SCSrcB32, MCK_Offset, MCK_CPol } as their lists of operand kinds. This means that for a set of parsed operands that is suitable for these instructions as determined by calling their corresponding operand class predicates, of these two instructions AsmParser will select the one that is happened to match first. For instructions with identical mnemonics, operands and features the matching order is generally not defined.

Furthermore, where otherwise identical instructions have operands defined in TableGen as having different AsmOperandClasses, the matching order is determined by comparing the names of these AsmOperandClasses:

return ValueName < RHS.ValueName;
Particularly, when both the classes are anonymous, which is often the case in the AMDGPU backend, the matching order will therefore depend on their generated names. Generated names of anonymous TableGen entites have the form anonymous_<n>, where <n> is a number that depends on when during the work of the TableGen's internal machinery this entity was defined relative to other anonymous entities, see RecordKeeper::getNewAnonymousName(). This in turn means that the instruction matching order is generally susceptible to where in .td files used AsmOperandClasses have been defined.

As I side note, we seem to have special code in TableGen that checks specifically for ambiguous matchables (instructions):

DEBUG_WITH_TYPE("ambiguous_instrs", {
However, because different anonymous operand classes are never considered equal, couldMatchAmbiguouslyWith() doesn't flag such cases.

Caught on an attempt to prepare an NFC patch involving adding an anonymous operand class, which led to failures on regression tests.

A subtask of #62629.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions