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.

Reply via email to