aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-05-13 05:35:09 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2015-05-13 03:35:09 +0000
commite66fc62389b36c6f544d9960dc0acf08f9c55b37 (patch)
tree305dd37a74f45200746b4c315e45feb7143fff32
parente4b5b3a5cb422662b1c4ef1102bf559082017ac3 (diff)
downloadgcc-e66fc62389b36c6f544d9960dc0acf08f9c55b37.zip
gcc-e66fc62389b36c6f544d9960dc0acf08f9c55b37.tar.gz
gcc-e66fc62389b36c6f544d9960dc0acf08f9c55b37.tar.bz2
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
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/i386/i386.c58
-rw-r--r--gcc/config/i386/i386.h1
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr66047.c15
5 files changed, 79 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3da39da..ea1909f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
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>
+
PR ipa/65873
* ipa-inline.c (can_inline_edge_p): Allow early inlining of always
inlines across optimization boundary.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d87dd01..fd52d89 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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
DFmode (2) arguments in SSE registers for a function with the
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
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
is called from SSE disabled function.
- We may work hard to work out these scenarios but hopefully
- it doesnot matter in practice. */
+ FIXME: We need a way to detect these cases cross-ltrans partition
+ 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)
- {
- error ("calling %qD with SSE caling convention without "
- "SSE/SSE2 enabled", decl);
- return 0;
- }
+ return -1;
return TARGET_SSE2_P (target_opts_for_fn (target->decl)
->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->bnds_in_bt = 0;
cum->force_bnd_pass = 0;
+ cum->decl = fndecl;
if (!TARGET_64BIT)
{
@@ -7452,6 +7455,7 @@ function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
HOST_WIDE_INT words)
{
int res = 0;
+ bool error_p = NULL;
switch (mode)
{
@@ -7484,9 +7488,13 @@ function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
gcc_unreachable ();
case DFmode:
+ if (cum->float_in_sse == -1)
+ error_p = 1;
if (cum->float_in_sse < 2)
break;
case SFmode:
+ if (cum->float_in_sse == -1)
+ error_p = 1;
if (cum->float_in_sse < 1)
break;
/* FALLTHRU */
@@ -7542,6 +7550,14 @@ function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
}
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;
}
@@ -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). */
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,
HOST_WIDE_INT bytes, HOST_WIDE_INT words)
{
+ bool error_p = false;
/* Avoid the AL settings for the Unix64 ABI. */
if (mode == VOIDmode)
return constm1_rtx;
@@ -7718,9 +7735,13 @@ function_arg_32 (const CUMULATIVE_ARGS *cum, machine_mode mode,
break;
case DFmode:
+ if (cum->float_in_sse == -1)
+ error_p = 1;
if (cum->float_in_sse < 2)
break;
case SFmode:
+ if (cum->float_in_sse == -1)
+ error_p = 1;
if (cum->float_in_sse < 1)
break;
/* FALLTHRU */
@@ -7779,6 +7800,14 @@ function_arg_32 (const CUMULATIVE_ARGS *cum, machine_mode mode,
}
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;
}
@@ -8258,8 +8287,15 @@ function_value_32 (machine_mode orig_mode, machine_mode mode,
if ((fn || fntype) && (mode == SFmode || mode == DFmode))
{
int sse_level = ix86_function_sseregparm (fntype, fn, false);
- if ((sse_level >= 1 && mode == SFmode)
- || (sse_level == 2 && mode == DFmode))
+ if (sse_level == -1)
+ {
+ 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;
}
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 24ff911..5279b2d 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1688,6 +1688,7 @@ typedef struct ix86_args {
int stdarg; /* Set to 1 if function is stdarg. */
enum calling_abi call_abi; /* Set to SYSV_ABI for sysv abi. Otherwise
MS_ABI for ms abi. */
+ tree decl; /* Callee decl. */
} CUMULATIVE_ARGS;
/* Initialize a variable CUM of type CUMULATIVE_ARGS
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fedfe43..d16a870 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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>
+
PR ipa/65873
* gcc.c-torture/compile/pr65873.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/i386/pr66047.c b/gcc/testsuite/gcc.target/i386/pr66047.c
new file mode 100644
index 0000000..60eefe4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66047.c
@@ -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 ();
+}
+