Hi, I met a bug in my gcc porting. It work fine when executing with -O0. But with -Os, there is a insn missed. I dumped the RTL and checked them. When in movebug.c.175r.lreg, it is fine. But in next phase -- movebug.c.176r.greg, the insn missed.
Here is the simple c program (movebug.c): void fun() __attribute__((noinline)); void fun() { volatile int a=0; } int main() { int i; for(i=2; i<16; ++i) { fun(); } return 0; } In *.175r.lreg, the RTL code is: (insn:HI 6 3 8 2 movebug.c:8 (set (reg/v:SI 37 [ i ]) (const_int 2 [0x2])) 2 {constant_load_si} (expr_list:REG_EQUAL (const_int 2 [0x2]) (nil))) (insn:HI 8 6 11 2 movebug.c:12 (set (reg/f:SI 42) (symbol_ref:SI ("fun") [flags 0x3] <function_decl 0xb729ba10 fun>)) 15 {symbolic_address_load} (expr_list:REG_EQUIV (symbol_ref:SI ("fun") [flags 0x3] <function_decl 0xb729ba10 fun>) (nil))) (code_label:HI 11 8 7 3 4 "" [1 uses]) (note:HI 7 11 10 3 [bb 3] NOTE_INSN_BASIC_BLOCK) (insn:HI 10 7 9 3 movebug.c:10 (set (reg/v:SI 37 [ i ]) (plus:SI (reg/v:SI 37 [ i ]) (const_int 1 [0x1]))) 45 {rice_addsi3} (nil)) (call_insn:HI 9 10 13 3 movebug.c:12 (parallel [ (call (mem:SI (reg/f:SI 42) [0 S4 A32]) (const_int 0 [0x0])) (clobber (reg:SI 17 LINK)) ]) 99 {call} (expr_list:REG_EH_REGION (const_int 0 [0x0]) (nil)) (nil)) The "fun" function address will be first loaded into register, and then CALL insn will refer this register which means call the function. The *.sched1 give the data flow: ;; ====================================================== ;; -- basic block 2 from 6 to 8 -- before reload ;; ====================================================== ;; 0--> 6 r37=0x2 :nothing ;; 1--> 8 r42=`fun' :nothing ;; Ready list (final): ;; total time = 1 ;; new head = 6 ;; new tail = 8 ;; ====================================================== ;; -- basic block 3 from 9 to 13 -- before reload ;; ====================================================== changing bb of uid 10 ;; 0--> 10 r37=r37+0x1 :nothing ;; 1--> 9 call [r42] :nothing ;; 2--> 13 pc={(r37!=0x10)?L11:pc} :nothing ;; Ready list (final): ;; total time = 2 ;; new head = 10 ;; new tail = 13 ;; ====================================================== ;; -- basic block 4 from 19 to 25 -- before reload ;; ====================================================== ;; 0--> 19 R2=0x0 :nothing ;; 1--> 25 use R2 :nothing ;; Ready list (final): ;; total time = 1 ;; new head = 19 ;; new tail = 25 But in movebug.c.176r.greg, the move function address into a register insn disappeared. I don't know why the optimization step will take this insn out of the program, because this will cause a logical error. (insn:HI 6 3 37 2 movebug.c:8 (set (reg:SI 4 R4) (const_int 2 [0x2])) 2 {constant_load_si} (expr_list:REG_EQUAL (const_int 2 [0x2]) (nil))) (insn 37 6 8 2 movebug.c:8 (set (mem/c:SI (reg/f:SI 15 R15) [3 i+0 S4 A32]) (reg:SI 4 R4)) 8 {store_si} (nil)) (note:HI 8 37 11 2 NOTE_INSN_DELETED) (code_label:HI 11 8 7 3 4 "" [1 uses]) (note:HI 7 11 38 3 [bb 3] NOTE_INSN_BASIC_BLOCK) (insn 38 7 10 3 movebug.c:10 (set (reg:SI 4 R4) (mem/c:SI (reg/f:SI 15 R15) [3 i+0 S4 A32])) 11 {load_si} (nil)) (insn:HI 10 38 39 3 movebug.c:10 (set (reg:SI 4 R4) (plus:SI (reg:SI 4 R4) (const_int 1 [0x1]))) 45 {rice_addsi3} (nil)) (insn 39 10 9 3 movebug.c:10 (set (mem/c:SI (reg/f:SI 15 R15) [3 i+0 S4 A32]) (reg:SI 4 R4)) 8 {store_si} (nil)) (call_insn:HI 9 39 40 3 movebug.c:12 (parallel [ (call (mem:SI (reg:SI 0 R0) [0 S4 A32]) (const_int 0 [0x0])) (clobber (reg:SI 17 LINK)) ]) 99 {call} (expr_list:REG_EH_REGION (const_int 0 [0x0]) (nil)) (nil)) also in movebug.c.194r.sched2, there is an overview of the flowchart: ;; ====================================================== ;; -- basic block 2 from 41 to 37 -- after reload ;; ====================================================== ;; 0--> 41 [R15-0x4]=R14 :nothing ;; 1--> 42 R0=LINK :nothing changing bb of uid 44 ;; 2--> 44 R15=R15-0xc :nothing ;; 3--> 43 [R14-0x8]=R0 :nothing changing bb of uid 6 ;; 4--> 6 R4=0x2 :nothing ;; 5--> 45 R14=R15 :nothing ;; 6--> 37 [R15]=R4 :nothing ;; Ready list (final): ;; total time = 6 ;; new head = 46 ;; new tail = 37 ;; ====================================================== ;; -- basic block 3 from 38 to 13 -- after reload ;; ====================================================== ;; 0--> 38 R4=[R15] :rice_load,nothing ;; 2--> 10 R4=R4+0x1 :nothing ;; 3--> 39 [R15]=R4 :nothing ;; 4--> 9 call [R0] :nothing ;; 5--> 40 R4=[R15] :rice_load,nothing ;; 7--> 13 pc={(R4!=0x10)?L11:pc} :nothing ;; Ready list (final): ;; total time = 7 ;; new head = 38 ;; new tail = 13 ;; ====================================================== ;; -- basic block 4 from 19 to 52 -- after reload ;; ====================================================== changing bb of uid 48 ;; 0--> 48 R15=R14+0xc :nothing changing bb of uid 50 ;; 1--> 50 R0=[R15-0x8] :rice_load,nothing ;; 2--> 19 R2=0x0 :nothing changing bb of uid 49 ;; 3--> 49 R14=[R15-0x4] :rice_load,nothing ;; 4--> 25 use R2 :nothing ;; 4--> 51 LINK=R0 :nothing ;; 5--> 52 return :nothing ;; Ready list (final): ;; total time = 5 ;; new head = 47 ;; new tail = 52 You can it 's absolutely wrong due to missing R0 assignment. And the CALL insn will jmp to a incorrect position. I don't know why it causes this problem. Does anyone also meet this kind of problem? Any suggestion is appreciated. Thanks very much. daniel.tian