https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51244

--- Comment #76 from Oleg Endo <olegendo at gcc dot gnu.org> ---
When compiling the libgcc divsc3 from PR 55212 with "-O2 -m2 -ml" (on sh-lra
branch) the following sequences are generated:

        tst     r0,r0
        subc    r0,r0     ! r0: T == 0 -> 0x00000000, T == 1 -> 0xFFFFFFFF
        not     r0,r0     ! r0: T == 0 -> 0xFFFFFFFF, T == 1 -> 0x00000000
        and     #1,r0     ! r0: T == 0 -> 1, T == 1 -> 0

which can be done better as:

        tst     r0,r0
        mov     #-1,r0
        negc    r0,r0

or
        tst     r0,r0
        movt    r0
        xor     #1,r0

and on SH2A:

        tst     r0,r0
        movrt   r0


combine is looking for the following patterns:

Failed to match this instruction:
(set (reg:SI 296 [ D.1371 ])
    (and:SI (not:SI (reg:SI 147 t))
        (const_int 1 [0x1])))

Failed to match this instruction:
(set (reg:SI 147 t)
    (and:SI (reg:SI 147 t)
        (const_int 1 [0x1])))

(and:SI (reg:SI T_REG) (const_int 1)) is effectively a T -> T nop move which is
supposed to be handled by the "*movtt" insn.  Maybe the case above and the
original eq:SI case in "*movtt" should be added to the t_reg_operand predicate.
 Then the "*movtt" pattern could be simplified to:

(define_insn_and_split "*movtt"
  [(set (reg:SI T_REG) (match_operand 0 "t_reg_operand"))] ...

Reply via email to