This is an archive of the discontinued LLVM Phabricator instance.

AMDGPU: Don't use 16-bit FP inline constants in integer operands
ClosedPublic

Authored by arsenm on Jun 15 2020, 5:37 AM.

Details

Summary

It seems to be a hardware defect that the half inline constants do not
work as expected for the 16-bit integer operations (the inverse does
work correctly). Experimentation seems to show these are really
reading the 32-bit inline constants, which can be observed by writing
inline asm using op_sel to see what's in the high half of the
constant. Theoretically we could fold the high halves of the 32-bit
constants using op_sel.

The *_asm_all.s MC tests are broken, and I don't know where the script
to autogenerate these are. I started manually fixing it, but there's
just too many cases to fix. This also does break the
assembler/disassembler support for these values, and I'm not sure what
to do about it. These are still valid encodings, so it seems like you
should be able to use them in some way. If you wrote assembly using
them, you could have really meant it (perhaps to read the high bits
with op_sel?). The disassembler will print the invalid literal
constant which will fail to re-assemble. The behavior is also
different depending on the use context. Consider this example, which
was previously accepted and encoded using the inline constant:

    
v_mad_i16 v5, v1, -4.0, v3
; encoding: [0x05,0x00,0xec,0xd1,0x01,0xef,0x0d,0x04]

In contexts where an inline immediate is required (such as on gfx8/9),
this will now be rejected. For gfx10, this will produce the literal
encoding and change the printed format:

v_mad_i16 v5, v1, 0xc400, v3
; encoding: [0x05,0x00,0x5e,0xd7,0x01,0xff,0x0d,0x04,0x00,0xc4,0x00,0x00]

This is just another variation of the issue that we don't perfectly
handle round trip assembly/disassembly due to not tracking how
immediates were encoded. This doesn't matter much in practice, since
compilers don't emit the suboptimal encoding. I doubt any users are
relying on this behavior (although I did make use of the old behavior
to figure out what was wrong).

Fixes bug 46302.

Diff Detail

Event Timeline

arsenm created this revision.Jun 15 2020, 5:37 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 15 2020, 5:37 AM
dp added a comment.Jun 15 2020, 10:47 AM

If this is a HW defect, should not the change be conditional, based on a feature?

Regarding gfx*asm_all - I'll update them myself after the change is integrated.

In D81841#2093296, @dp wrote:

If this is a HW defect, should not the change be conditional, based on a feature?

It's universally broken, so no. If this was theoretically fixed in future hardware, we could add one for working 16-bit integer immediates

Regarding gfx*asm_all - I'll update them myself after the change is integrated.

dp accepted this revision.Jun 16 2020, 6:36 AM

LGTM with minor notes

llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
598

Extra space

llvm/test/MC/AMDGPU/gfx9_asm_all.s
1

You disabled all tests so other changes in this file should probably be reverted.

llvm/test/MC/Disassembler/AMDGPU/literalv216_gfx10.txt
82

This and subsequent changes define special tests which check that disassembler is able to decode invalid instructions. Should they be separated from regular tests? Or have an appropriate comment?

This revision is now accepted and ready to land.Jun 16 2020, 6:36 AM
arsenm closed this revision.Jun 17 2020, 4:15 PM
arsenm marked an inline comment as done.
llvm/test/MC/Disassembler/AMDGPU/literalv216_gfx10.txt
82

I wasn't sure what to do here since we don't have an answer to perfect round trip disassembly