diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index e2743e0bd5cb582315fc0294c4d26a059e4e26bf..3e7e1b138ff8a991c6f1cf7a27896cbbd541c97b 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -4780,13 +4780,31 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, examine_argument (nat_mode, type, 0, &needed_intregs, &needed_sseregs); - need_temp = (!REG_P (container) + bool container_in_reg = false; + if (REG_P (container)) + container_in_reg = true; + else if (GET_CODE (container) == PARALLEL + && GET_MODE (container) == BLKmode + && XVECLEN (container, 0) == 1) + { + /* Check if it is a PARALLEL BLKmode container of an EXPR_LIST + expression in a TImode register. In this case, temp isn't + needed. Otherwise, the TImode variable will be put in the + GPR save area which guarantees only 8-byte alignment. */ + rtx x = XVECEXP (container, 0, 0); + if (GET_CODE (x) == EXPR_LIST + && REG_P (XEXP (x, 0)) + && XEXP (x, 1) == const0_rtx) + container_in_reg = true; + } + + need_temp = (!container_in_reg && ((needed_intregs && TYPE_ALIGN (type) > 64) || TYPE_ALIGN (type) > 128)); /* In case we are passing structure, verify that it is consecutive block on the register save area. If not we need to do moves. */ - if (!need_temp && !REG_P (container)) + if (!need_temp && !container_in_reg) { /* Verify that all registers are strictly consecutive */ if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0)))) @@ -11768,7 +11786,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; @@ -11790,6 +11808,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); @@ -22581,6 +22606,13 @@ ix86_stack_protect_guard (void) return default_stack_protect_guard (); } +static bool +ix86_stack_protect_runtime_enabled_p (void) +{ + /* Naked functions should not enable stack protector. */ + return !ix86_function_naked (current_function_decl); +} + /* For 32-bit code we can save PIC register setup by using __stack_chk_fail_local hidden function instead of calling __stack_chk_fail directly. 64-bit code doesn't need to setup any PIC @@ -24601,6 +24633,10 @@ ix86_libgcc_floating_mode_supported_p #undef TARGET_STACK_PROTECT_GUARD #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard +#undef TARGET_STACK_PROTECT_RUNTIME_ENABLED_P +#define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P \ + ix86_stack_protect_runtime_enabled_p + #if !TARGET_MACHO #undef TARGET_STACK_PROTECT_FAIL #define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 5052f878d0324d21af6cd52c6abee85931b9ca83..a198e36a14550f9adb9a7e0b939253ee70af7f48 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2177,7 +2177,7 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER]; #define ASM_OUTPUT_SYMBOL_REF(FILE, SYM) \ do { \ const char *name \ - = assemble_name_resolve (XSTR (x, 0)); \ + = assemble_name_resolve (XSTR (SYM, 0)); \ /* In -masm=att wrap identifiers that start with $ \ into parens. */ \ if (ASSEMBLER_DIALECT == ASM_ATT \ diff --git a/gcc/testsuite/gcc.target/i386/pr116621.c b/gcc/testsuite/gcc.target/i386/pr116621.c new file mode 100644 index 0000000000000000000000000000000000000000..704266458a850a90307f677f0a14e58f6c4cecd9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr116621.c @@ -0,0 +1,43 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#include +#include + +union S8302 +{ + union + { + double b; + int c; + } a; + long double d; + unsigned short int f[5]; +}; + +union S8302 s8302; +extern void check8302va (int i, ...); + +int +main (void) +{ + memset (&s8302, '\0', sizeof (s8302)); + s8302.a.b = -221438.250000; + check8302va (1, s8302); + return 0; +} + +__attribute__((noinline, noclone)) +void +check8302va (int z, ...) +{ + union S8302 arg, *p; + va_list ap; + + __builtin_va_start (ap, z); + p = &s8302; + arg = __builtin_va_arg (ap, union S8302); + if (p->a.b != arg.a.b) + __builtin_abort (); + __builtin_va_end (ap); +} diff --git a/gcc/testsuite/gcc.target/i386/pr116839.c b/gcc/testsuite/gcc.target/i386/pr116839.c new file mode 100644 index 0000000000000000000000000000000000000000..e5df82562518d3168a86b3e58532a9e1ba0b4de4 --- /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; + } +} diff --git a/gcc/testsuite/gcc.target/i386/pr116962.c b/gcc/testsuite/gcc.target/i386/pr116962.c new file mode 100644 index 0000000000000000000000000000000000000000..ced16eee746b967670fc0c0990f8aebacd6e4462 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr116962.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target fstack_protector } } */ +/* { dg-options "-O2 -fstack-protector-all" } */ +/* { dg-final { scan-assembler-not "__stack_chk_fail" } } */ + +__attribute__ ((naked)) +void +foo (void) +{ + asm ("ret"); +}