diff mbox series

Fix x86 double word splitting (PR target/91604)

Message ID 20190903070832.GR2120@tucnak
State New
Headers show
Series Fix x86 double word splitting (PR target/91604) | expand

Commit Message

Jakub Jelinek Sept. 3, 2019, 7:08 a.m. UTC
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.


	Jakub

Comments

Uros Bizjak Sept. 3, 2019, 4:02 p.m. UTC | #1
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
diff mbox series

Patch

--- 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;
+}