re PR c/84229 (A valid code rejected with -flto)
authorJan Hubicka <hubicka@ucw.cz>
Wed, 21 Feb 2018 19:05:30 +0000 (20:05 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 21 Feb 2018 19:05:30 +0000 (19:05 +0000)
PR c/84229
* ipa-cp.c (determine_versionability): Do not version functions caling
va_arg_pack.

From-SVN: r257877

gcc/ChangeLog
gcc/ipa-cp.c

index 14326080acdd97edd89dedd4aa66929412e2776e..2bc276eb9f2140d7aeae2abf858a3947475ae897 100644 (file)
@@ -1,3 +1,9 @@
+2018-02-21  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR c/84229
+       * ipa-cp.c (determine_versionability): Do not version functions caling
+       va_arg_pack.
+
 2018-02-21  Martin Liska  <mliska@suse.cz>
 
        PR driver/83193
index 4202c9996751a315da8eb787ab3a9fe03e87a568..182dc498364a15896685eccef43b8a43e515d80d 100644 (file)
@@ -630,6 +630,24 @@ determine_versionability (struct cgraph_node *node,
       reason = "calls comdat-local function";
     }
 
+  /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN
+     works only when inlined.  Cloning them may still lead to better code
+     becuase ipa-cp will not give up on cloning further.  If the function is
+     external this however leads to wrong code becuase we may end up producing
+     offline copy of the function.  */
+  if (DECL_EXTERNAL (node->decl))
+    for (cgraph_edge *edge = node->callees; !reason && edge;
+        edge = edge->next_callee)
+      if (DECL_BUILT_IN (edge->callee->decl)
+         && DECL_BUILT_IN_CLASS (edge->callee->decl) == BUILT_IN_NORMAL)
+        {
+         if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK)
+           reason = "external function which calls va_arg_pack";
+         if (DECL_FUNCTION_CODE (edge->callee->decl)
+             == BUILT_IN_VA_ARG_PACK_LEN)
+           reason = "external function which calls va_arg_pack_len";
+        }
+
   if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
     fprintf (dump_file, "Function %s is not versionable, reason: %s.\n",
             node->dump_name (), reason);