mirror of git://gcc.gnu.org/git/gcc.git
re PR target/61300 (powerpc64le miscompile with K&R-style function definition at -O0)
PR target/61300 * doc/tm.texi.in (INCOMING_REG_PARM_STACK_SPACE): Document. * doc/tm.texi: Regenerate. * function.c (INCOMING_REG_PARM_STACK_SPACE): Provide default. Use throughout in place of REG_PARM_STACK_SPACE. * config/rs6000/rs6000.c (rs6000_reg_parm_stack_space): Add "incoming" param. Pass to rs6000_function_parms_need_stack. (rs6000_function_parms_need_stack): Add "incoming" param, ignore prototype_p when incoming. Use function decl when incoming to handle K&R style functions. * config/rs6000/rs6000.h (REG_PARM_STACK_SPACE): Adjust. (INCOMING_REG_PARM_STACK_SPACE): Define. From-SVN: r211296
This commit is contained in:
parent
424ce7d729
commit
ddbb449ffe
|
|
@ -1,3 +1,18 @@
|
||||||
|
2014-06-06 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR target/61300
|
||||||
|
* doc/tm.texi.in (INCOMING_REG_PARM_STACK_SPACE): Document.
|
||||||
|
* doc/tm.texi: Regenerate.
|
||||||
|
* function.c (INCOMING_REG_PARM_STACK_SPACE): Provide default.
|
||||||
|
Use throughout in place of REG_PARM_STACK_SPACE.
|
||||||
|
* config/rs6000/rs6000.c (rs6000_reg_parm_stack_space): Add
|
||||||
|
"incoming" param. Pass to rs6000_function_parms_need_stack.
|
||||||
|
(rs6000_function_parms_need_stack): Add "incoming" param, ignore
|
||||||
|
prototype_p when incoming. Use function decl when incoming
|
||||||
|
to handle K&R style functions.
|
||||||
|
* config/rs6000/rs6000.h (REG_PARM_STACK_SPACE): Adjust.
|
||||||
|
(INCOMING_REG_PARM_STACK_SPACE): Define.
|
||||||
|
|
||||||
2014-06-05 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
|
2014-06-05 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
|
||||||
|
|
||||||
PR target/52472
|
PR target/52472
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ extern tree altivec_resolve_overloaded_builtin (location_t, tree, void *);
|
||||||
extern rtx rs6000_libcall_value (enum machine_mode);
|
extern rtx rs6000_libcall_value (enum machine_mode);
|
||||||
extern rtx rs6000_va_arg (tree, tree);
|
extern rtx rs6000_va_arg (tree, tree);
|
||||||
extern int function_ok_for_sibcall (tree);
|
extern int function_ok_for_sibcall (tree);
|
||||||
extern int rs6000_reg_parm_stack_space (tree);
|
extern int rs6000_reg_parm_stack_space (tree, bool);
|
||||||
extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
|
extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
|
||||||
extern bool rs6000_elf_in_small_data_p (const_tree);
|
extern bool rs6000_elf_in_small_data_p (const_tree);
|
||||||
#ifdef ARGS_SIZE_RTX
|
#ifdef ARGS_SIZE_RTX
|
||||||
|
|
|
||||||
|
|
@ -10479,35 +10479,65 @@ rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
|
||||||
list, or passes any parameter in memory. */
|
list, or passes any parameter in memory. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
rs6000_function_parms_need_stack (tree fun)
|
rs6000_function_parms_need_stack (tree fun, bool incoming)
|
||||||
{
|
{
|
||||||
function_args_iterator args_iter;
|
tree fntype, result;
|
||||||
tree arg_type;
|
|
||||||
CUMULATIVE_ARGS args_so_far_v;
|
CUMULATIVE_ARGS args_so_far_v;
|
||||||
cumulative_args_t args_so_far;
|
cumulative_args_t args_so_far;
|
||||||
|
|
||||||
if (!fun)
|
if (!fun)
|
||||||
/* Must be a libcall, all of which only use reg parms. */
|
/* Must be a libcall, all of which only use reg parms. */
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
fntype = fun;
|
||||||
if (!TYPE_P (fun))
|
if (!TYPE_P (fun))
|
||||||
fun = TREE_TYPE (fun);
|
fntype = TREE_TYPE (fun);
|
||||||
|
|
||||||
/* Varargs functions need the parameter save area. */
|
/* Varargs functions need the parameter save area. */
|
||||||
if (!prototype_p (fun) || stdarg_p (fun))
|
if ((!incoming && !prototype_p (fntype)) || stdarg_p (fntype))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
INIT_CUMULATIVE_INCOMING_ARGS (args_so_far_v, fun, NULL_RTX);
|
INIT_CUMULATIVE_INCOMING_ARGS (args_so_far_v, fntype, NULL_RTX);
|
||||||
args_so_far = pack_cumulative_args (&args_so_far_v);
|
args_so_far = pack_cumulative_args (&args_so_far_v);
|
||||||
|
|
||||||
if (aggregate_value_p (TREE_TYPE (fun), fun))
|
/* When incoming, we will have been passed the function decl.
|
||||||
|
It is necessary to use the decl to handle K&R style functions,
|
||||||
|
where TYPE_ARG_TYPES may not be available. */
|
||||||
|
if (incoming)
|
||||||
{
|
{
|
||||||
tree type = build_pointer_type (TREE_TYPE (fun));
|
gcc_assert (DECL_P (fun));
|
||||||
rs6000_parm_needs_stack (args_so_far, type);
|
result = DECL_RESULT (fun);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = TREE_TYPE (fntype);
|
||||||
|
|
||||||
|
if (result && aggregate_value_p (result, fntype))
|
||||||
|
{
|
||||||
|
if (!TYPE_P (result))
|
||||||
|
result = TREE_TYPE (result);
|
||||||
|
result = build_pointer_type (result);
|
||||||
|
rs6000_parm_needs_stack (args_so_far, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
FOREACH_FUNCTION_ARGS (fun, arg_type, args_iter)
|
if (incoming)
|
||||||
if (rs6000_parm_needs_stack (args_so_far, arg_type))
|
{
|
||||||
return true;
|
tree parm;
|
||||||
|
|
||||||
|
for (parm = DECL_ARGUMENTS (fun);
|
||||||
|
parm && parm != void_list_node;
|
||||||
|
parm = TREE_CHAIN (parm))
|
||||||
|
if (rs6000_parm_needs_stack (args_so_far, TREE_TYPE (parm)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
function_args_iterator args_iter;
|
||||||
|
tree arg_type;
|
||||||
|
|
||||||
|
FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
|
||||||
|
if (rs6000_parm_needs_stack (args_so_far, arg_type))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -10519,7 +10549,7 @@ rs6000_function_parms_need_stack (tree fun)
|
||||||
all parameters in registers. */
|
all parameters in registers. */
|
||||||
|
|
||||||
int
|
int
|
||||||
rs6000_reg_parm_stack_space (tree fun)
|
rs6000_reg_parm_stack_space (tree fun, bool incoming)
|
||||||
{
|
{
|
||||||
int reg_parm_stack_space;
|
int reg_parm_stack_space;
|
||||||
|
|
||||||
|
|
@ -10537,7 +10567,7 @@ rs6000_reg_parm_stack_space (tree fun)
|
||||||
case ABI_ELFv2:
|
case ABI_ELFv2:
|
||||||
/* ??? Recomputing this every time is a bit expensive. Is there
|
/* ??? Recomputing this every time is a bit expensive. Is there
|
||||||
a place to cache this information? */
|
a place to cache this information? */
|
||||||
if (rs6000_function_parms_need_stack (fun))
|
if (rs6000_function_parms_need_stack (fun, incoming))
|
||||||
reg_parm_stack_space = TARGET_64BIT ? 64 : 32;
|
reg_parm_stack_space = TARGET_64BIT ? 64 : 32;
|
||||||
else
|
else
|
||||||
reg_parm_stack_space = 0;
|
reg_parm_stack_space = 0;
|
||||||
|
|
|
||||||
|
|
@ -1602,7 +1602,14 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
|
||||||
/* Define this if stack space is still allocated for a parameter passed
|
/* Define this if stack space is still allocated for a parameter passed
|
||||||
in a register. The value is the number of bytes allocated to this
|
in a register. The value is the number of bytes allocated to this
|
||||||
area. */
|
area. */
|
||||||
#define REG_PARM_STACK_SPACE(FNDECL) rs6000_reg_parm_stack_space((FNDECL))
|
#define REG_PARM_STACK_SPACE(FNDECL) \
|
||||||
|
rs6000_reg_parm_stack_space ((FNDECL), false)
|
||||||
|
|
||||||
|
/* Define this macro if space guaranteed when compiling a function body
|
||||||
|
is different to space required when making a call, a situation that
|
||||||
|
can arise with K&R style function definitions. */
|
||||||
|
#define INCOMING_REG_PARM_STACK_SPACE(FNDECL) \
|
||||||
|
rs6000_reg_parm_stack_space ((FNDECL), true)
|
||||||
|
|
||||||
/* Define this if the above stack space is to be considered part of the
|
/* Define this if the above stack space is to be considered part of the
|
||||||
space allocated by the caller. */
|
space allocated by the caller. */
|
||||||
|
|
|
||||||
|
|
@ -3799,6 +3799,13 @@ which.
|
||||||
@c above is overfull. not sure what to do. --mew 5feb93 did
|
@c above is overfull. not sure what to do. --mew 5feb93 did
|
||||||
@c something, not sure if it looks good. --mew 10feb93
|
@c something, not sure if it looks good. --mew 10feb93
|
||||||
|
|
||||||
|
@defmac INCOMING_REG_PARM_STACK_SPACE (@var{fndecl})
|
||||||
|
Like @code{REG_PARM_STACK_SPACE}, but for incoming register arguments.
|
||||||
|
Define this macro if space guaranteed when compiling a function body
|
||||||
|
is different to space required when making a call, a situation that
|
||||||
|
can arise with K&R style function definitions.
|
||||||
|
@end defmac
|
||||||
|
|
||||||
@defmac OUTGOING_REG_PARM_STACK_SPACE (@var{fntype})
|
@defmac OUTGOING_REG_PARM_STACK_SPACE (@var{fntype})
|
||||||
Define this to a nonzero value if it is the responsibility of the
|
Define this to a nonzero value if it is the responsibility of the
|
||||||
caller to allocate the area reserved for arguments passed in registers
|
caller to allocate the area reserved for arguments passed in registers
|
||||||
|
|
|
||||||
|
|
@ -3351,6 +3351,13 @@ which.
|
||||||
@c above is overfull. not sure what to do. --mew 5feb93 did
|
@c above is overfull. not sure what to do. --mew 5feb93 did
|
||||||
@c something, not sure if it looks good. --mew 10feb93
|
@c something, not sure if it looks good. --mew 10feb93
|
||||||
|
|
||||||
|
@defmac INCOMING_REG_PARM_STACK_SPACE (@var{fndecl})
|
||||||
|
Like @code{REG_PARM_STACK_SPACE}, but for incoming register arguments.
|
||||||
|
Define this macro if space guaranteed when compiling a function body
|
||||||
|
is different to space required when making a call, a situation that
|
||||||
|
can arise with K&R style function definitions.
|
||||||
|
@end defmac
|
||||||
|
|
||||||
@defmac OUTGOING_REG_PARM_STACK_SPACE (@var{fntype})
|
@defmac OUTGOING_REG_PARM_STACK_SPACE (@var{fntype})
|
||||||
Define this to a nonzero value if it is the responsibility of the
|
Define this to a nonzero value if it is the responsibility of the
|
||||||
caller to allocate the area reserved for arguments passed in registers
|
caller to allocate the area reserved for arguments passed in registers
|
||||||
|
|
|
||||||
|
|
@ -1348,9 +1348,13 @@ static int cfa_offset;
|
||||||
#define STACK_POINTER_OFFSET 0
|
#define STACK_POINTER_OFFSET 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined (REG_PARM_STACK_SPACE) && !defined (INCOMING_REG_PARM_STACK_SPACE)
|
||||||
|
#define INCOMING_REG_PARM_STACK_SPACE REG_PARM_STACK_SPACE
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If not defined, pick an appropriate default for the offset of dynamically
|
/* If not defined, pick an appropriate default for the offset of dynamically
|
||||||
allocated memory depending on the value of ACCUMULATE_OUTGOING_ARGS,
|
allocated memory depending on the value of ACCUMULATE_OUTGOING_ARGS,
|
||||||
REG_PARM_STACK_SPACE, and OUTGOING_REG_PARM_STACK_SPACE. */
|
INCOMING_REG_PARM_STACK_SPACE, and OUTGOING_REG_PARM_STACK_SPACE. */
|
||||||
|
|
||||||
#ifndef STACK_DYNAMIC_OFFSET
|
#ifndef STACK_DYNAMIC_OFFSET
|
||||||
|
|
||||||
|
|
@ -1362,12 +1366,12 @@ static int cfa_offset;
|
||||||
`crtl->outgoing_args_size'. Nevertheless, we must allow
|
`crtl->outgoing_args_size'. Nevertheless, we must allow
|
||||||
for it when allocating stack dynamic objects. */
|
for it when allocating stack dynamic objects. */
|
||||||
|
|
||||||
#if defined(REG_PARM_STACK_SPACE)
|
#ifdef INCOMING_REG_PARM_STACK_SPACE
|
||||||
#define STACK_DYNAMIC_OFFSET(FNDECL) \
|
#define STACK_DYNAMIC_OFFSET(FNDECL) \
|
||||||
((ACCUMULATE_OUTGOING_ARGS \
|
((ACCUMULATE_OUTGOING_ARGS \
|
||||||
? (crtl->outgoing_args_size \
|
? (crtl->outgoing_args_size \
|
||||||
+ (OUTGOING_REG_PARM_STACK_SPACE ((!(FNDECL) ? NULL_TREE : TREE_TYPE (FNDECL))) ? 0 \
|
+ (OUTGOING_REG_PARM_STACK_SPACE ((!(FNDECL) ? NULL_TREE : TREE_TYPE (FNDECL))) ? 0 \
|
||||||
: REG_PARM_STACK_SPACE (FNDECL))) \
|
: INCOMING_REG_PARM_STACK_SPACE (FNDECL))) \
|
||||||
: 0) + (STACK_POINTER_OFFSET))
|
: 0) + (STACK_POINTER_OFFSET))
|
||||||
#else
|
#else
|
||||||
#define STACK_DYNAMIC_OFFSET(FNDECL) \
|
#define STACK_DYNAMIC_OFFSET(FNDECL) \
|
||||||
|
|
@ -2224,8 +2228,9 @@ assign_parms_initialize_all (struct assign_parm_data_all *all)
|
||||||
#endif
|
#endif
|
||||||
all->args_so_far = pack_cumulative_args (&all->args_so_far_v);
|
all->args_so_far = pack_cumulative_args (&all->args_so_far_v);
|
||||||
|
|
||||||
#ifdef REG_PARM_STACK_SPACE
|
#ifdef INCOMING_REG_PARM_STACK_SPACE
|
||||||
all->reg_parm_stack_space = REG_PARM_STACK_SPACE (current_function_decl);
|
all->reg_parm_stack_space
|
||||||
|
= INCOMING_REG_PARM_STACK_SPACE (current_function_decl);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue