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

            Bug ID: 58517
           Summary: [SH] wrong code with subc and movsicc
                    (-mpretend-cmove) after ce2
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: olegendo at gcc dot gnu.org
            Target: sh*-*-*

While working on something else, I've noticed the following sequence in the
CSiBE set in the file zlib-1.1.4/infblock.s, compiling with -m4-single -ml -O2
-mpretend-cmove (trunk rev 201978):

.L257:
    sett        ! 1740    sett    [length = 2]
    mov    r2,r13    ! 2180    movsi_ie/2    [length = 2]
    sub    r5,r1    ! 1588    *subsi3_internal    [length = 2]
    subc    r5,r13    ! 1741    *subc    [length = 2]
    bt    0f    ! 1589    *movsicc_t_false/1    [length = 4]
    mov    r1,r13
0:
    tst    r13,r13    ! 435    cmpeqsi_t/1    [length = 2]
    bf    .L67    ! 436    *cbranch_t    [length = 2]
    bra    .L124
    nop        ! 2774    jump_compact    [length = 4]

The subc insn clobbers the T_REG and the following 'bt 0f' just looks wrong.
It seems that something goes wrong and the insn that does the test before
*movsicc_t_false gets eliminated because the sett-subc sequence is placed in
between.
After the combine pass the sequence looks like:

(note 422 421 423 45 [bb 45] NOTE_INSN_BASIC_BLOCK)
(insn 423 422 432 45 (set (reg:SI 147 t)
        (gtu:SI (reg/f:SI 424 [ D.2926 ])
            (reg/v/f:SI 189 [ q ]))) infblock.c:202 34 {cmpgtusi_t}
     (nil))
(insn 432 423 424 45 (set (reg/v:SI 190 [ n ])
        (minus:SI (reg/v/f:SI 423 [ q ])
            (reg/v/f:SI 189 [ q ]))) infblock.c:202 76 {*subsi3_internal}
     (expr_list:REG_DEAD (reg/v/f:SI 423 [ q ])
        (nil)))
(jump_insn 424 432 425 45 (set (pc)
        (if_then_else (eq (reg:SI 147 t)
                (const_int 0 [0]))
            (label_ref:SI 433)
            (pc))) infblock.c:202 295 {*cbranch_t}
     (expr_list:REG_DEAD (reg:SI 147 t)
        (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
            (nil)))
 -> 433)
(note 425 424 426 46 [bb 46] NOTE_INSN_BASIC_BLOCK)
(note 426 425 427 46 NOTE_INSN_DELETED)
(insn 427 426 433 46 (parallel [
            (set (reg/v:SI 190 [ n ])
                (plus:SI (not:SI (reg/v/f:SI 189 [ q ]))
                    (reg/f:SI 424 [ D.2926 ])))
            (clobber (reg:SI 147 t))
        ]) infblock.c:202 74 {*subc}
     (expr_list:REG_UNUSED (reg:SI 147 t)
        (expr_list:REG_DEAD (reg/f:SI 424 [ D.2926 ])
            (nil))))
(code_label 433 427 434 47 70 "" [1 uses])


After the following pass ce2 it becomes:

(note 422 421 423 45 [bb 45] NOTE_INSN_BASIC_BLOCK)
(insn 423 422 432 45 (set (reg:SI 147 t)
        (gtu:SI (reg/f:SI 424 [ D.2926 ])
            (reg/v/f:SI 189 [ q ]))) infblock.c:202 34 {cmpgtusi_t}
     (nil))
(insn 432 423 1587 45 (set (reg/v:SI 190 [ n ])
        (minus:SI (reg/v/f:SI 423 [ q ])
            (reg/v/f:SI 189 [ q ]))) infblock.c:202 76 {*subsi3_internal}
     (expr_list:REG_DEAD (reg/v/f:SI 423 [ q ])
        (nil)))
(insn 1587 432 1588 45 (parallel [
            (set (reg:SI 945)
                (plus:SI (not:SI (reg/v/f:SI 189 [ q ]))
                    (reg/f:SI 424 [ D.2926 ])))
            (clobber (reg:SI 147 t))
        ]) infblock.c:202 74 {*subc}
     (nil))
(insn 1588 1587 1589 45 (set (reg:SI 946)
        (minus:SI (reg/v/f:SI 423 [ q ])
            (reg/v/f:SI 189 [ q ]))) infblock.c:202 76 {*subsi3_internal}
     (nil))
(insn 1589 1588 435 45 (set (reg/v:SI 190 [ n ])
        (if_then_else:SI (eq (reg:SI 147 t)
                (const_int 0 [0]))
            (reg:SI 946)
            (reg:SI 945))) infblock.c:202 54 {*movsicc_t_false}
     (nil))
(insn 435 1589 436 45 (set (reg:SI 147 t)
        (eq:SI (reg/v:SI 190 [ n ])
            (const_int 0 [0]))) infblock.c:202 17 {cmpeqsi_t}
     (nil))
(jump_insn 436 435 1378 45 (set (pc)
        (if_then_else (eq (reg:SI 147 t)
                (const_int 0 [0]))
            (label_ref 501)
            (pc))) infblock.c:202 295 {*cbranch_t}
     (expr_list:REG_DEAD (reg:SI 147 t)
        (expr_list:REG_BR_PROB (const_int 10000 [0x2710])
            (nil)))
 -> 501)

which is wrong.  I haven't checked whether it also happens on current trunk.

Reply via email to