lra: Canonicalize mult to shift in address reloads
Inside a (mem) RTX, it is canonical to write multiplications by powers
of two using a (mult) [0]. Outside of a (mem), the canonical way to
write multiplications by powers of two is using (ashift).
Now I observed that LRA does not quite respect this RTL canonicalization
rule. When compiling gcc/testsuite/gcc.dg/torture/pr34330.c with -Os
-ftree-vectorize, the RTL in the dump "281r.ira" has the insn:
(set (reg:SI 111)
(mem:SI (plus:DI (mult:DI (reg:DI 101 [ ivtmp.9 ])
(const_int 4 [0x4]))
(reg/v/f:DI 105 [ b ]))))
but LRA then proceeds to generate a reload, and we get the following
non-canonical insn in "282r.reload":
(set (reg:DI 7 x7 [121])
(plus:DI (mult:DI (reg:DI 5 x5 [orig:101 ivtmp.9 ] [101])
(const_int 4 [0x4]))
(reg/v/f:DI 1 x1 [orig:105 b ] [105])))
This patch fixes LRA to ensure that we generate canonical RTL in this
case. After the patch, we get the following insn in "282r.reload":
(set (reg:DI 7 x7 [121])
(plus:DI (ashift:DI (reg:DI 5 x5 [orig:101 ivtmp.9 ] [101])
(const_int 2 [0x2]))
(reg/v/f:DI 1 x1 [orig:105 b ] [105])))
[0] : https://gcc.gnu.org/onlinedocs/gccint/Insn-Canonicalizations.html
gcc/ChangeLog:
* lra-constraints.c (canonicalize_reload_addr): New.
(curr_insn_transform): Use canonicalize_reload_addr to ensure we
generate canonical RTL for an address reload.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/mem-shift-canonical.c: New test.