re PR target/44290 (__naked attribute is broken)

PR target/44290
	* attribs.c (decl_attributes): Insert "noinline" and "noclone"
	if "naked".
	* tree-sra.c (ipa_sra_preliminary_function_checks): Return
	false if ! tree_versionable_function_p.

	testsuite/
	PR target/44290
	* gcc.dg/pr44290-1.c: New test.
	* gcc.dg/pr44290-2.c: New test.

From-SVN: r162466
This commit is contained in:
Jie Zhang 2010-07-23 14:47:46 +00:00 committed by Jie Zhang
parent 9477ccb2b1
commit 6104449219
6 changed files with 76 additions and 0 deletions

View file

@ -1,3 +1,11 @@
2010-07-23 Jie Zhang <jie@codesourcery.com>
PR target/44290
* attribs.c (decl_attributes): Insert "noinline" and "noclone"
if "naked".
* tree-sra.c (ipa_sra_preliminary_function_checks): Return
false if ! tree_versionable_function_p.
2010-07-23 Nathan Froyd <froydnj@codesourcery.com>
* builtins.def (BUILT_IN_ARGS_INFO): Remove.

View file

@ -276,6 +276,19 @@ decl_attributes (tree *node, tree attributes, int flags)
TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
}
/* A "naked" function attribute implies "noinline" and "noclone" for
those targets that support it. */
if (TREE_CODE (*node) == FUNCTION_DECL
&& lookup_attribute_spec (get_identifier ("naked"))
&& lookup_attribute ("naked", attributes) != NULL)
{
if (lookup_attribute ("noinline", attributes) == NULL)
attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
if (lookup_attribute ("noclone", attributes) == NULL)
attributes = tree_cons (get_identifier ("noclone"), NULL, attributes);
}
targetm.insert_attributes (*node, &attributes);
for (a = attributes; a; a = TREE_CHAIN (a))

View file

@ -1,3 +1,9 @@
2010-07-23 Jie Zhang <jie@codesourcery.com>
PR target/44290
* gcc.dg/pr44290-1.c: New test.
* gcc.dg/pr44290-2.c: New test.
2010-07-23 Jason Merrill <jason@redhat.com>
PR c++/45008

View file

@ -0,0 +1,18 @@
/* { dg-do compile { target arm*-*-* avr-*-* mcore-*-* rx-*-* spu-*-* } } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
static void __attribute__((naked))
foo(void *from, void *to)
{
asm volatile("dummy"::"r"(from), "r"(to));
}
unsigned int fie[2];
void fum(void *to)
{
foo(fie, to);
}
/* { dg-final { scan-tree-dump "foo \\\(void \\\* from, void \\\* to\\\)" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View file

@ -0,0 +1,24 @@
/* { dg-do compile { target arm*-*-* avr-*-* mcore-*-* rx-*-* spu-*-* } } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
static unsigned long __attribute__((naked))
foo (unsigned long base)
{
asm volatile ("dummy");
}
unsigned long
bar (void)
{
static int start, set;
if (!set)
{
set = 1;
start = foo (0);
}
return foo (start);
}
/* { dg-final { scan-tree-dump "foo \\\(long unsigned int base\\\)" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View file

@ -4301,6 +4301,13 @@ modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
static bool
ipa_sra_preliminary_function_checks (struct cgraph_node *node)
{
if (!tree_versionable_function_p (current_function_decl))
{
if (dump_file)
fprintf (dump_file, "Function isn't allowed to be versioned.\n");
return false;
}
if (!cgraph_node_can_be_local_p (node))
{
if (dump_file)