https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65979
Oleg Endo <olegendo at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2015-05-20 Ever confirmed|0 |1 --- Comment #14 from Oleg Endo <olegendo at gcc dot gnu.org> --- (In reply to Kazumoto Kojima from comment #13) > Looks that this doesn't work when the operand 1 is equal to the operand 2 > which is the case for the above insns 92, 93 and 83. The peephole > removed with the fix in PR65153 transformed these insns prior to > the above peephole so to avoid the problem. The patch below fixes > this case. It looks there are similar peephole patterns,though. > Oleg, if you get the spare time, could you look into these peepholes? > > -- > diff --git a/config/sh/sh.md b/config/sh/sh.md > index 27f0074..5bc3401 100644 > --- a/config/sh/sh.md > +++ b/config/sh/sh.md > @@ -14750,6 +14750,7 @@ label: > "TARGET_SH1 > && peep2_reg_dead_p (3, operands[0]) > && !reg_overlap_mentioned_p (operands[0], operands[3]) > + && !reg_overlap_mentioned_p (operands[1], operands[2]) > && (REGNO (operands[0]) == REGNO (operands[4]) > || REGNO (operands[0]) == REGNO (operands[5])) > && (REGNO (operands[2]) == REGNO (operands[4]) Sorry for the long chain of trouble and pain. Adding the !reg_overlap_mentioned_p (operands[1], operands[2]) condition should fix the problem. However, the peephole is actually meant to transform (insn 92 14 15 3 (set (reg:SI 1 r1 [orig:171 D.2078 ] [171]) (reg:SI 2 r2 [172])) 252 {movsi_ie} (expr_list:REG_DEAD (reg:SI 2 r2 [172]) (nil))) (insn 93 16 83 3 (set (reg:SI 2 r2) (const_int 66602 [0x1042a])) 252 {movsi_ie} (nil)) (insn 83 93 18 3 (set (reg:SI 147 t) (eq:SI (and:SI (reg:SI 1 r1 [orig:171 D.2078 ] [171]) (reg:SI 2 r2)) (const_int 0 [0]))) 1 {tstsi_t} (expr_list:REG_DEAD (reg:SI 2 r2) (expr_list:REG_DEAD (reg:SI 1 r1 [orig:171 D.2078 ] [171]) (nil)))) into (insn 93 16 83 3 (set (reg:SI 2 r1) (const_int 66602 [0x1042a])) 252 {movsi_ie} (nil)) (insn 83 93 18 3 (set (reg:SI 147 t) (eq:SI (and:SI (reg:SI 1 r1 [orig:171 D.2078 ] [171]) (reg:SI 2 r2)) (const_int 0 [0]))) 1 {tstsi_t} (expr_list:REG_DEAD (reg:SI 2 r2) (expr_list:REG_DEAD (reg:SI 1 r1 [orig:171 D.2078 ] [171]) (nil)))) I think the check operands[1] / operands[2] check should go into the preparation statement. operands[0] is dying after this peephole, so I guess this should work: { if (reg_overlap_mentioned_p (operands[1], operands[2])) std::swap (operands[0], operands[2]) sh_check_add_incdec_notes (emit_move_insn (operands[2], operands[3])); emit_insn (gen_tstsi_t (operands[2], gen_rtx_REG (SImode, (REGNO (operands[1]))))); } I guess that the following peephole (sh.md line 14733) will also have a similar problem.