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.