re PR target/66047 (vlc compilation failure with target attribute)
PR target/66047 * i386.c (ix86_function_sseregparm): Only return -1 if local function with implied regparm is called from -mno-sse function. (init_cumulative_args): Output error if ix86_function_sseregparm return -1 and SSE register would be needed. (function_arg_advance_32): Likewise. (function_arg_32): Likewise. * i386.h (ix86_args): Add decl field. * gcc.target/i386/pr66047.c: New testcase. From-SVN: r223111
This commit is contained in:
parent
e4b5b3a5cb
commit
e66fc62389
|
@ -1,3 +1,14 @@
|
||||||
|
2015-05-12 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
|
PR target/pr66047.c
|
||||||
|
* i386.c (ix86_function_sseregparm): Only return -1 if local function
|
||||||
|
with implied regparm is called from -mno-sse function.
|
||||||
|
(init_cumulative_args): Output error if ix86_function_sseregparm
|
||||||
|
return -1 and SSE register would be needed.
|
||||||
|
(function_arg_advance_32): Likewise.
|
||||||
|
(function_arg_32): Likewise.
|
||||||
|
* i386.h (ix86_args): Add decl field.
|
||||||
|
|
||||||
2015-05-12 Jan Hubicka <hubicka@ucw.cz>
|
2015-05-12 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
PR ipa/65873
|
PR ipa/65873
|
||||||
|
|
|
@ -5895,7 +5895,10 @@ ix86_function_regparm (const_tree type, const_tree decl)
|
||||||
/* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
|
/* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
|
||||||
DFmode (2) arguments in SSE registers for a function with the
|
DFmode (2) arguments in SSE registers for a function with the
|
||||||
indicated TYPE and DECL. DECL may be NULL when calling function
|
indicated TYPE and DECL. DECL may be NULL when calling function
|
||||||
indirectly or considering a libcall. Otherwise return 0. */
|
indirectly or considering a libcall. Return -1 if any FP parameter
|
||||||
|
should be rejected by error. This is used in siutation we imply SSE
|
||||||
|
calling convetion but the function is called from another function with
|
||||||
|
SSE disabled. Otherwise return 0. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
|
ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
|
||||||
|
@ -5944,14 +5947,13 @@ ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
|
||||||
{
|
{
|
||||||
/* Refuse to produce wrong code when local function with SSE enabled
|
/* Refuse to produce wrong code when local function with SSE enabled
|
||||||
is called from SSE disabled function.
|
is called from SSE disabled function.
|
||||||
We may work hard to work out these scenarios but hopefully
|
FIXME: We need a way to detect these cases cross-ltrans partition
|
||||||
it doesnot matter in practice. */
|
and avoid using SSE calling conventions on local functions called
|
||||||
|
from function with SSE disabled. For now at least delay the
|
||||||
|
warning until we know we are going to produce wrong code.
|
||||||
|
See PR66047 */
|
||||||
if (!TARGET_SSE && warn)
|
if (!TARGET_SSE && warn)
|
||||||
{
|
return -1;
|
||||||
error ("calling %qD with SSE caling convention without "
|
|
||||||
"SSE/SSE2 enabled", decl);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return TARGET_SSE2_P (target_opts_for_fn (target->decl)
|
return TARGET_SSE2_P (target_opts_for_fn (target->decl)
|
||||||
->x_ix86_isa_flags) ? 2 : 1;
|
->x_ix86_isa_flags) ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
@ -6507,6 +6509,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
|
||||||
cum->bnd_regno = FIRST_BND_REG;
|
cum->bnd_regno = FIRST_BND_REG;
|
||||||
cum->bnds_in_bt = 0;
|
cum->bnds_in_bt = 0;
|
||||||
cum->force_bnd_pass = 0;
|
cum->force_bnd_pass = 0;
|
||||||
|
cum->decl = fndecl;
|
||||||
|
|
||||||
if (!TARGET_64BIT)
|
if (!TARGET_64BIT)
|
||||||
{
|
{
|
||||||
|
@ -7452,6 +7455,7 @@ function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
|
||||||
HOST_WIDE_INT words)
|
HOST_WIDE_INT words)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
bool error_p = NULL;
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
|
@ -7484,9 +7488,13 @@ function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
|
|
||||||
case DFmode:
|
case DFmode:
|
||||||
|
if (cum->float_in_sse == -1)
|
||||||
|
error_p = 1;
|
||||||
if (cum->float_in_sse < 2)
|
if (cum->float_in_sse < 2)
|
||||||
break;
|
break;
|
||||||
case SFmode:
|
case SFmode:
|
||||||
|
if (cum->float_in_sse == -1)
|
||||||
|
error_p = 1;
|
||||||
if (cum->float_in_sse < 1)
|
if (cum->float_in_sse < 1)
|
||||||
break;
|
break;
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
|
@ -7542,6 +7550,14 @@ function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (error_p)
|
||||||
|
{
|
||||||
|
cum->float_in_sse = 0;
|
||||||
|
error ("calling %qD with SSE calling convention without "
|
||||||
|
"SSE/SSE2 enabled", cum->decl);
|
||||||
|
sorry ("this is a GCC bug that can be worked around by adding "
|
||||||
|
"attribute used to function called");
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -7674,10 +7690,11 @@ ix86_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
||||||
(otherwise it is an extra parameter matching an ellipsis). */
|
(otherwise it is an extra parameter matching an ellipsis). */
|
||||||
|
|
||||||
static rtx
|
static rtx
|
||||||
function_arg_32 (const CUMULATIVE_ARGS *cum, machine_mode mode,
|
function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
|
||||||
machine_mode orig_mode, const_tree type,
|
machine_mode orig_mode, const_tree type,
|
||||||
HOST_WIDE_INT bytes, HOST_WIDE_INT words)
|
HOST_WIDE_INT bytes, HOST_WIDE_INT words)
|
||||||
{
|
{
|
||||||
|
bool error_p = false;
|
||||||
/* Avoid the AL settings for the Unix64 ABI. */
|
/* Avoid the AL settings for the Unix64 ABI. */
|
||||||
if (mode == VOIDmode)
|
if (mode == VOIDmode)
|
||||||
return constm1_rtx;
|
return constm1_rtx;
|
||||||
|
@ -7718,9 +7735,13 @@ function_arg_32 (const CUMULATIVE_ARGS *cum, machine_mode mode,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DFmode:
|
case DFmode:
|
||||||
|
if (cum->float_in_sse == -1)
|
||||||
|
error_p = 1;
|
||||||
if (cum->float_in_sse < 2)
|
if (cum->float_in_sse < 2)
|
||||||
break;
|
break;
|
||||||
case SFmode:
|
case SFmode:
|
||||||
|
if (cum->float_in_sse == -1)
|
||||||
|
error_p = 1;
|
||||||
if (cum->float_in_sse < 1)
|
if (cum->float_in_sse < 1)
|
||||||
break;
|
break;
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
|
@ -7779,6 +7800,14 @@ function_arg_32 (const CUMULATIVE_ARGS *cum, machine_mode mode,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (error_p)
|
||||||
|
{
|
||||||
|
cum->float_in_sse = 0;
|
||||||
|
error ("calling %qD with SSE calling convention without "
|
||||||
|
"SSE/SSE2 enabled", cum->decl);
|
||||||
|
sorry ("this is a GCC bug that can be worked around by adding "
|
||||||
|
"attribute used to function called");
|
||||||
|
}
|
||||||
|
|
||||||
return NULL_RTX;
|
return NULL_RTX;
|
||||||
}
|
}
|
||||||
|
@ -8258,8 +8287,15 @@ function_value_32 (machine_mode orig_mode, machine_mode mode,
|
||||||
if ((fn || fntype) && (mode == SFmode || mode == DFmode))
|
if ((fn || fntype) && (mode == SFmode || mode == DFmode))
|
||||||
{
|
{
|
||||||
int sse_level = ix86_function_sseregparm (fntype, fn, false);
|
int sse_level = ix86_function_sseregparm (fntype, fn, false);
|
||||||
if ((sse_level >= 1 && mode == SFmode)
|
if (sse_level == -1)
|
||||||
|| (sse_level == 2 && mode == DFmode))
|
{
|
||||||
|
error ("calling %qD with SSE caling convention without "
|
||||||
|
"SSE/SSE2 enabled", fn);
|
||||||
|
sorry ("this is a GCC bug that can be worked around by adding "
|
||||||
|
"attribute used to function called");
|
||||||
|
}
|
||||||
|
else if ((sse_level >= 1 && mode == SFmode)
|
||||||
|
|| (sse_level == 2 && mode == DFmode))
|
||||||
regno = FIRST_SSE_REG;
|
regno = FIRST_SSE_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1688,6 +1688,7 @@ typedef struct ix86_args {
|
||||||
int stdarg; /* Set to 1 if function is stdarg. */
|
int stdarg; /* Set to 1 if function is stdarg. */
|
||||||
enum calling_abi call_abi; /* Set to SYSV_ABI for sysv abi. Otherwise
|
enum calling_abi call_abi; /* Set to SYSV_ABI for sysv abi. Otherwise
|
||||||
MS_ABI for ms abi. */
|
MS_ABI for ms abi. */
|
||||||
|
tree decl; /* Callee decl. */
|
||||||
} CUMULATIVE_ARGS;
|
} CUMULATIVE_ARGS;
|
||||||
|
|
||||||
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2015-05-12 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
|
PR target/pr66047.c
|
||||||
|
* gcc.target/i386/pr66047.c: New testcase.
|
||||||
|
|
||||||
2015-05-12 Jan Hubicka <hubicka@ucw.cz>
|
2015-05-12 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
PR ipa/65873
|
PR ipa/65873
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2 -mno-sse" } */
|
||||||
|
/* { dg-require-effective-target ia32 } */
|
||||||
|
__attribute__((target ("sse2"), noinline)) static void
|
||||||
|
foo (void)
|
||||||
|
{
|
||||||
|
asm volatile ("" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bar (void)
|
||||||
|
{
|
||||||
|
foo ();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue