http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49007

--- Comment #5 from John David Anglin <danglin at gcc dot gnu.org> 2011-05-20 
19:19:35 UTC ---
This loop in cleanup_tree_cfg_1 is miscompiled:

  /* Start by iterating over all basic blocks.  We cannot use FOR_EACH_BB,
     since the basic blocks may get removed.  */
  n = last_basic_block;
  for (i = NUM_FIXED_BLOCKS; i < n; i++)
    {
      bb = BASIC_BLOCK (i);
      if (bb)
        retval |= cleanup_tree_cfg_bb (bb);
    }

The dbr pass incorrectly optimizes the loop index register $r4
causing the index to increment by two when cleanup_tree_cfg_bb
is called.  As a result, a cleanup is skipped for bb=0x7ac36b40.
This is generated code:

   0x005d5600 <+264>:   ldo 2(r4),ret0
=> 0x005d5604 <+268>:   ldw,s ret0(r26),r26
   0x005d5608 <+272>:   cmpib,= 0,r26,0x5d5624 <cleanup_tree_cfg+300>
   0x005d560c <+276>:   ldo 1(r4),r4
   0x005d5610 <+280>:   b,l 0x5d4018 <cleanup_tree_cfg_bb>,rp
   0x005d5614 <+284>:   nop
   0x005d5618 <+288>:   or ret0,r6,ret0
   0x005d561c <+292>:   extrw,u ret0,31,8,r6
   0x005d5620 <+296>:   ldo 1(r4),r4
   0x005d5624 <+300>:   cmpb,<<,n r4,r5,0x5d55b0 <cleanup_tree_cfg+184>
   0x005d5628 <+304>:   ldw 0(r3),ret0

With -fno-delayed-branch we have instead:

   0x005d58e8 <+288>:   ldo 2(r4),ret0
=> 0x005d58ec <+292>:   ldw,s ret0(r26),r26
   0x005d58f0 <+296>:   cmpib,=,n 0,r26,0x5d5904 <cleanup_tree_cfg+316>
   0x005d58f4 <+300>:   b,l 0x5d4190 <cleanup_tree_cfg_bb>,rp
   0x005d58f8 <+304>:   nop
   0x005d58fc <+308>:   or ret0,r6,ret0
   0x005d5900 <+312>:   extrw,u ret0,31,8,r6
   0x005d5904 <+316>:   ldo 1(r4),r4
   0x005d5908 <+320>:   cmpb,<< r4,r5,0x5d588c <cleanup_tree_cfg+196>
   0x005d590c <+324>:   nop

The barriers dump has:

(insn 95 94 96 ../../gcc/gcc/basic-block.h:194 (set (reg:SI 28 %r28 [143])
        (plus:SI (reg/v:SI 4 %r4 [orig:111 i ] [111])
            (const_int 2 [0x2]))) 111 {addsi3} (nil))

(insn 96 95 97 ../../gcc/gcc/basic-block.h:194 (set (reg/v/f:SI 26 %r26
[orig:110
bb ] [110])
        (mem/s/f/j:SI (plus:SI (mult:SI (reg:SI 28 %r28 [143])
                    (const_int 4 [0x4]))
                (reg/f:SI 26 %r26 [orig:104 iftmp.1903 ] [104])) [0
<variable>.vec
 S4 A32])) 37 {*pa.md:2542} (expr_list:REG_DEAD (reg:SI 28 %r28 [143])
        (nil)))

(jump_insn 97 96 98 ../../gcc/gcc/tree-cfgcleanup.c:698 (set (pc)
        (if_then_else (eq (reg/v/f:SI 26 %r26 [orig:110 bb ] [110])
                (const_int 0 [0x0]))
            (label_ref 105)
            (pc))) 25 {*pa.md:1770} (expr_list:REG_BR_PROB (const_int 2820
[0xb04]
)
        (nil)))

(note 98 97 100 [bb 18] NOTE_INSN_BASIC_BLOCK)

(call_insn 100 98 101 ../../gcc/gcc/tree-cfgcleanup.c:699 (parallel [
            (set (reg:SI 28 %r28)
                (call (mem:SI (symbol_ref/v:SI ("@cleanup_tree_cfg_bb") [flags
0x2
03] <function_decl 7a193b60 cleanup_tree_cfg_bb>) [0 S4 A32])
                    (const_int 16 [0x10])))
            (clobber (reg:SI 1 %r1))
            (clobber (reg:SI 2 %r2))
            (use (const_int 0 [0x0]))
        ]) 212 {call_val_symref} (expr_list:REG_DEAD (reg:SI 26 %r26)
        (expr_list:REG_EH_REGION (const_int 0 [0x0])
            (nil)))
    (expr_list:REG_DEP_TRUE (use (reg:SI 26 %r26))
        (nil)))

(note 101 100 103 NOTE_INSN_DELETED)

(insn 103 101 104 ../../gcc/gcc/tree-cfgcleanup.c:699 (set (reg:SI 28 %r28
[145])
        (ior:SI (reg:SI 28 %r28)
            (reg/v:SI 6 %r6 [orig:109 retval+-3 ] [109]))) 131 {*pa.md:6187}
(expr
_list:REG_DEAD (reg/v:SI 6 %r6 [orig:109 retval+-3 ] [109])
        (nil)))

(insn 104 103 105 ../../gcc/gcc/tree-cfgcleanup.c:699 (set (reg/v:SI 6 %r6
[orig:1
09 retval+-3 ] [109])
        (zero_extend:SI (reg:QI 28 %r28 [orig:145+3 ] [145]))) 83 {*pa.md:5001}
(e
xpr_list:REG_DEAD (reg:QI 28 %r28 [orig:145+3 ] [145])
        (nil)))

(code_label 105 104 106 601 "" [1 uses])

(note 106 105 107 [bb 19] NOTE_INSN_BASIC_BLOCK)

(insn 107 106 109 ../../gcc/gcc/tree-cfgcleanup.c:695 (set (reg/v:SI 4 %r4
[orig:1
11 i ] [111])
        (plus:SI (reg/v:SI 4 %r4 [orig:111 i ] [111])
            (const_int 1 [0x1]))) 111 {addsi3} (nil))

(jump_insn 109 107 369 ../../gcc/gcc/tree-cfgcleanup.c:695 (set (pc)
        (if_then_else (gtu (reg/v:SI 5 %r5 [orig:112 n ] [112])
                (reg/v:SI 4 %r4 [orig:111 i ] [111]))
            (label_ref 108)
            (pc))) 25 {*pa.md:1770} (expr_list:REG_BR_PROB (const_int 9700
[0x25e4
])
        (nil)))

The dbr dump has:

(insn 95 94 435 ../../gcc/gcc/basic-block.h:194 (set (reg:SI 28 %r28 [143])
        (plus:SI (reg/v:SI 4 %r4 [orig:111 i ] [111])
            (const_int 2 [0x2]))) 111 {addsi3} (nil))

(code_label 435 95 96 620 "" [1 uses])

(insn 96 435 467 ../../gcc/gcc/basic-block.h:194 (set (reg/v/f:SI 26 %r26
[orig:11
0 bb ] [110])
        (mem/s/f/j:SI (plus:SI (mult:SI (reg:SI 28 %r28 [143])
                    (const_int 4 [0x4]))
                (reg/f:SI 26 %r26 [orig:104 iftmp.1903 ] [104])) [0
<variable>.vec
 S4 A32])) 37 {*pa.md:2542} (expr_list:REG_DEAD (reg:SI 28 %r28 [143])
        (nil)))

(insn 467 96 98 ../../gcc/gcc/tree-cfgcleanup.c:698 (sequence [
            (jump_insn 97 96 107 ../../gcc/gcc/tree-cfgcleanup.c:698 (set (pc)
                    (if_then_else (eq (reg/v/f:SI 26 %r26 [orig:110 bb ] [110])
                            (const_int 0 [0x0]))
                        (label_ref:SI 466)
                        (pc))) 25 {*pa.md:1770} (expr_list:REG_BR_PRED
(const_int
16 [0x10])
                    (expr_list:REG_BR_PROB (const_int 2820 [0xb04])
                        (nil))))
            (insn/s 107 97 98 (set (reg/v:SI 4 %r4 [orig:111 i ] [111])
                    (plus:SI (reg/v:SI 4 %r4 [orig:111 i ] [111])
                        (const_int 1 [0x1]))) 111 {addsi3} (nil))
        ]) -1 (nil))

(note 98 467 100 [bb 18] NOTE_INSN_BASIC_BLOCK)

(call_insn 100 98 101 ../../gcc/gcc/tree-cfgcleanup.c:699 (parallel [
            (set (reg:SI 28 %r28)
                (call (mem:SI (symbol_ref/v:SI ("@cleanup_tree_cfg_bb") [flags
0x2
03] <function_decl 7a193b60 cleanup_tree_cfg_bb>) [0 S4 A32])
                    (const_int 16 [0x10])))
            (clobber (reg:SI 1 %r1))
            (clobber (reg:SI 2 %r2))
            (use (const_int 0 [0x0]))
        ]) 212 {call_val_symref} (expr_list:REG_DEAD (reg:SI 26 %r26)
        (expr_list:REG_EH_REGION (const_int 0 [0x0])
            (nil)))
    (expr_list:REG_DEP_TRUE (use (reg:SI 26 %r26))
        (nil)))

(note 101 100 103 NOTE_INSN_DELETED)

(insn 103 101 104 ../../gcc/gcc/tree-cfgcleanup.c:699 (set (reg:SI 28 %r28
[145])
        (ior:SI (reg:SI 28 %r28)
            (reg/v:SI 6 %r6 [orig:109 retval+-3 ] [109]))) 131 {*pa.md:6187}
(expr
_list:REG_DEAD (reg/v:SI 6 %r6 [orig:109 retval+-3 ] [109])
        (nil)))

(insn 104 103 106 ../../gcc/gcc/tree-cfgcleanup.c:699 (set (reg/v:SI 6 %r6
[orig:1
09 retval+-3 ] [109])
        (zero_extend:SI (reg:QI 28 %r28 [orig:145+3 ] [145]))) 83 {*pa.md:5001}
(e
xpr_list:REG_DEAD (reg:QI 28 %r28 [orig:145+3 ] [145])
        (nil)))

(note 106 104 107 [bb 19] NOTE_INSN_BASIC_BLOCK)

(insn 107 106 466 ../../gcc/gcc/tree-cfgcleanup.c:695 (set (reg/v:SI 4 %r4
[orig:1
11 i ] [111])
        (plus:SI (reg/v:SI 4 %r4 [orig:111 i ] [111])
            (const_int 1 [0x1]))) 111 {addsi3} (nil))

(code_label 466 107 438 625 "" [1 uses])

(insn 438 466 369 ../../gcc/gcc/tree-cfgcleanup.c:695 (sequence [
            (jump_insn/u 109 466 66 ../../gcc/gcc/tree-cfgcleanup.c:695 (set
(pc)
                    (if_then_else (gtu (reg/v:SI 5 %r5 [orig:112 n ] [112])
                            (reg/v:SI 4 %r4 [orig:111 i ] [111]))
                        (label_ref 108)
                        (pc))) 25 {*pa.md:1770} (expr_list:REG_BR_PRED
(const_int
14 [0xe])
                    (expr_list:REG_BR_PROB (const_int 9700 [0x25e4])
                        (nil))))
            (insn/s 66 109 369 (set (reg/f:SI 28 %r28 [orig:133 cfun ] [133])
                    (mem/f/c/i:SI (reg/f:SI 3 %r3 [217]) [0 cfun+0 S4 A32])) 37
{*
pa.md:2542} (expr_list:REG_EQUIV (mem/f/c/i:SI (reg/f:SI 3 %r3 [217]) [0 cfun+0
S4
 A32])
                    (nil)))
        ]) -1 (nil))

Reply via email to