------- 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

Reply via email to