re PR ipa/63566 (i686 bootstrap fails: ICE RTL flag check: INSN_UID used with unexpec...
authorJan Hubicka <hubicka@ucw.cz>
Sun, 8 Feb 2015 21:04:41 +0000 (22:04 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 8 Feb 2015 21:04:41 +0000 (21:04 +0000)
PR ipa/63566
* i386.c (ix86_function_regparm): Look through aliases to see if callee
is local and optimized.
(ix86_function_sseregparm): Likewise; also use target's SSE math
settings; error out instead of silently generating wrong code
on mismatches.
(init_cumulative_args): Look through aliases.

From-SVN: r220520

gcc/ChangeLog
gcc/config/i386/i386.c

index 34598e15b18d9526e03e28a70d5d1dc00f07a9f7..83019f916986e18d574f4f5c60314d246d852b5c 100644 (file)
@@ -1,3 +1,13 @@
+2015-02-08  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/63566 
+       * i386.c (ix86_function_regparm): Look through aliases to see if callee
+       is local and optimized.
+       (ix86_function_sseregparm): Likewise; also use target's SSE math
+       settings; error out instead of silently generating wrong code
+       on mismatches.
+       (init_cumulative_args): Look through aliases.
+
 2015-02-08  Jan Hubicka  <hubicka@ucw.cz>
 
        PR ipa/63566 
index 7f5796ab52e7644651e2c8227c3da232bbba9b90..b39e5077ae15122a3166b8e4c918eae0a56f1ed7 100644 (file)
@@ -5767,49 +5767,55 @@ ix86_function_regparm (const_tree type, const_tree decl)
 
   /* Use register calling convention for local functions when possible.  */
   if (decl
-      && TREE_CODE (decl) == FUNCTION_DECL
+      && TREE_CODE (decl) == FUNCTION_DECL)
+    {
+      cgraph_node *target = cgraph_node::get (decl);
+      if (target)
+       target = target->function_symbol ();
+
       /* Caller and callee must agree on the calling convention, so
         checking here just optimize means that with
         __attribute__((optimize (...))) caller could use regparm convention
         and callee not, or vice versa.  Instead look at whether the callee
         is optimized or not.  */
-      && opt_for_fn (decl, optimize)
-      && !(profile_flag && !flag_fentry))
-    {
-      /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
-      cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE (decl));
-      if (i && i->local && i->can_change_signature)
+      if (target && opt_for_fn (target->decl, optimize)
+         && !(profile_flag && !flag_fentry))
        {
-         int local_regparm, globals = 0, regno;
+         cgraph_local_info *i = &target->local;
+         if (i && i->local && i->can_change_signature)
+           {
+             int local_regparm, globals = 0, regno;
 
-         /* Make sure no regparm register is taken by a
-            fixed register variable.  */
-         for (local_regparm = 0; local_regparm < REGPARM_MAX; local_regparm++)
-           if (fixed_regs[local_regparm])
-             break;
+             /* Make sure no regparm register is taken by a
+                fixed register variable.  */
+             for (local_regparm = 0; local_regparm < REGPARM_MAX;
+                  local_regparm++)
+               if (fixed_regs[local_regparm])
+                 break;
 
-         /* We don't want to use regparm(3) for nested functions as
-            these use a static chain pointer in the third argument.  */
-         if (local_regparm == 3 && DECL_STATIC_CHAIN (decl))
-           local_regparm = 2;
+             /* We don't want to use regparm(3) for nested functions as
+                these use a static chain pointer in the third argument.  */
+             if (local_regparm == 3 && DECL_STATIC_CHAIN (target->decl))
+               local_regparm = 2;
 
-         /* In 32-bit mode save a register for the split stack.  */
-         if (!TARGET_64BIT && local_regparm == 3 && flag_split_stack)
-           local_regparm = 2;
+             /* Save a register for the split stack.  */
+             if (local_regparm == 3 && flag_split_stack)
+               local_regparm = 2;
 
-         /* Each fixed register usage increases register pressure,
-            so less registers should be used for argument passing.
-            This functionality can be overriden by an explicit
-            regparm value.  */
-         for (regno = AX_REG; regno <= DI_REG; regno++)
-           if (fixed_regs[regno])
-             globals++;
+             /* Each fixed register usage increases register pressure,
+                so less registers should be used for argument passing.
+                This functionality can be overriden by an explicit
+                regparm value.  */
+             for (regno = AX_REG; regno <= DI_REG; regno++)
+               if (fixed_regs[regno])
+                 globals++;
 
-         local_regparm
-           = globals < local_regparm ? local_regparm - globals : 0;
+             local_regparm
+               = globals < local_regparm ? local_regparm - globals : 0;
 
-         if (local_regparm > regparm)
-           regparm = local_regparm;
+             if (local_regparm > regparm)
+               regparm = local_regparm;
+           }
        }
     }
 
@@ -5848,15 +5854,37 @@ ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
       return 2;
     }
 
+  if (!decl)
+    return 0;
+
+  cgraph_node *target = cgraph_node::get (decl);
+  if (target)
+    target = target->function_symbol ();
+
   /* For local functions, pass up to SSE_REGPARM_MAX SFmode
      (and DFmode for SSE2) arguments in SSE registers.  */
-  if (decl && TARGET_SSE_MATH && optimize
+  if (target
+      /* TARGET_SSE_MATH */
+      && (target_opts_for_fn (target->decl)->x_ix86_fpmath & FPMATH_SSE)
+      && opt_for_fn (target->decl, optimize)
       && !(profile_flag && !flag_fentry))
     {
-      /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
-      cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE(decl));
+      cgraph_local_info *i = &target->local;
       if (i && i->local && i->can_change_signature)
-       return TARGET_SSE2 ? 2 : 1;
+       {
+         /* 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.  */
+         if (!TARGET_SSE && warn)
+           {
+             error ("calling %qD with SSE caling convention without "
+                    "SSE/SSE2 enabled", decl);
+             return 0;
+           }
+         return TARGET_SSE2_P (target_opts_for_fn (target->decl)
+                               ->x_ix86_isa_flags) ? 2 : 1;
+       }
     }
 
   return 0;
@@ -6343,20 +6371,25 @@ init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
                      tree fndecl,
                      int caller)
 {
-  struct cgraph_local_info *i;
+  struct cgraph_local_info *i = NULL;
+  struct cgraph_node *target = NULL;
 
   memset (cum, 0, sizeof (*cum));
 
   if (fndecl)
     {
-      i = cgraph_node::local_info (fndecl);
-      cum->call_abi = ix86_function_abi (fndecl);
+      target = cgraph_node::get (fndecl);
+      if (target)
+       {
+         target = target->function_symbol ();
+         i = cgraph_node::local_info (target->decl);
+         cum->call_abi = ix86_function_abi (target->decl);
+       }
+      else
+       cum->call_abi = ix86_function_abi (fndecl);
     }
   else
-    {
-      i = NULL;
-      cum->call_abi = ix86_function_type_abi (fntype);
-    }
+    cum->call_abi = ix86_function_type_abi (fntype);
 
   cum->caller = caller;
 
@@ -6392,7 +6425,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
      helping K&R code.
      FIXME: once typesytem is fixed, we won't need this code anymore.  */
   if (i && i->local && i->can_change_signature)
-    fntype = TREE_TYPE (fndecl);
+    fntype = TREE_TYPE (target->decl);
   cum->stdarg = stdarg_p (fntype);
   cum->maybe_vaarg = (fntype
                      ? (!prototype_p (fntype) || stdarg_p (fntype))