diff mbox

PATCH: PR target/58690: internal compiler error: in copy_to_mode_reg, at explow.c:641

Message ID 20131011183844.GA26798@intel.com
State New
Headers show

Commit Message

H.J. Lu Oct. 11, 2013, 6:38 p.m. UTC
Hi,

In x32, when a TLS address is in DImode and Pmode is SImode,
copy_addr_to_reg will fail.  This patch adds ix86_copy_addr_to_reg
to first copy DImode address into a DImode register and then to generate
SImode SUBREG in this case.  Tested on x32.  OK for trunk?

Thanks.


H.J.
---
gcc/

2013-10-11  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/58690
	* config/i386/i386.c (ix86_copy_addr_to_reg): New function.
	(ix86_expand_movmem): Replace copy_addr_to_reg with
	ix86_copy_addr_to_reg.
	(ix86_expand_setmem): Likewise.

gcc/testsuite/

2013-10-11  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/58690
	* gcc.target/i386/pr58690.c: New test

Comments

Uros Bizjak Oct. 12, 2013, 7:21 a.m. UTC | #1
On Fri, Oct 11, 2013 at 8:38 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:

> In x32, when a TLS address is in DImode and Pmode is SImode,
> copy_addr_to_reg will fail.  This patch adds ix86_copy_addr_to_reg
> to first copy DImode address into a DImode register and then to generate
> SImode SUBREG in this case.  Tested on x32.  OK for trunk?
>
> 2013-10-11  H.J. Lu  <hongjiu.lu@intel.com>
>
>         PR target/58690
>         * config/i386/i386.c (ix86_copy_addr_to_reg): New function.
>         (ix86_expand_movmem): Replace copy_addr_to_reg with
>         ix86_copy_addr_to_reg.
>         (ix86_expand_setmem): Likewise.
>
> gcc/testsuite/
>
> 2013-10-11  H.J. Lu  <hongjiu.lu@intel.com>
>
>         PR target/58690
>         * gcc.target/i386/pr58690.c: New test
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 37c1bec..e39d63db 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -22076,6 +22076,21 @@ counter_mode (rtx count_exp)
>    return SImode;
>  }
>
> +/* Copy the address to a register in Pmode.  Support x32 TLS address in
> +   DImode and Pmode in SImode.  */

Copy the address to a Pmode register.  This is used for x32 to truncate
DImode TLS address to a SImode register.

> +static rtx
> +ix86_copy_addr_to_reg (rtx addr)
> +{
> +  if (GET_MODE (addr) != Pmode)
> +    {
> +      gcc_assert (GET_MODE (addr) == DImode && Pmode == SImode);
> +      return gen_rtx_SUBREG (SImode, copy_to_mode_reg (DImode, addr), 0);
> +    }
> +  else
> +    return copy_addr_to_reg (addr);
> +}

No negative conditions please. Just switch arms of the if clause.

OK with these changes.

Do we also need this patch on 4.8?

Thanks,
Uros.
diff mbox

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 37c1bec..e39d63db 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -22076,6 +22076,21 @@  counter_mode (rtx count_exp)
   return SImode;
 }
 
+/* Copy the address to a register in Pmode.  Support x32 TLS address in
+   DImode and Pmode in SImode.  */
+
+static rtx
+ix86_copy_addr_to_reg (rtx addr)
+{
+  if (GET_MODE (addr) != Pmode)
+    {
+      gcc_assert (GET_MODE (addr) == DImode && Pmode == SImode);
+      return gen_rtx_SUBREG (SImode, copy_to_mode_reg (DImode, addr), 0);
+    }
+  else
+    return copy_addr_to_reg (addr);
+}
+
 /* When SRCPTR is non-NULL, output simple loop to move memory
    pointer to SRCPTR to DESTPTR via chunks of MODE unrolled UNROLL times,
    overall size is COUNT specified in bytes.  When SRCPTR is NULL, output the
@@ -23032,8 +23047,8 @@  ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
 
   if (!count)
     count_exp = copy_to_mode_reg (GET_MODE (count_exp), count_exp);
-  destreg = copy_addr_to_reg (XEXP (dst, 0));
-  srcreg = copy_addr_to_reg (XEXP (src, 0));
+  destreg = ix86_copy_addr_to_reg (XEXP (dst, 0));
+  srcreg = ix86_copy_addr_to_reg (XEXP (src, 0));
 
   unroll_factor = 1;
   move_mode = word_mode;
@@ -23436,7 +23451,7 @@  ix86_expand_setmem (rtx dst, rtx count_exp, rtx val_exp, rtx align_exp,
 
   if (!count)
     count_exp = copy_to_mode_reg (counter_mode (count_exp), count_exp);
-  destreg = copy_addr_to_reg (XEXP (dst, 0));
+  destreg = ix86_copy_addr_to_reg (XEXP (dst, 0));
 
   move_mode = word_mode;
   unroll_factor = 1;
diff --git a/gcc/testsuite/gcc.target/i386/pr58690.c b/gcc/testsuite/gcc.target/i386/pr58690.c
new file mode 100644
index 0000000..87a87cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr58690.c
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { ! { ia32 } } } } */
+/* { dg-require-effective-target maybe_x32 } */
+/* { dg-options "-O2 -mx32 -maddress-mode=short" } */
+
+struct gomp_thread
+{
+  char foo[41];
+};
+extern __thread struct gomp_thread gomp_tls_data;
+void
+foo (void)
+{
+  __builtin_memset (&gomp_tls_data, '\0', sizeof (gomp_tls_data));
+}