[Bug target/65250] New: [SH] Improve comparisons followed by a negated cstore

olegendo at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sat Feb 28 11:59:00 GMT 2015


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

            Bug ID: 65250
           Summary: [SH] Improve comparisons followed by a negated cstore
           Product: gcc
           Version: 5.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*-*-*

The following example

bool test (int value)
{
  switch(value)
  {
    case 0:
    case 1:
    case 2:
      return true;
    default:
      return false;
  }
}

with -O2 -m4 compiles to:
        mov     #2,r1
        cmp/hi  r1,r4
        mov     #-1,r0
        rts
    negc    r0,r0

On SH4 there is no movrt, so it's better to do that as:
        mov     #2,r1
        cmp/hs  r4,r2
        rts
        movt    r0

..which is just inverting the comparison.


Combine tries the following pattern:

Failed to match this instruction:
(parallel [
        (set (reg:SI 168)
            (leu:SI (reg:SI 4 r4 [ value ])
                (const_int 2 [0x2])))
        (set (reg:SI 147 t)
            (const_int 1 [0x1]))
        (use (reg:SI 169))
    ])

..which is a combination of the inverted comparison and the expanded movrt (via
negc), which always sets T = 1.

A treg_set_expr pattern like the following could be added:

(define_insn_and_split "*"
  [(set (match_operand:SI 0 "arith_reg_dest")
        (match_operand 1 "treg_set_expr_not_const01"))
   (set (reg:SI T_REG) (const_int 1))
   (use (match_operand:SI 2 "arith_reg_operand"))]
 ...)

which would then split out the comparison insn and a trailing sett.  If the
sett is a dead store it will (should) get eliminated afterwards.

However, before that, the initial comparison and cstore expansion should be
investigated.



More information about the Gcc-bugs mailing list