On Wed, Nov 8, 2023 at 5:37 PM Alexandre Oliva <ol...@adacore.com> wrote: > > Ping? > https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598872.html > > Looking at the code generated for sse2-{load,store}-multi.c with PIE, > I realized we could use UNSPEC_GOTOFF as a base address, and that this > would enable the test to use the vector insns expected by the tests > even with PIC, so I extended the base + offset logic used by the SSE2 > multi-load/store peepholes to accept reg + symbolic base + offset too, > so that the test generated the expected insns even with PIE. > > Regstrapped on x86_64-linux-gnu, also tested with gcc-13 on i686- and > x86_64-. Ok to install? > > > for gcc/ChangeLog > > * config/i386/i386.cc (symbolic_base_address_p, > base_address_p): New, factored out from... > (extract_base_offset_in_addr): ... here and extended to > recognize REG+GOTOFF, as in gcc.target/i386/sse2-load-multi.c > and sse2-store-multi.c with PIE enabled by default.
LGTM. Thanks, Uros. > --- > gcc/config/i386/i386.cc | 89 > ++++++++++++++++++++++++++++++++++++++++------- > 1 file changed, 75 insertions(+), 14 deletions(-) > > diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc > index c2bd07fced7b1..eec9b42396e0a 100644 > --- a/gcc/config/i386/i386.cc > +++ b/gcc/config/i386/i386.cc > @@ -25198,11 +25198,40 @@ ix86_reloc_rw_mask (void) > } > #endif > > -/* If MEM is in the form of [base+offset], extract the two parts > - of address and set to BASE and OFFSET, otherwise return false. */ > +/* Return true iff ADDR can be used as a symbolic base address. */ > > static bool > -extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset) > +symbolic_base_address_p (rtx addr) > +{ > + if (GET_CODE (addr) == SYMBOL_REF) > + return true; > + > + if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_GOTOFF) > + return true; > + > + return false; > +} > + > +/* Return true iff ADDR can be used as a base address. */ > + > +static bool > +base_address_p (rtx addr) > +{ > + if (REG_P (addr)) > + return true; > + > + if (symbolic_base_address_p (addr)) > + return true; > + > + return false; > +} > + > +/* If MEM is in the form of [(base+symbase)+offset], extract the three > + parts of address and set to BASE, SYMBASE and OFFSET, otherwise > + return false. */ > + > +static bool > +extract_base_offset_in_addr (rtx mem, rtx *base, rtx *symbase, rtx *offset) > { > rtx addr; > > @@ -25213,21 +25242,52 @@ extract_base_offset_in_addr (rtx mem, rtx *base, > rtx *offset) > if (GET_CODE (addr) == CONST) > addr = XEXP (addr, 0); > > - if (REG_P (addr) || GET_CODE (addr) == SYMBOL_REF) > + if (base_address_p (addr)) > { > *base = addr; > + *symbase = const0_rtx; > *offset = const0_rtx; > return true; > } > > if (GET_CODE (addr) == PLUS > - && (REG_P (XEXP (addr, 0)) > - || GET_CODE (XEXP (addr, 0)) == SYMBOL_REF) > - && CONST_INT_P (XEXP (addr, 1))) > + && base_address_p (XEXP (addr, 0))) > { > - *base = XEXP (addr, 0); > - *offset = XEXP (addr, 1); > - return true; > + rtx addend = XEXP (addr, 1); > + > + if (GET_CODE (addend) == CONST) > + addend = XEXP (addend, 0); > + > + if (CONST_INT_P (addend)) > + { > + *base = XEXP (addr, 0); > + *symbase = const0_rtx; > + *offset = addend; > + return true; > + } > + > + /* Also accept REG + symbolic ref, with or without a CONST_INT > + offset. */ > + if (REG_P (XEXP (addr, 0))) > + { > + if (symbolic_base_address_p (addend)) > + { > + *base = XEXP (addr, 0); > + *symbase = addend; > + *offset = const0_rtx; > + return true; > + } > + > + if (GET_CODE (addend) == PLUS > + && symbolic_base_address_p (XEXP (addend, 0)) > + && CONST_INT_P (XEXP (addend, 1))) > + { > + *base = XEXP (addr, 0); > + *symbase = XEXP (addend, 0); > + *offset = XEXP (addend, 1); > + return true; > + } > + } > } > > return false; > @@ -25242,7 +25302,8 @@ ix86_operands_ok_for_move_multiple (rtx *operands, > bool load, > machine_mode mode) > { > HOST_WIDE_INT offval_1, offval_2, msize; > - rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2, offset_1, offset_2; > + rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2, > + symbase_1, symbase_2, offset_1, offset_2; > > if (load) > { > @@ -25265,13 +25326,13 @@ ix86_operands_ok_for_move_multiple (rtx *operands, > bool load, > return false; > > /* Check if the addresses are in the form of [base+offset]. */ > - if (!extract_base_offset_in_addr (mem_1, &base_1, &offset_1)) > + if (!extract_base_offset_in_addr (mem_1, &base_1, &symbase_1, &offset_1)) > return false; > - if (!extract_base_offset_in_addr (mem_2, &base_2, &offset_2)) > + if (!extract_base_offset_in_addr (mem_2, &base_2, &symbase_2, &offset_2)) > return false; > > /* Check if the bases are the same. */ > - if (!rtx_equal_p (base_1, base_2)) > + if (!rtx_equal_p (base_1, base_2) || !rtx_equal_p (symbase_1, symbase_2)) > return false; > > offval_1 = INTVAL (offset_1); > > > -- > Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ > Free Software Activist GNU Toolchain Engineer > More tolerance and less prejudice are key for inclusion and diversity > Excluding neuro-others for not behaving ""normal"" is *not* inclusive