This is an archive of the discontinued LLVM Phabricator instance.

[SVE][CodeGen] Lower floating point -> integer conversions
ClosedPublic

Authored by kmclaughlin on Sep 7 2020, 6:44 AM.

Details

Summary

This patch adds new ISD nodes, FCVTZS_MERGE_PASSTHRU &
FCVTZU_MERGE_PASSTHRU, which are used to lower the
following intrinsics:

  • llvm.aarch64.sve.fcvtzu
  • llvm.aarch64.sve.fcvtzs

Diff Detail

Event Timeline

kmclaughlin created this revision.Sep 7 2020, 6:44 AM
Herald added a project: Restricted Project. · View Herald Transcript
paulwalker-arm added inline comments.Sep 7 2020, 6:55 AM
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
12347–12349

This doesn't look correct. You are dropping the passthru value (i.e. Operand(1)) and always using UNDEF instead. It's a bit troubling that such a change hasn't broken any of the lit tests.

I think you'll want to treat these like the other unary operations, which have matching _MERGE_PASSTHRU ISD nodes rather than _PRED ones.

kmclaughlin edited the summary of this revision. (Show Details)
  • Renamed ISD nodes to FP_TO_[S|U]INT_MERGE_PASSTHRU
  • Lower only the llvm.aarch64.sve.fcvtz[u|s] intrinsics to these nodes and not those with a type suffix (e.g. llvm.aarch64.sve.fcvtzs.i32f64)
  • Removed combineSVEConversionFP() and added the new nodes to the list in isMergePassthruOpcode()
efriedma added inline comments.Sep 10 2020, 12:17 PM
llvm/lib/Target/AArch64/AArch64ISelLowering.h
84

Probably should be named FP_TO_UINT_SAT_MERGE_PASSTHRU or something like that, if you're going to use it to lower llvm.aarch64.sve.fcvtzu. (See D54749)

llvm/lib/Target/AArch64/AArch64ISelLowering.h
84

I had a feeling you might say this. The problem is this is more than a rename because the SAT nodes take an additional parameter. This is not really a hurdle but there's a question as to where you draw the line. All the intrinsics expect to produce results that match the instructions on which they're based. This would suggest we can never use names based on similar ISD nodes because the common nodes do not define all corner cases. This seems like overkill considering the _PRED/_MERGE nodes are all under the AArch64ISD namespace, which to me suggests they follow AArch64 semantics.

efriedma added inline comments.Sep 10 2020, 1:39 PM
llvm/lib/Target/AArch64/AArch64ISelLowering.h
84

I think if there's some significant functionality difference, we should call it out in the name somehow. There's a very high likelihood that these nodes, or something like them, will eventually become target-independent. And even before that, people will likely assume they're equivalent based on the name. I don't want something to subtly break because someone didn't realize there was a difference. (It's particularly terrible in cases like fp->int conversions and shifts: if you confuse them, the result appears to mostly work, but you'll get a bug report years later.)

If you're not comfortable naming FP_TO_UINT_SAT_MERGE_PASSTHRU without the matching width parameter, we could just call it FCVTZU_MERGE_PASSTHRU .

paulwalker-arm added inline comments.Sep 10 2020, 2:41 PM
llvm/lib/Target/AArch64/AArch64ISelLowering.h
84

Yes I much prefer that naming strategy. Given this change I guess there are other nodes that should be renamed.

kmclaughlin edited the summary of this revision. (Show Details)
  • Renamed ISD nodes to FCVTZ[S|U]_MERGE_PASSTHRU
  • Renamed AArch64fcvtz[s|u]_p to AArch64fcvtz[s|u]_mt & moved their definitions to the block containing other _mt nodes in AArch64SVEInstrInfo.td
efriedma added inline comments.Sep 11 2020, 4:18 PM
llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
562 ↗(On Diff #291248)

Why is isScalableVector() relevant here?

  • Removed isScalableVector() check from PromoteIntRes_FP_TO_XINT
  • Updated fptoui tests where the result type is promoted to check for fcvtzu
llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
562 ↗(On Diff #291248)

It's not really relevant here, when I first created the patch I thought that it was better not to replace FP_TO_UINT with FP_TO_SINT when promoting the result, but I think it's fine to do this for scalable types also.
I've removed the isScalableVector() from here and updated the affected tests (e.g. nxv2f64 -> nxv2i32) to check for fcvtzs.

paulwalker-arm accepted this revision.Sep 16 2020, 8:27 AM

LGTM assuming adding the missing tests don't throw up anything unexpected.

llvm/test/CodeGen/AArch64/sve-fcvt.ll
22

Perhaps worth adding tests for:
fcvtz[s,u]_h_nxv2f32
fcvtz[s,u]_h_nxv2f64
fcvtz[s,u]_h_nxv4f32

127

I know it's in the langref but it cannot hurt to add a comment here along the lines of NOTE: Using fcvtzs is safe because fptoui overflow is considered poison and a 64bit signed value encompasses the entire range of a 16bit unsigned value. What do you think?

This revision is now accepted and ready to land.Sep 16 2020, 8:27 AM

Oh and the commit message should reference the lowering of FP_TO_SINT/FP_TO_UINT.

efriedma accepted this revision.Sep 16 2020, 4:05 PM
This revision was automatically updated to reflect the committed changes.
kmclaughlin marked an inline comment as done.
kmclaughlin added inline comments.Sep 17 2020, 6:06 AM
llvm/test/CodeGen/AArch64/sve-fcvt.ll
127

I've added your comment in here, it will definitely help me to remember why this is safe in future :)