This is an archive of the discontinued LLVM Phabricator instance.

[AArch64][GlobalISel] Change G_FCONSTANTs feeding into stores into G_CONSTANTS
ClosedPublic

Authored by paquette on Jan 15 2020, 4:31 PM.

Details

Summary

Given the following situation:

x = G_FCONSTANT (something that can't be materialized)
G_STORE x, some_addr

We know that x must be materialized as at least a single mov. However, at the time of selection, the G_STORE will have been regbankselected to a FPR store.

So, as a result, you'll get an unnecessary fmov into the G_STORE.

Storing a constant value in a GPR and a constant value in a FPR are the same. So, whenever you see a G_FCONSTANT that feeds into only G_STORES, so might as well make it a G_CONSTANT.

This adds a target-specific combine which changes G_FCONSTANTs feeding into G_STOREs into G_CONSTANTs.

Diff Detail

Event Timeline

paquette created this revision.Jan 15 2020, 4:31 PM

Also I have no idea if this is how we want to do target-specific combines, so if there's a better way to do it, I'll take it.

arsenm added a subscriber: arsenm.Jan 15 2020, 5:23 PM
arsenm added inline comments.
llvm/lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp
50

There's no reason to go through getZExtValue, buildConstant accepts the APInt directly

I think in cases where it's possible to use an fmov with immediate:

fmov s0, #fpimm
str s0, [x0]

We should do that over forcing going through GPR. When we go through gpr, there might be fp immediate values which cannot be represented with a single instruction GPR register materialization, instead requiring movk/movz.

When we go through gpr, there might be fp immediate values which cannot be represented with a single instruction GPR register materialization, instead requiring movk/movz.

I don't think that we can ever actually hit this situation.

In AArch64AddressingModes.h:

/// getFP32Imm - Return an 8-bit floating-point version of the 32-bit
/// floating-point value. If the value cannot be represented as an 8-bit
/// floating-point value, then return -1.
...
/// getFP64Imm - Return an 8-bit floating-point version of the 64-bit
/// floating-point value. If the value cannot be represented as an 8-bit
/// floating-point value, then return -1.

The range of legal floating point values for fmov is much smaller than the range of legal values we can pack into a mov. So, I don't think a case where we can avoid two movs by using fmov actually exists.

paquette updated this revision to Diff 238604.Jan 16 2020, 1:45 PM
  • Don't use getZExtValue
  • Add asserts that we're getting a G_FCONSTANT
aemerson accepted this revision.Jan 16 2020, 2:12 PM

LGTM.

This revision is now accepted and ready to land.Jan 16 2020, 2:12 PM
This revision was automatically updated to reflect the committed changes.