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.