[RS6000] altivec style lvx/stvx addresses vs power10

gcc.target/powerpc/fold-vec-st-pixel.c and other testcases fail on
power10, generating
	addi 9,5,12
	rldicr 9,9,0,59
	stxv 34,0(9)
rather than
	addi 5,5,12
	stvx 2,0,5
for an altivec lvx/stvx style address.

The problem starts with fwprop creating
(insn 9 4 0 2 (set (mem:V8HI (and:DI (plus:DI (reg/v/f:DI 121 [ vpp ])
                    (const_int 12 [0xc]))
                (const_int -16 [0xfffffffffffffff0])) [0 MEM <vector(8) short int> [(void *)_4 & -16B]+0 S16 A128])
        (reg/v:V8HI 120 [ vp1 ])) "pixel.c":6:10 1237 {vsx_movv8hi_64bit}
which is finally thrown out as invalid by lra.  lra of course does that
by reloading the entire address.

fwprop creates the invalid address due to rs6000_legitimate_address_p
trimming off the outer AND of altivec style addresses before applying
other predicates.  address_is_prefixed then allows the inner address.

Now at the time the AND stripping was added (git commit 850e8d3d56),
rs6000_legitimate_address looked a lot simpler.  This patch allows
through just those addresses that were legitimate in those simpler
days.

	* config/rs6000/rs6000.c (rs6000_legitimate_address_p): Limit
	AND addressing to just lvx/stvx style addresses.
This commit is contained in:
Alan Modra 2020-10-23 12:11:15 +10:30
parent 1a21c0ecd9
commit d0e2ffcca0
1 changed files with 10 additions and 4 deletions

View File

@ -9110,15 +9110,21 @@ rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
bool reg_offset_p = reg_offset_addressing_ok_p (mode);
bool quad_offset_p = mode_supports_dq_form (mode);
/* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
if (TARGET_ELF && RS6000_SYMBOL_REF_TLS_P (x))
return 0;
/* Handle unaligned altivec lvx/stvx type addresses. */
if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
&& GET_CODE (x) == AND
&& CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) == -16)
x = XEXP (x, 0);
{
x = XEXP (x, 0);
return (legitimate_indirect_address_p (x, reg_ok_strict)
|| legitimate_indexed_address_p (x, reg_ok_strict)
|| virtual_stack_registers_memory_p (x));
}
if (TARGET_ELF && RS6000_SYMBOL_REF_TLS_P (x))
return 0;
if (legitimate_indirect_address_p (x, reg_ok_strict))
return 1;
if (TARGET_UPDATE