ms_abi -> sysv_abi passing float arguments incorrectly (backported from 4.5) http://gcc.gnu.org/PR43869 https://bugs.gentoo.org/352201 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -4724,18 +4724,18 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ cum->nregs = ix86_regparm; if (TARGET_64BIT) { - if (cum->call_abi != DEFAULT_ABI) - cum->nregs = DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX - : X64_REGPARM_MAX; + cum->nregs = (cum->call_abi == SYSV_ABI + ? X86_64_REGPARM_MAX + : X64_REGPARM_MAX); } if (TARGET_SSE) { cum->sse_nregs = SSE_REGPARM_MAX; if (TARGET_64BIT) { - if (cum->call_abi != DEFAULT_ABI) - cum->sse_nregs = DEFAULT_ABI != SYSV_ABI ? X86_64_SSE_REGPARM_MAX - : X64_SSE_REGPARM_MAX; + cum->sse_nregs = (cum->call_abi == SYSV_ABI + ? X86_64_SSE_REGPARM_MAX + : X64_SSE_REGPARM_MAX); } } if (TARGET_MMX) @@ -5849,10 +5849,7 @@ function_arg_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode, if (mode == VOIDmode) return GEN_INT (cum->maybe_vaarg ? (cum->sse_nregs < 0 - ? (cum->call_abi == DEFAULT_ABI - ? SSE_REGPARM_MAX - : (DEFAULT_ABI != SYSV_ABI ? X86_64_SSE_REGPARM_MAX - : X64_SSE_REGPARM_MAX)) + ? X86_64_SSE_REGPARM_MAX : cum->sse_regno) : -1); @@ -6552,10 +6549,6 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) rtx nsse_reg; alias_set_type set; int i; - int regparm = ix86_regparm; - - if (cum->call_abi != DEFAULT_ABI) - regparm = DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX : X64_REGPARM_MAX; /* GPR size of varargs save area. */ if (cfun->va_list_gpr_size) @@ -6577,7 +6570,7 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) set = get_varargs_alias_set (); for (i = cum->regno; - i < regparm + i < X86_64_REGPARM_MAX && i < cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD; i++) { --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr43869.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ +/* { dg-require-effective-target lp64 } */ + +int __attribute__((__noinline__)) +bugged(float f1, float f2, float f3, float f4, + float f5, float f6, float f7, float f8) +{ + return f1 || f2 || f3 || f4 || f5 != 1. || f6 != 1. || f7 != 1. || f8 != 1.; +} + +int __attribute__((__noinline__, __ms_abi__)) isbugged(void) +{ + return bugged(0, 0, 0, 0, 1., 1., 1., 1.); +} + +int main() +{ + return isbugged(); +} +