[Bug target/65265] New: [SH] Use rotcl to logically and/or comparison results

olegendo at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Mar 1 20:06:00 GMT 2015


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

            Bug ID: 65265
           Summary: [SH] Use rotcl to logically and/or comparison results
           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 code:

int test (int a, int b, int c, int d)
{
  return (a == b) & (b == 0) & (c != 0);
}

currently compiles to:
        tst     r5,r5
        movt    r1
        tst     r6,r6
        mov     #-1,r0
        negc    r0,r0
        cmp/eq  r5,r4
        and     r0,r1
        movt    r0
        rts
        and     r1,r0

which is slightly better as:
        tst     r5,r5
        movt    r0
        tst     r6,r6
        rotcl   r0
        cmp/eq  r4,r5
        rotcl   r0
        cmp/eq  #5,r0
        rts
        movt    r0

Logical ANDs/ORs of comparison results can be done by first collecting all
comparison results in one register and then testing/comparing that register. 
Negated T bit stores (negc above) can be handled by adjusting the final
comparison/bit test constant, or by negating all bits using a not reg,reg insn. 

It seems this is worth doing for 3 or more comparisons.  Since regs are 32
bits, up to 32 comparison results can be collected that way, although it's
probably better to insert conditional branches in between to short circuit the
thing.

Combine already tries out things like:

Failed to match this instruction:
(set (reg:SI 179)
    (and:SI (ne:SI (reg:SI 6 r6 [ c ])
            (const_int 0 [0]))
        (eq:SI (reg:SI 5 r5 [ b ])
            (const_int 0 [0]))))

Which can be handled rather easily using treg_set_expr:

[(set (match_operand:SI 0 "arith_reg_dest")
      (and:SI (match_operand 1 "treg_set_expr")
              (match_operand 2 "treg_set_expr")))]

.. which will make combine try out longer and/ior chains like

(and:SI (and:SI (match_operand 1 "treg_set_expr")
                (match_operand 2 "treg_set_expr")
        (match_operand 3 "treg_set_expr"))

and so on.
This can be captured using a special predicate and then smashed in split1 into
the respective insn sequence.



More information about the Gcc-bugs mailing list