Message ID | 20240925094241.104004-1-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | x86: Don't use address override with segment regsiter | expand |
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 >
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 > > > >
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 --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; + } +}
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