mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 19:03:59 +08:00
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 c79cc30862
)
This commit is contained in:
parent
e282606b6c
commit
2e66eb7e7e
@ -11787,7 +11787,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;
|
||||
@ -11809,6 +11809,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);
|
||||
|
48
gcc/testsuite/gcc.target/i386/pr116839.c
Normal file
48
gcc/testsuite/gcc.target/i386/pr116839.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user