On Wed, Aug 07, 2019 at 07:12:19PM +0100, Richard Sandiford wrote: > The AArch64 port uses define_splits to prefer moving certain float > constants via integer registers over loading them from memory. E.g.: > > (set (reg:SF X) (const_double:SF C)) > > splits to: > > (set (reg:SI tmp) (const_int C')) > (set (reg:SF X) (subreg:SF (reg:SI tmp) 0)) > > The problem with using splits for this -- especially when the split > instruction is a constant move -- is that the original form is still > valid and can be recreated by later pre-RA passes. (And I think that's > a valid thing for them to do, since they're folding away what appears in > rtl terms to be a redundant instruction.) > > One pass that can do this is ira's combine_and_move_insns, which among > other things looks for registers that are set once and used once. > If the register is set to a rematerialisable value, the code tries > to fold that value into the single use. > > We don't normally see this effect at -O2 and above because > combine_and_move_insns isn't run when -fsched-pressure is enabled > (which it is by default on AArch64). But arguably the combine part is > useful independently of -fsched-pressure, and only the move part is > suspect. So I don't think we should rely on the combination not > happening here. > > The new tests demonstrate the problem by running the original tests > at -O instead of -O2. > > This patch does the optimisation by splitting the moves at generation > time and rejecting the combined form while the split is still possible. > REG_EQUAL notes on the second move still give the original floating-point > value for passes that need it. > > Tested on aarch64-linux-gnu (with and without SVE) and aarch64_be-elf. > OK to install?
OK. Thanks, James > Richard > > > 2019-08-07 Richard Sandiford <richard.sandif...@arm.com> > > gcc/ > * config/aarch64/aarch64-protos.h (aarch64_move_float_via_int_p): > Declare. > * config/aarch64/aarch64.c (aarch64_move_float_via_int_p): New > function, extracted from the GPF_HF move splitter. > * config/aarch64/aarch64.md: Remove GPF_HF move splitter. > (mov<GPF_TF_F16:mode>): Move via an integer register if > aarch64_move_float_via_int_p. > (*movhf_aarch64, *movsf_aarch64, *movdf_aarch64): Check > aarch64_move_float_via_int_p. > * config/aarch64/iterators.md (fcvt_target): Handle TI and TF. > (FCVT_TARGET): Likewise. > > gcc/testsuite/ > * gcc.target/aarch64/dbl_mov_immediate_2.c: New test. > * gcc.target/aarch64/f16_mov_immediate_5.c: Likewise. > * gcc.target/aarch64/flt_mov_immediate_2.c: Likewise.