This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix x86 double word splitting (PR target/91604)
- From: Uros Bizjak <ubizjak at gmail dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 3 Sep 2019 18:02:39 +0200
- Subject: Re: [PATCH] Fix x86 double word splitting (PR target/91604)
- References: <20190903070832.GR2120@tucnak>
On Tue, Sep 3, 2019 at 9:08 AM Jakub Jelinek <jakub@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 <jakub@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