Message ID | 1407556266-12337-3-git-send-email-apinski@cavium.com |
---|---|
State | New |
Headers | show |
On Fri, Aug 8, 2014 at 8:51 PM, Andrew Pinski <apinski@cavium.com> wrote: > This patch fixes the original problem that HJL was having with x32 in > PR 47727, it is more constraint than HJL's patch only care about what > is happening inside a CONST; if we allow it for other cases, > the RTL and generated code is incorrect as it does not have the needed > zero extend. This allows ILP32 to work correctlya and allows &a + 2 to > be still generated correctly when doing a convert_memory_address_addr_space. > > > OK? Bootstrapped and tested on x86_64-linux-gnu (though not with x32 but > visually looked at the failing testcase with a much older compiler). > Also tested on aarch64-linux-gnu with no regressions and also fixing ld.so > for ILP32. Ping? > > Thanks, > Andrew Pinski > > ChangeLog: > * explow.c (convert_memory_address_addr_space): Rename to ... > (convert_memory_address_addr_space_1): This. Add in_const argument. > Inside a CONST RTL, permute the conversion and addition of constant > for zero and sign extended pointers. > (convert_memory_address_addr_space): New function. > > > --- > gcc/explow.c | 40 ++++++++++++++++++++++++++++------------ > 1 files changed, 28 insertions(+), 12 deletions(-) > > diff --git a/gcc/explow.c b/gcc/explow.c > index eb7dc85..64017a0 100644 > --- a/gcc/explow.c > +++ b/gcc/explow.c > @@ -310,11 +310,13 @@ break_out_memory_refs (rtx x) > an address in the address space's address mode, or vice versa (TO_MODE says > which way). We take advantage of the fact that pointers are not allowed to > overflow by commuting arithmetic operations over conversions so that address > - arithmetic insns can be used. */ > + arithmetic insns can be used. IN_CONST is true if this conversion is inside > + a CONST. */ > > -rtx > -convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED, > - rtx x, addr_space_t as ATTRIBUTE_UNUSED) > +static rtx > +convert_memory_address_addr_space_1 (enum machine_mode to_mode ATTRIBUTE_UNUSED, > + rtx x, addr_space_t as ATTRIBUTE_UNUSED, > + bool in_const) > { > #ifndef POINTERS_EXTEND_UNSIGNED > gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode); > @@ -370,8 +372,8 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED, > > case CONST: > return gen_rtx_CONST (to_mode, > - convert_memory_address_addr_space > - (to_mode, XEXP (x, 0), as)); > + convert_memory_address_addr_space_1 > + (to_mode, XEXP (x, 0), as, true)); > break; > > case PLUS: > @@ -381,16 +383,18 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED, > does not change it or if one operand is a constant and we are > using a ptr_extend instruction (POINTERS_EXTEND_UNSIGNED < 0). > We can always safely permute them if we are making the address > - narrower. */ > + narrower. Inside a CONST RTL, this is safe for both pointers > + zero or sign extended as pointers cannot wrap. */ > if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode) > || (GET_CODE (x) == PLUS > && CONST_INT_P (XEXP (x, 1)) > - && (XEXP (x, 1) == convert_memory_address_addr_space > - (to_mode, XEXP (x, 1), as) > - || POINTERS_EXTEND_UNSIGNED < 0))) > + && ((in_const && POINTERS_EXTEND_UNSIGNED !=0) > + || XEXP (x, 1) == convert_memory_address_addr_space_1 > + (to_mode, XEXP (x, 1), as, in_const) > + || POINTERS_EXTEND_UNSIGNED < 0))) > return gen_rtx_fmt_ee (GET_CODE (x), to_mode, > - convert_memory_address_addr_space > - (to_mode, XEXP (x, 0), as), > + convert_memory_address_addr_space_1 > + (to_mode, XEXP (x, 0), as, in_const), > XEXP (x, 1)); > break; > > @@ -402,6 +406,18 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED, > x, POINTERS_EXTEND_UNSIGNED); > #endif /* defined(POINTERS_EXTEND_UNSIGNED) */ > } > + > +/* Given X, a memory address in address space AS' pointer mode, convert it to > + an address in the address space's address mode, or vice versa (TO_MODE says > + which way). We take advantage of the fact that pointers are not allowed to > + overflow by commuting arithmetic operations over conversions so that address > + arithmetic insns can be used. */ > + > +rtx > +convert_memory_address_addr_space (enum machine_mode to_mode, rtx x, addr_space_t as) > +{ > + return convert_memory_address_addr_space_1 (to_mode, x, as, false); > +} > > /* Return something equivalent to X but valid as a memory address for something > of mode MODE in the named address space AS. When X is not itself valid, > -- > 1.7.2.5 >
On 08/08/2014 08:51 PM, Andrew Pinski wrote: > ChangeLog: > * explow.c (convert_memory_address_addr_space): Rename to ... > (convert_memory_address_addr_space_1): This. Add in_const argument. > Inside a CONST RTL, permute the conversion and addition of constant > for zero and sign extended pointers. > (convert_memory_address_addr_space): New function. Ok, with one nit... > + && ((in_const && POINTERS_EXTEND_UNSIGNED !=0) Missing space after != r~
diff --git a/gcc/explow.c b/gcc/explow.c index eb7dc85..64017a0 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -310,11 +310,13 @@ break_out_memory_refs (rtx x) an address in the address space's address mode, or vice versa (TO_MODE says which way). We take advantage of the fact that pointers are not allowed to overflow by commuting arithmetic operations over conversions so that address - arithmetic insns can be used. */ + arithmetic insns can be used. IN_CONST is true if this conversion is inside + a CONST. */ -rtx -convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED, - rtx x, addr_space_t as ATTRIBUTE_UNUSED) +static rtx +convert_memory_address_addr_space_1 (enum machine_mode to_mode ATTRIBUTE_UNUSED, + rtx x, addr_space_t as ATTRIBUTE_UNUSED, + bool in_const) { #ifndef POINTERS_EXTEND_UNSIGNED gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode); @@ -370,8 +372,8 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED, case CONST: return gen_rtx_CONST (to_mode, - convert_memory_address_addr_space - (to_mode, XEXP (x, 0), as)); + convert_memory_address_addr_space_1 + (to_mode, XEXP (x, 0), as, true)); break; case PLUS: @@ -381,16 +383,18 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED, does not change it or if one operand is a constant and we are using a ptr_extend instruction (POINTERS_EXTEND_UNSIGNED < 0). We can always safely permute them if we are making the address - narrower. */ + narrower. Inside a CONST RTL, this is safe for both pointers + zero or sign extended as pointers cannot wrap. */ if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode) || (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)) - && (XEXP (x, 1) == convert_memory_address_addr_space - (to_mode, XEXP (x, 1), as) - || POINTERS_EXTEND_UNSIGNED < 0))) + && ((in_const && POINTERS_EXTEND_UNSIGNED !=0) + || XEXP (x, 1) == convert_memory_address_addr_space_1 + (to_mode, XEXP (x, 1), as, in_const) + || POINTERS_EXTEND_UNSIGNED < 0))) return gen_rtx_fmt_ee (GET_CODE (x), to_mode, - convert_memory_address_addr_space - (to_mode, XEXP (x, 0), as), + convert_memory_address_addr_space_1 + (to_mode, XEXP (x, 0), as, in_const), XEXP (x, 1)); break; @@ -402,6 +406,18 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED, x, POINTERS_EXTEND_UNSIGNED); #endif /* defined(POINTERS_EXTEND_UNSIGNED) */ } + +/* Given X, a memory address in address space AS' pointer mode, convert it to + an address in the address space's address mode, or vice versa (TO_MODE says + which way). We take advantage of the fact that pointers are not allowed to + overflow by commuting arithmetic operations over conversions so that address + arithmetic insns can be used. */ + +rtx +convert_memory_address_addr_space (enum machine_mode to_mode, rtx x, addr_space_t as) +{ + return convert_memory_address_addr_space_1 (to_mode, x, as, false); +} /* Return something equivalent to X but valid as a memory address for something of mode MODE in the named address space AS. When X is not itself valid,