------- Comment #5 from ramana at gcc dot gnu dot org 2010-07-06 22:29 -------
The problem essentially is a miscompilation of diagnostic_action_after_output
in this case .
Attached is a testcase that demonstrates this problem with a cross compiler.
Configure just the compiler with arm-linux-gnueabi and you can see the
problem.
diagnostic_action_after_output.isra.1:
@ Volatile: function does not return. ---> There we go ! Treating this
function as a NORETURN function when it clearly is *not* .
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
sub r1, r1, #2
stmfd sp!, {r3, lr} --> Not saved in the set of callee saved
registers ...
mov r4, r0 --> r4 is clobbered and is a callee saved register.
cmp r1, #7
ldrls pc, [pc, r1, asl #2]
b .L69
.L74:
.word .L70
.word .L71
.word .L72
.word .L72
.word .L68
.word .L68
.word .L68
.word .L68
.L72:
ldrb r3, [r0, #65] @ zero_extendqisi2
cmp r3, #0
>From a session in gdb. As you can see the call to arm_compute_func_type is the
one that causes the problems here. arm_compute_func_type decides whether a
function is volatile or not depending on the value of TREE_THIS_VOLATILE for
current_function_decl. This allows the compiler to do optimizations that remove
the save of callee save registers in such volatile functions.
#0 arm_compute_func_type () at
/work/fsfwork/svn/trunk/gcc/config/arm/arm.c:1949
#1 0x000000000094a764 in arm_current_func_type () at
/work/fsfwork/svn/trunk/gcc/config/arm/arm.c:1993
#2 0x000000000094a787 in arm_allocate_stack_slots_for_args () at
/work/fsfwork/svn/trunk/gcc/config/arm/arm.c:2002
#3 0x000000000060da5e in use_register_for_decl (decl=0x2b5ae7029960) at
/work/fsfwork/svn/trunk/gcc/function.c:2015
#4 0x00000000004e5251 in expand_one_var (var=0x2b5ae7029960, toplevel=1
'\001', really_expand=0 '\0') at /work/fsfwork/svn/trunk/gcc/cfgexpand.c:983
#5 0x00000000004e5fcb in estimated_stack_frame_size () at
/work/fsfwork/svn/trunk/gcc/cfgexpand.c:1276
#6 0x000000000098d855 in compute_inline_parameters (node=0x2b5ae6f2cc18) at
/work/fsfwork/svn/trunk/gcc/ipa-inline.c:2022
#7 0x000000000080b631 in convert_callers (node=0x2b5ae6d89158,
old_decl=0x2b5ae6f1ff00, adjustments=0x4384680) at
/work/fsfwork/svn/trunk/gcc/tree-sra.c:4212
#8 0x000000000080b96c in modify_function (node=0x2b5ae6f2c560,
adjustments=0x4384680) at /work/fsfwork/svn/trunk/gcc/tree-sra.c:4276
#9 0x000000000080be6f in ipa_early_sra () at
/work/fsfwork/svn/trunk/gcc/tree-sra.c:4395
#10 0x00000000006ca396 in execute_one_pass (pass=0x1118480) at
/work/fsfwork/svn/trunk/gcc/passes.c:1565
#11 0x00000000006ca4ec in execute_pass_list (pass=0x1118480) at
/work/fsfwork/svn/trunk/gcc/passes.c:1620
#12 0x00000000006ca505 in execute_pass_list (pass=0x11181e0) at
/work/fsfwork/svn/trunk/gcc/passes.c:1621
#13 0x00000000006c998b in do_per_function_toporder (callback=0x6ca4d0
<execute_pass_list>, data=0x11180c0) at
/work/fsfwork/svn/trunk/gcc/passes.c:1158
#14 0x00000000006cad17 in execute_ipa_pass_list (pass=0x1118240) at
/work/fsfwork/svn/trunk/gcc/passes.c:1920
#15 0x0000000000982269 in cgraph_optimize () at
/work/fsfwork/svn/trunk/gcc/cgraphunit.c:1851
#16 0x00000000009824ea in cgraph_finalize_compilation_unit () at
/work/fsfwork/svn/trunk/gcc/cgraphunit.c:1171
#17 0x0000000000418b34 in c_write_global_declarations () at
/work/fsfwork/svn/trunk/gcc/c-decl.c:9698
#18 0x000000000076ee64 in toplev_main (argc=4, argv=0x7fffc3eda328) at
/work/fsfwork/svn/trunk/gcc/toplev.c:997
(gdb) p current_function_name ()
$3 = 0x2b5ae7024bb8 "diagnostic_action_after_output.isra.1"
(gdb) p current_function_decl
$4 = (tree) 0x2b5ae6f1fe00
(gdb) pct
error_recursion
(gdb) p cfun->decl
$5 = (tree) 0x2b5ae703c500
(gdb) pct
diagnostic_action_after_output.isra.1
Notice that cfun->decl and current_function_decl are different here because the
context hasn't been set up correctly in tree-sra.c . The following patch
appears to fix it by correctly not setting the function to be non-volatile.
Index: tree-sra.c
===================================================================
--- tree-sra.c (revision 161870)
+++ tree-sra.c (working copy)
@@ -4209,8 +4209,11 @@ convert_callers (struct cgraph_node *nod
for (cs = node->callers; cs; cs = cs->next_caller)
if (!bitmap_bit_p (recomputed_callers, cs->caller->uid))
{
+ current_function_decl = cs->caller->decl;
+ push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
compute_inline_parameters (cs->caller);
bitmap_set_bit (recomputed_callers, cs->caller->uid);
+ pop_cfun ();
}
BITMAP_FREE (recomputed_callers);
After the patch was applied on a cross-compiler
diagnostic_action_after_output.isra.1:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
sub r1, r1, #2
stmfd sp!, {r4, lr} -> Notice the save of r4 on the stack.
mov r4, r0
Now bootstrapping on arm-linux-gnueabi.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44768