]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/66047 (vlc compilation failure with target attribute)
authorJan Hubicka <hubicka@ucw.cz>
Wed, 13 May 2015 03:35:09 +0000 (05:35 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 13 May 2015 03:35:09 +0000 (03:35 +0000)
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

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr66047.c [new file with mode: 0644]

index 3da39da22e50a43ab73f1db7fb94bee2a60ba74a..ea1909fd24ef71f52b2bda03c9b752b89eadec6e 100644 (file)
@@ -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>
 
        PR ipa/65873
index d87dd01f0a7087696008b7f158d2d55c156f2b91..fd52d891257bdaee6bdfcf05210d2255f2c5f660 100644 (file)
@@ -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;
     }
 
index 24ff911df9eea388b936780ce1ceb3b72c6671ea..5279b2d36c3c93358cf744003021533e3323a491 100644 (file)
@@ -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
index fedfe4396285c0b1ea41f1f00773d2ce0ebdfe53..d16a8707fc59300ba09c441b210cde03e8e3a735 100644 (file)
@@ -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>
 
        PR ipa/65873
diff --git a/gcc/testsuite/gcc.target/i386/pr66047.c b/gcc/testsuite/gcc.target/i386/pr66047.c
new file mode 100644 (file)
index 0000000..60eefe4
--- /dev/null
@@ -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 ();
+}
+