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.

Reply via email to