On Tue, Sep 3, 2019 at 9:08 AM Jakub Jelinek <ja...@redhat.com> wrote: > > Hi! > > As mentioned in the PR, adjust_address in certain cases forces the address > into a register. This doesn't work if there is a matching MEM, where we > need rtx_equal_p before the splitting as well as after the splitting. > > The following patch fixes that by checking for the matching MEM (looks just > for one, that should be enough for x86 backend IMHO) and reusing the > adjust_address results in that case instead of calling it again. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2019-09-03 Jakub Jelinek <ja...@redhat.com> > > PR target/91604 > * config/i386/i386-expand.c (split_double_mode): If there is more than > one MEM operand and they are rtx_equal_p, reuse lo_half/hi_half from > already split matching MEM operand instead of calling adjust_address > again. > > * gcc.target/i386/pr91604.c: New test.
OK. Thanks, Uros. > > --- gcc/config/i386/i386-expand.c.jj 2019-08-29 11:22:21.897593027 +0200 > +++ gcc/config/i386/i386-expand.c 2019-09-02 18:31:10.362812352 +0200 > @@ -106,6 +106,8 @@ split_double_mode (machine_mode mode, rt > { > machine_mode half_mode; > unsigned int byte; > + rtx mem_op = NULL_RTX; > + int mem_num = 0; > > switch (mode) > { > @@ -129,8 +131,18 @@ split_double_mode (machine_mode mode, rt > but we still have to handle it. */ > if (MEM_P (op)) > { > - lo_half[num] = adjust_address (op, half_mode, 0); > - hi_half[num] = adjust_address (op, half_mode, byte); > + if (mem_op && rtx_equal_p (op, mem_op)) > + { > + lo_half[num] = lo_half[mem_num]; > + hi_half[num] = hi_half[mem_num]; > + } > + else > + { > + mem_op = op; > + mem_num = num; > + lo_half[num] = adjust_address (op, half_mode, 0); > + hi_half[num] = adjust_address (op, half_mode, byte); > + } > } > else > { > --- gcc/testsuite/gcc.target/i386/pr91604.c.jj 2019-09-02 18:35:24.399989307 > +0200 > +++ gcc/testsuite/gcc.target/i386/pr91604.c 2019-09-02 18:32:29.409622762 > +0200 > @@ -0,0 +1,11 @@ > +/* PR target/91604 */ > +/* { dg-do compile } */ > +/* { dg-options "-O3 -msse2 --param max-gcse-memory=0 > -fno-rerun-cse-after-loop" } */ > + > +long long v; > + > +void > +foo (void) > +{ > + v = ~v; > +} > > Jakub