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:
Alan Modra 2014-06-06 10:34:22 +09:30 committed by Alan Modra
parent 424ce7d729
commit ddbb449ffe
7 changed files with 92 additions and 21 deletions

View File

@ -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>
PR target/52472

View File

@ -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_va_arg (tree, 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 bool rs6000_elf_in_small_data_p (const_tree);
#ifdef ARGS_SIZE_RTX

View File

@ -10479,35 +10479,65 @@ rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
list, or passes any parameter in memory. */
static bool
rs6000_function_parms_need_stack (tree fun)
rs6000_function_parms_need_stack (tree fun, bool incoming)
{
function_args_iterator args_iter;
tree arg_type;
tree fntype, result;
CUMULATIVE_ARGS args_so_far_v;
cumulative_args_t args_so_far;
if (!fun)
/* Must be a libcall, all of which only use reg parms. */
return false;
fntype = fun;
if (!TYPE_P (fun))
fun = TREE_TYPE (fun);
fntype = TREE_TYPE (fun);
/* Varargs functions need the parameter save area. */
if (!prototype_p (fun) || stdarg_p (fun))
if ((!incoming && !prototype_p (fntype)) || stdarg_p (fntype))
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);
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));
rs6000_parm_needs_stack (args_so_far, type);
gcc_assert (DECL_P (fun));
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 (rs6000_parm_needs_stack (args_so_far, arg_type))
return true;
if (incoming)
{
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;
}
@ -10519,7 +10549,7 @@ rs6000_function_parms_need_stack (tree fun)
all parameters in registers. */
int
rs6000_reg_parm_stack_space (tree fun)
rs6000_reg_parm_stack_space (tree fun, bool incoming)
{
int reg_parm_stack_space;
@ -10537,7 +10567,7 @@ rs6000_reg_parm_stack_space (tree fun)
case ABI_ELFv2:
/* ??? Recomputing this every time is a bit expensive. Is there
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;
else
reg_parm_stack_space = 0;

View File

@ -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
in a register. The value is the number of bytes allocated to this
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
space allocated by the caller. */

View File

@ -3799,6 +3799,13 @@ which.
@c above is overfull. not sure what to do. --mew 5feb93 did
@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})
Define this to a nonzero value if it is the responsibility of the
caller to allocate the area reserved for arguments passed in registers

View File

@ -3351,6 +3351,13 @@ which.
@c above is overfull. not sure what to do. --mew 5feb93 did
@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})
Define this to a nonzero value if it is the responsibility of the
caller to allocate the area reserved for arguments passed in registers

View File

@ -1348,9 +1348,13 @@ static int cfa_offset;
#define STACK_POINTER_OFFSET 0
#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
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
@ -1362,12 +1366,12 @@ static int cfa_offset;
`crtl->outgoing_args_size'. Nevertheless, we must allow
for it when allocating stack dynamic objects. */
#if defined(REG_PARM_STACK_SPACE)
#ifdef INCOMING_REG_PARM_STACK_SPACE
#define STACK_DYNAMIC_OFFSET(FNDECL) \
((ACCUMULATE_OUTGOING_ARGS \
? (crtl->outgoing_args_size \
+ (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))
#else
#define STACK_DYNAMIC_OFFSET(FNDECL) \
@ -2224,8 +2228,9 @@ assign_parms_initialize_all (struct assign_parm_data_all *all)
#endif
all->args_so_far = pack_cumulative_args (&all->args_so_far_v);
#ifdef REG_PARM_STACK_SPACE
all->reg_parm_stack_space = REG_PARM_STACK_SPACE (current_function_decl);
#ifdef INCOMING_REG_PARM_STACK_SPACE
all->reg_parm_stack_space
= INCOMING_REG_PARM_STACK_SPACE (current_function_decl);
#endif
}