[gcc r14-10716] x86: Don't use address override with segment regsiter
H.J. Lu
hjl@gcc.gnu.org
Sat Sep 28 10:49:50 GMT 2024
https://gcc.gnu.org/g:25cb153f93bb9ff3543ba8e31bbe7be4f6168aa4
commit r14-10716-g25cb153f93bb9ff3543ba8e31bbe7be4f6168aa4
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Wed Sep 25 16:39:04 2024 +0800
x86: Don't use address override with segment regsiter
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), %r12d
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>
(cherry picked from commit c79cc30862d7255ca15884aa956d1ccfa279d86a)
Diff:
---
gcc/config/i386/i386.cc | 9 +++++-
gcc/testsuite/gcc.target/i386/pr116839.c | 48 ++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 8f1c1f9ccd0a..93d05a301c92 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -12458,7 +12458,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;
@@ -12480,6 +12480,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 000000000000..e5df82562518
--- /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;
+ }
+}
More information about the Gcc-cvs
mailing list