This is an archive of the discontinued LLVM Phabricator instance.

[AArch64][SVE] Asm: Add parsing/printing support for exact FP immediates.
ClosedPublic

Authored by sdesmalen on Jun 4 2018, 6:21 AM.

Details

Summary

Some instructions require of a limited set of FP immediates as operands,
for example '#0.5 or #1.0' for SVE's FADD instruction.

This patch adds support for parsing and printing such FP immediates as
exact values (e.g. #0.499999 is not accepted for #0.5).

Diff Detail

Repository
rL LLVM

Event Timeline

sdesmalen created this revision.Jun 4 2018, 6:21 AM

Hi, I might be missing something, but why do we need this? Why is this not the same as the already existing "k_FPImm" case (with perhaps an additional check somewhere to see if it is one of these 4 expected values)?

The k_FPImm case works a little different.. Instead of it storing the APFloat value, it stores the (AArch64_AM) encoded FP imm value. If the value cannot be encoded, the parser throws an error. Also not all values can be encoded, such as '0.0', for which the parser (for k_FPImm) puts in a "#0.0" string literal into the parsed operands list. The two cases can be merged, but I think it may be better to do that in a separate patch as this will require some refactoring and changes to match e.g. the #0.0 case in existing FP instructions.

It looks like we currently have two ways in which floating-point operands can get parsed, and this patch adds a third, which accepts values which overlap with both of the existing ones. Instead, this seems like a good time to tidy this up, always parsing to the same AArch64Operand, and using predicate functions to check if the value is valid for each operand type, as we do for integer operands with different ranges.

Hi @olista01 , I just tried merging this change with k_FPImm and one of the problems I'm running into is with the '#0.0' and InstAliases.
For example in SVEInstrFormats.td, class sve_int_dup_imm:

InstAlias<"fmov $Zd, #0.0", (!cast<Instruction>(NAME # _S) ZPR32:$Zd, 0, 0), 1>;

If #0.0 would be an operand of type fpimm0, say fpimm0:$imm, then TableGen tells me the operand needs to be used in the instruction. But not only would we want to pass 0 instead of $imm, the immediate for sve_int_dup_imm is of a completely different type, namely cpy_imm8_opt_lsl_i32. Do you have any suggestions how to solve that?

Also which are the other two ways you mention? (I only know of k_FPImm?)

sdesmalen updated this revision to Diff 150138.Jun 6 2018, 8:05 AM

Merged k_ExactFPImm with k_FPImm.

Thanks, this looks a lot better IMO.

lib/Target/AArch64/AArch64SystemOperands.td
249 ↗(On Diff #150138)

The only thing I am wondering is if we can easily get rid of this of these "half", "one", etc., definitions? This still feels a bit like a few special cases, a bit hacky if you like, that can perhaps be made a bit more generic. I don't have a suggestion yet how though; I would need to spend some more time looking at it.

SjoerdMeijer accepted this revision.Jun 15 2018, 1:47 AM

Looks OK to me.

lib/Target/AArch64/AArch64SystemOperands.td
240 ↗(On Diff #150138)

Nit: I think some comments how and why this is used (for SVE) would be good. I mean, "ExactFPImm" is kind of a generic name, but this is used a lookup table for a few instructions that only accept a few specific immediates.

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
135 ↗(On Diff #150138)

Nit: perpahs a bit more descriptive name, e.g. AddFPZeroAsLiteral, or just AddZeroAsLiteral?

This revision is now accepted and ready to land.Jun 15 2018, 1:47 AM
This revision was automatically updated to reflect the committed changes.
sdesmalen marked 2 inline comments as done.Jun 15 2018, 6:16 AM