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

             Bug #: 50249
           Summary: ira marks wrong value for inheriting
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: vr...@gcc.gnu.org


Using an approved-for-commit middle-end patch for bug 43864, I hit the
following
error in ira:

Before ira, insn 320 defines r588, which is used in identical loads insn 321
and
insn 329.

10.cc.188r.asmcons:
...
(insn 320 318 321 20 (set (reg/f:SI 588)
        (plus:SI (reg/f:SI 166)
            (const_int -12))) 5 {*thumb1_addsi3}
     (nil))

(insn 321 320 322 20 (set (reg:SI 379)
        (mem:SI (reg/f:SI 588))) 177 {*thumb1_movsi_insn}
     (nil))

(insn 322 321 326 20 (set (mem/s/f:SI (plus:SI (reg/f:SI 329)
        (reg:SI 379)))
        (reg/f:SI 170)) 177 {*thumb1_movsi_insn}
     (expr_list:REG_DEAD (reg:SI 379)
        (nil)))

(insn 326 322 329 20 (set (mem/s/c:SI (plus:SI (reg/f:SI 329)
                (const_int 4)))
        (reg:SI 338)) 177 {*thumb1_movsi_insn}
     (expr_list:REG_DEAD (reg:SI 338)
        (nil)))

(insn 329 326 330 20 (set (reg:SI 386)
        (mem:SI (reg/f:SI 588) )) 177 {*thumb1_movsi_insn}
     (nil))

(insn 330 329 331 20 (set (reg:SI 385)
        (plus:SI (reg/f:SI 329)
            (reg:SI 386))) 5 {*thumb1_addsi3}
     (expr_list:REG_DEAD (reg:SI 386)
        (nil)))
...


After ira, r588 is defined by insn 1140, insn 1141 an insn 320 in r10.
It is then copied to r1 by insn 1143, before being used in the first load,
insn 1144. This first load also overwrites r1.
The second load, insn 1146 however uses r1 as if is was still a copy of r10.

10.cc.191r.ira:
...
(insn 1140 1139 1141 20 (set (reg/f:SI 10 sl [588])
        (reg:SI 1 r1)) 177 {*thumb1_movsi_insn}
     (nil))

(insn 1141 1140 320 20 (set (reg:SI 2 r2)
        (const_int -12)) 177 {*thumb1_movsi_insn}
     (nil))

(insn 320 1141 321 20 (set (reg/f:SI 10 sl [588])
        (plus:SI (reg/f:SI 10 sl [588])
            (reg:SI 2 r2))) 5 {*thumb1_addsi3}
     (nil))

(note 321 320 1145 20 NOTE_INSN_DELETED)

(insn 1145 321 1142 20 (set (reg:SI 0 r0)
        (mem/c:SI (plus:SI (reg/f:SI 13 sp)
                (const_int 12))))
      177 {*thumb1_movsi_insn}
     (nil))

(insn 1142 1145 1143 20 (set (reg:SI 2 r2)
        (plus:SI (reg/f:SI 13 sp)
            (const_int 336))) 5 {*thumb1_addsi3}
     (nil))

(insn 1143 1142 1144 20 (set (reg:SI 1 r1)
        (reg/f:SI 10 sl [588])) 177 {*thumb1_movsi_insn}
     (nil))

(insn 1144 1143 322 20 (set (reg:SI 1 r1)
        (mem:SI (reg:SI 1 r1)))
      177 {*thumb1_movsi_insn}
     (nil))

(insn 322 1144 326 20 (set (mem/s/f:SI (plus:SI (reg:SI 2 r2)
                (reg:SI 1 r1)))
        (reg:SI 0 r0)) 177 {*thumb1_movsi_insn}
     (nil))

(insn 326 322 329 20 (set (mem/s/c:SI (plus:SI (reg/f:SI 13 sp)
            (const_int 340)))
        (reg:SI 3 r3 [338])) 177 {*thumb1_movsi_insn}
     (nil))

(note 329 326 1146 20 NOTE_INSN_DELETED)

(insn 1146 329 330 20 (set (reg:SI 1 r1)
        (mem:SI (reg:SI 1 r1)))
      177 {*thumb1_movsi_insn}
     (nil))

(insn 330 1146 332 20 (set (reg:SI 0 r0 [385])
        (plus:SI (reg:SI 2 r2)
            (reg:SI 1 r1))) 5 {*thumb1_addsi3}
     (nil))
...

The reloads for insn 322 are visible in the ira dump. Reload 1 is the copy from
r10 to r1. Reload 2 is the first load.

10.cc.191r.ira:
...
Reloads for insn # 322
Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 13 sp)
                                                    (const_int 336))
        LO_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 0)
        reload_in_reg: (plus:SI (reg/f:SI 13 sp)
                                                    (const_int 336))
        reload_reg_rtx: (reg:SI 2 r2)
Reload 1: reload_in (SI) = (reg/f:SI 10 sl [588])
        BASE_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 0)
        reload_in_reg: (reg/f:SI 10 sl [588])
        reload_reg_rtx: (reg:SI 1 r1)
Reload 2: reload_in (SI) = (mem:SI (reg/f:SI 10 sl [588]))
        LO_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 0), can't combine
    reload_in_reg: (reg:SI 379)
        reload_reg_rtx: (reg:SI 1 r1)
Reload 3: LO_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 0), optional, can't
          combine, secondary_reload_p
Reload 4: reload_out (SI) = (mem/s/f:SI (plus:SI (plus:SI (reg/f:SI 13 sp)
                                                            (const_int 336))
                                                        (reg:SI 379 )))
    NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
        reload_out_reg: (mem/s/f:SI (plus:SI (plus:SI (reg/f:SI 13 sp)
                                                        (const_int 336))
                                                        (reg:SI 379)))
        secondary_out_reload = 3
Reload 5: reload_in (SI) = (reg/f:SI 170)
        LO_REGS, RELOAD_FOR_INPUT (opnum = 1)
        reload_in_reg: (reg/f:SI 170)
        reload_reg_rtx: (reg:SI 0 r0)
...

in emit_reload_insns, ira determines which reloads can be inherited by later
instructions, by testing reload_reg_reaches_end_p (and
reload_regs_reach_end_p).
These tests return true for both reload 1 and reload 2, since they call the
functions with the same arguments.  It seems that the functions
mark_reload_reg_in_use and reload_reg_reaches_end_p and the underlying 
adminstration do not distinguish between the 2 reloads. They have the same
regno, opnum, type and mode.
So we end up setting reg_reloaded_contents twice, once for each reload. Since
we
do this in reload_order, we first handle reload 2 and then reload 1. So the
effective reg_reloaded_contents is the one of reload 1, while it should be the 
one of reload 2.

Reply via email to