From ead0ba5768adbf6a275dff580a1bf3e06d677bc8 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 8 Feb 2015 22:04:41 +0100 Subject: [PATCH] re PR ipa/63566 (i686 bootstrap fails: ICE RTL flag check: INSN_UID used with unexpected rtx code 'set' in INSN_UID, at rtl.h:1326) 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 | 10 ++++ gcc/config/i386/i386.c | 119 ++++++++++++++++++++++++++--------------- 2 files changed, 86 insertions(+), 43 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 34598e15b18..83019f91698 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-02-08 Jan Hubicka + + 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 PR ipa/63566 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7f5796ab52e..b39e5077ae1 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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)) -- 2.30.2