diff mbox series

x86: Don't use address override with segment regsiter

Message ID 20240925094241.104004-1-hjl.tools@gmail.com
State New
Headers show
Series x86: Don't use address override with segment regsiter | expand

Commit Message

H.J. Lu Sept. 25, 2024, 9:42 a.m. UTC
Address override only applies to the (reg32) part in the thread address
fs:(reg32).  Don't rewrite thread address like

(set (reg:CCZ 17 flags)
    (compare:CCZ (reg:SI 98 [ __gmpfr_emax.0_1 ])
        (mem/c:SI (plus:SI (plus:SI (unspec:SI [
                            (const_int 0 [0])
                        ] UNSPEC_TP)
                    (reg:SI 107))
                (const:SI (unspec:SI [
                            (symbol_ref:SI ("previous_emax") [flags 0x1a] <var_decl 0x7fffe9a11cf0 previous_emax>)
                        ] UNSPEC_DTPOFF))) [1 previous_emax+0 S4 A32])))

if address override is used to avoid the invalid memory operand like

	cmpl	%fs:previous_emax@dtpoff(%eax), %r12

gcc/

	PR target/116839
	* config/i386/i386.cc (ix86_rewrite_tls_address_1): Make it
	static.  Return if TLS address is thread register plus an integer
	register.

gcc/testsuite/

	PR target/116839
	* gcc.target/i386/pr116839.c: New file.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 gcc/config/i386/i386.cc                  |  9 ++++-
 gcc/testsuite/gcc.target/i386/pr116839.c | 48 ++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr116839.c

Comments

Uros Bizjak Sept. 25, 2024, 11:06 a.m. UTC | #1
On Wed, Sep 25, 2024 at 11:42 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> Address override only applies to the (reg32) part in the thread address
> fs:(reg32).  Don't rewrite thread address like
>
> (set (reg:CCZ 17 flags)
>     (compare:CCZ (reg:SI 98 [ __gmpfr_emax.0_1 ])
>         (mem/c:SI (plus:SI (plus:SI (unspec:SI [
>                             (const_int 0 [0])
>                         ] UNSPEC_TP)
>                     (reg:SI 107))
>                 (const:SI (unspec:SI [
>                             (symbol_ref:SI ("previous_emax") [flags 0x1a] <var_decl 0x7fffe9a11cf0 previous_emax>)
>                         ] UNSPEC_DTPOFF))) [1 previous_emax+0 S4 A32])))
>
> if address override is used to avoid the invalid memory operand like
>
>         cmpl    %fs:previous_emax@dtpoff(%eax), %r12
>
> gcc/
>
>         PR target/116839
>         * config/i386/i386.cc (ix86_rewrite_tls_address_1): Make it
>         static.  Return if TLS address is thread register plus an integer
>         register.
>
> gcc/testsuite/
>
>         PR target/116839
>         * gcc.target/i386/pr116839.c: New file.

OK.

Thanks,
Uros.

>
> Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> ---
>  gcc/config/i386/i386.cc                  |  9 ++++-
>  gcc/testsuite/gcc.target/i386/pr116839.c | 48 ++++++++++++++++++++++++
>  2 files changed, 56 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr116839.c
>
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index 2f736a3b346..cfa84ed013d 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -12469,7 +12469,7 @@ ix86_tls_address_pattern_p (rtx op)
>  }
>
>  /* Rewrite *LOC so that it refers to a default TLS address space.  */
> -void
> +static void
>  ix86_rewrite_tls_address_1 (rtx *loc)
>  {
>    subrtx_ptr_iterator::array_type array;
> @@ -12491,6 +12491,13 @@ ix86_rewrite_tls_address_1 (rtx *loc)
>                   if (GET_CODE (u) == UNSPEC
>                       && XINT (u, 1) == UNSPEC_TP)
>                     {
> +                     /* NB: Since address override only applies to the
> +                        (reg32) part in fs:(reg32), return if address
> +                        override is used.  */
> +                     if (Pmode != word_mode
> +                         && REG_P (XEXP (*x, 1 - i)))
> +                       return;
> +
>                       addr_space_t as = DEFAULT_TLS_SEG_REG;
>
>                       *x = XEXP (*x, 1 - i);
> diff --git a/gcc/testsuite/gcc.target/i386/pr116839.c b/gcc/testsuite/gcc.target/i386/pr116839.c
> new file mode 100644
> index 00000000000..e5df8256251
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr116839.c
> @@ -0,0 +1,48 @@
> +/* { dg-do compile { target { ! ia32 } } } */
> +/* { dg-require-effective-target maybe_x32 } */
> +/* { dg-options "-mx32 -O2 -fPIC -mtls-dialect=gnu2" } */
> +/* { dg-final { scan-assembler-not "cmpl\[ \t\]+%fs:previous_emax@dtpoff\\(%eax\\)" } } */
> +
> +typedef long mpfr_prec_t;
> +typedef long mpfr_exp_t;
> +typedef struct {
> +  mpfr_prec_t _mpfr_prec;
> +} __mpfr_struct;
> +typedef __mpfr_struct mpfr_t[1];
> +extern _Thread_local mpfr_exp_t __gmpfr_emax;
> +static _Thread_local mpfr_exp_t previous_emax;
> +static _Thread_local mpfr_t bound_emax;
> +extern const mpfr_t __gmpfr_const_log2_RNDD;
> +extern const mpfr_t __gmpfr_const_log2_RNDU;
> +
> +typedef enum {
> +  MPFR_RNDN=0,
> +  MPFR_RNDZ,
> +  MPFR_RNDU,
> +  MPFR_RNDD,
> +  MPFR_RNDA,
> +  MPFR_RNDF,
> +  MPFR_RNDNA=-1
> +} mpfr_rnd_t;
> +typedef __mpfr_struct *mpfr_ptr;
> +typedef const __mpfr_struct *mpfr_srcptr;
> +void mpfr_mul (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
> +
> +void
> +foo (void)
> +{
> +  mpfr_exp_t saved_emax;
> +
> +  if (__gmpfr_emax != previous_emax)
> +    {
> +      saved_emax = __gmpfr_emax;
> +
> +      bound_emax->_mpfr_prec = 32;
> +
> +      mpfr_mul (bound_emax, saved_emax < 0 ?
> +                __gmpfr_const_log2_RNDD : __gmpfr_const_log2_RNDU,
> +                MPFR_RNDU);
> +      previous_emax = saved_emax;
> +      __gmpfr_emax = saved_emax;
> +    }
> +}
> --
> 2.46.1
>
H.J. Lu Sept. 28, 2024, 3:23 a.m. UTC | #2
On Wed, Sep 25, 2024, 7:06 PM Uros Bizjak <ubizjak@gmail.com> wrote:

> On Wed, Sep 25, 2024 at 11:42 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > Address override only applies to the (reg32) part in the thread address
> > fs:(reg32).  Don't rewrite thread address like
> >
> > (set (reg:CCZ 17 flags)
> >     (compare:CCZ (reg:SI 98 [ __gmpfr_emax.0_1 ])
> >         (mem/c:SI (plus:SI (plus:SI (unspec:SI [
> >                             (const_int 0 [0])
> >                         ] UNSPEC_TP)
> >                     (reg:SI 107))
> >                 (const:SI (unspec:SI [
> >                             (symbol_ref:SI ("previous_emax") [flags
> 0x1a] <var_decl 0x7fffe9a11cf0 previous_emax>)
> >                         ] UNSPEC_DTPOFF))) [1 previous_emax+0 S4 A32])))
> >
> > if address override is used to avoid the invalid memory operand like
> >
> >         cmpl    %fs:previous_emax@dtpoff(%eax), %r12
> >
> > gcc/
> >
> >         PR target/116839
> >         * config/i386/i386.cc (ix86_rewrite_tls_address_1): Make it
> >         static.  Return if TLS address is thread register plus an integer
> >         register.
> >
> > gcc/testsuite/
> >
> >         PR target/116839
> >         * gcc.target/i386/pr116839.c: New file.
>
> OK.
>

OK to backport?

Thanks.

H.J.

>
> Thanks,
> Uros.
>
> >
> > Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> > ---
> >  gcc/config/i386/i386.cc                  |  9 ++++-
> >  gcc/testsuite/gcc.target/i386/pr116839.c | 48 ++++++++++++++++++++++++
> >  2 files changed, 56 insertions(+), 1 deletion(-)
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr116839.c
> >
> > diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> > index 2f736a3b346..cfa84ed013d 100644
> > --- a/gcc/config/i386/i386.cc
> > +++ b/gcc/config/i386/i386.cc
> > @@ -12469,7 +12469,7 @@ ix86_tls_address_pattern_p (rtx op)
> >  }
> >
> >  /* Rewrite *LOC so that it refers to a default TLS address space.  */
> > -void
> > +static void
> >  ix86_rewrite_tls_address_1 (rtx *loc)
> >  {
> >    subrtx_ptr_iterator::array_type array;
> > @@ -12491,6 +12491,13 @@ ix86_rewrite_tls_address_1 (rtx *loc)
> >                   if (GET_CODE (u) == UNSPEC
> >                       && XINT (u, 1) == UNSPEC_TP)
> >                     {
> > +                     /* NB: Since address override only applies to the
> > +                        (reg32) part in fs:(reg32), return if address
> > +                        override is used.  */
> > +                     if (Pmode != word_mode
> > +                         && REG_P (XEXP (*x, 1 - i)))
> > +                       return;
> > +
> >                       addr_space_t as = DEFAULT_TLS_SEG_REG;
> >
> >                       *x = XEXP (*x, 1 - i);
> > diff --git a/gcc/testsuite/gcc.target/i386/pr116839.c
> b/gcc/testsuite/gcc.target/i386/pr116839.c
> > new file mode 100644
> > index 00000000000..e5df8256251
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/pr116839.c
> > @@ -0,0 +1,48 @@
> > +/* { dg-do compile { target { ! ia32 } } } */
> > +/* { dg-require-effective-target maybe_x32 } */
> > +/* { dg-options "-mx32 -O2 -fPIC -mtls-dialect=gnu2" } */
> > +/* { dg-final { scan-assembler-not "cmpl\[ \t\]+%fs:previous_emax@dtpoff\\(%eax\\)"
> } } */
> > +
> > +typedef long mpfr_prec_t;
> > +typedef long mpfr_exp_t;
> > +typedef struct {
> > +  mpfr_prec_t _mpfr_prec;
> > +} __mpfr_struct;
> > +typedef __mpfr_struct mpfr_t[1];
> > +extern _Thread_local mpfr_exp_t __gmpfr_emax;
> > +static _Thread_local mpfr_exp_t previous_emax;
> > +static _Thread_local mpfr_t bound_emax;
> > +extern const mpfr_t __gmpfr_const_log2_RNDD;
> > +extern const mpfr_t __gmpfr_const_log2_RNDU;
> > +
> > +typedef enum {
> > +  MPFR_RNDN=0,
> > +  MPFR_RNDZ,
> > +  MPFR_RNDU,
> > +  MPFR_RNDD,
> > +  MPFR_RNDA,
> > +  MPFR_RNDF,
> > +  MPFR_RNDNA=-1
> > +} mpfr_rnd_t;
> > +typedef __mpfr_struct *mpfr_ptr;
> > +typedef const __mpfr_struct *mpfr_srcptr;
> > +void mpfr_mul (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
> > +
> > +void
> > +foo (void)
> > +{
> > +  mpfr_exp_t saved_emax;
> > +
> > +  if (__gmpfr_emax != previous_emax)
> > +    {
> > +      saved_emax = __gmpfr_emax;
> > +
> > +      bound_emax->_mpfr_prec = 32;
> > +
> > +      mpfr_mul (bound_emax, saved_emax < 0 ?
> > +                __gmpfr_const_log2_RNDD : __gmpfr_const_log2_RNDU,
> > +                MPFR_RNDU);
> > +      previous_emax = saved_emax;
> > +      __gmpfr_emax = saved_emax;
> > +    }
> > +}
> > --
> > 2.46.1
> >
>
>
Uros Bizjak Sept. 28, 2024, 8:20 a.m. UTC | #3
On Sat, Sep 28, 2024 at 5:23 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Wed, Sep 25, 2024, 7:06 PM Uros Bizjak <ubizjak@gmail.com> wrote:
>>
>> On Wed, Sep 25, 2024 at 11:42 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>> >
>> > Address override only applies to the (reg32) part in the thread address
>> > fs:(reg32).  Don't rewrite thread address like
>> >
>> > (set (reg:CCZ 17 flags)
>> >     (compare:CCZ (reg:SI 98 [ __gmpfr_emax.0_1 ])
>> >         (mem/c:SI (plus:SI (plus:SI (unspec:SI [
>> >                             (const_int 0 [0])
>> >                         ] UNSPEC_TP)
>> >                     (reg:SI 107))
>> >                 (const:SI (unspec:SI [
>> >                             (symbol_ref:SI ("previous_emax") [flags 0x1a] <var_decl 0x7fffe9a11cf0 previous_emax>)
>> >                         ] UNSPEC_DTPOFF))) [1 previous_emax+0 S4 A32])))
>> >
>> > if address override is used to avoid the invalid memory operand like
>> >
>> >         cmpl    %fs:previous_emax@dtpoff(%eax), %r12
>> >
>> > gcc/
>> >
>> >         PR target/116839
>> >         * config/i386/i386.cc (ix86_rewrite_tls_address_1): Make it
>> >         static.  Return if TLS address is thread register plus an integer
>> >         register.
>> >
>> > gcc/testsuite/
>> >
>> >         PR target/116839
>> >         * gcc.target/i386/pr116839.c: New file.
>>
>> OK.
>
>
> OK to backport?

Also OK.

Thanks,
Uros.

>
> Thanks.
>
> H.J.
>>
>>
>> Thanks,
>> Uros.
>>
>> >
>> > Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
>> > ---
>> >  gcc/config/i386/i386.cc                  |  9 ++++-
>> >  gcc/testsuite/gcc.target/i386/pr116839.c | 48 ++++++++++++++++++++++++
>> >  2 files changed, 56 insertions(+), 1 deletion(-)
>> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr116839.c
>> >
>> > diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
>> > index 2f736a3b346..cfa84ed013d 100644
>> > --- a/gcc/config/i386/i386.cc
>> > +++ b/gcc/config/i386/i386.cc
>> > @@ -12469,7 +12469,7 @@ ix86_tls_address_pattern_p (rtx op)
>> >  }
>> >
>> >  /* Rewrite *LOC so that it refers to a default TLS address space.  */
>> > -void
>> > +static void
>> >  ix86_rewrite_tls_address_1 (rtx *loc)
>> >  {
>> >    subrtx_ptr_iterator::array_type array;
>> > @@ -12491,6 +12491,13 @@ ix86_rewrite_tls_address_1 (rtx *loc)
>> >                   if (GET_CODE (u) == UNSPEC
>> >                       && XINT (u, 1) == UNSPEC_TP)
>> >                     {
>> > +                     /* NB: Since address override only applies to the
>> > +                        (reg32) part in fs:(reg32), return if address
>> > +                        override is used.  */
>> > +                     if (Pmode != word_mode
>> > +                         && REG_P (XEXP (*x, 1 - i)))
>> > +                       return;
>> > +
>> >                       addr_space_t as = DEFAULT_TLS_SEG_REG;
>> >
>> >                       *x = XEXP (*x, 1 - i);
>> > diff --git a/gcc/testsuite/gcc.target/i386/pr116839.c b/gcc/testsuite/gcc.target/i386/pr116839.c
>> > new file mode 100644
>> > index 00000000000..e5df8256251
>> > --- /dev/null
>> > +++ b/gcc/testsuite/gcc.target/i386/pr116839.c
>> > @@ -0,0 +1,48 @@
>> > +/* { dg-do compile { target { ! ia32 } } } */
>> > +/* { dg-require-effective-target maybe_x32 } */
>> > +/* { dg-options "-mx32 -O2 -fPIC -mtls-dialect=gnu2" } */
>> > +/* { dg-final { scan-assembler-not "cmpl\[ \t\]+%fs:previous_emax@dtpoff\\(%eax\\)" } } */
>> > +
>> > +typedef long mpfr_prec_t;
>> > +typedef long mpfr_exp_t;
>> > +typedef struct {
>> > +  mpfr_prec_t _mpfr_prec;
>> > +} __mpfr_struct;
>> > +typedef __mpfr_struct mpfr_t[1];
>> > +extern _Thread_local mpfr_exp_t __gmpfr_emax;
>> > +static _Thread_local mpfr_exp_t previous_emax;
>> > +static _Thread_local mpfr_t bound_emax;
>> > +extern const mpfr_t __gmpfr_const_log2_RNDD;
>> > +extern const mpfr_t __gmpfr_const_log2_RNDU;
>> > +
>> > +typedef enum {
>> > +  MPFR_RNDN=0,
>> > +  MPFR_RNDZ,
>> > +  MPFR_RNDU,
>> > +  MPFR_RNDD,
>> > +  MPFR_RNDA,
>> > +  MPFR_RNDF,
>> > +  MPFR_RNDNA=-1
>> > +} mpfr_rnd_t;
>> > +typedef __mpfr_struct *mpfr_ptr;
>> > +typedef const __mpfr_struct *mpfr_srcptr;
>> > +void mpfr_mul (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
>> > +
>> > +void
>> > +foo (void)
>> > +{
>> > +  mpfr_exp_t saved_emax;
>> > +
>> > +  if (__gmpfr_emax != previous_emax)
>> > +    {
>> > +      saved_emax = __gmpfr_emax;
>> > +
>> > +      bound_emax->_mpfr_prec = 32;
>> > +
>> > +      mpfr_mul (bound_emax, saved_emax < 0 ?
>> > +                __gmpfr_const_log2_RNDD : __gmpfr_const_log2_RNDU,
>> > +                MPFR_RNDU);
>> > +      previous_emax = saved_emax;
>> > +      __gmpfr_emax = saved_emax;
>> > +    }
>> > +}
>> > --
>> > 2.46.1
>> >
>>
diff mbox series

Patch

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 2f736a3b346..cfa84ed013d 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -12469,7 +12469,7 @@  ix86_tls_address_pattern_p (rtx op)
 }
 
 /* Rewrite *LOC so that it refers to a default TLS address space.  */
-void
+static void
 ix86_rewrite_tls_address_1 (rtx *loc)
 {
   subrtx_ptr_iterator::array_type array;
@@ -12491,6 +12491,13 @@  ix86_rewrite_tls_address_1 (rtx *loc)
 		  if (GET_CODE (u) == UNSPEC
 		      && XINT (u, 1) == UNSPEC_TP)
 		    {
+		      /* NB: Since address override only applies to the
+			 (reg32) part in fs:(reg32), return if address
+			 override is used.  */
+		      if (Pmode != word_mode
+			  && REG_P (XEXP (*x, 1 - i)))
+			return;
+
 		      addr_space_t as = DEFAULT_TLS_SEG_REG;
 
 		      *x = XEXP (*x, 1 - i);
diff --git a/gcc/testsuite/gcc.target/i386/pr116839.c b/gcc/testsuite/gcc.target/i386/pr116839.c
new file mode 100644
index 00000000000..e5df8256251
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr116839.c
@@ -0,0 +1,48 @@ 
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-require-effective-target maybe_x32 } */
+/* { dg-options "-mx32 -O2 -fPIC -mtls-dialect=gnu2" } */
+/* { dg-final { scan-assembler-not "cmpl\[ \t\]+%fs:previous_emax@dtpoff\\(%eax\\)" } } */
+
+typedef long mpfr_prec_t;
+typedef long mpfr_exp_t;
+typedef struct {
+  mpfr_prec_t _mpfr_prec;
+} __mpfr_struct;
+typedef __mpfr_struct mpfr_t[1];
+extern _Thread_local mpfr_exp_t __gmpfr_emax;
+static _Thread_local mpfr_exp_t previous_emax;
+static _Thread_local mpfr_t bound_emax;
+extern const mpfr_t __gmpfr_const_log2_RNDD;
+extern const mpfr_t __gmpfr_const_log2_RNDU;
+
+typedef enum {
+  MPFR_RNDN=0,
+  MPFR_RNDZ,
+  MPFR_RNDU,
+  MPFR_RNDD,
+  MPFR_RNDA,
+  MPFR_RNDF,
+  MPFR_RNDNA=-1
+} mpfr_rnd_t;
+typedef __mpfr_struct *mpfr_ptr;
+typedef const __mpfr_struct *mpfr_srcptr;
+void mpfr_mul (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+
+void
+foo (void)
+{
+  mpfr_exp_t saved_emax;
+
+  if (__gmpfr_emax != previous_emax)
+    {
+      saved_emax = __gmpfr_emax;
+
+      bound_emax->_mpfr_prec = 32;
+
+      mpfr_mul (bound_emax, saved_emax < 0 ?
+                __gmpfr_const_log2_RNDD : __gmpfr_const_log2_RNDU,
+                MPFR_RNDU);
+      previous_emax = saved_emax;
+      __gmpfr_emax = saved_emax;
+    }
+}