This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug rtl-optimization/67731] New: Combine of OR'ed bitfields should use bit-test


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

            Bug ID: 67731
           Summary: Combine of OR'ed bitfields should use bit-test
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: olegendo at gcc dot gnu.org
                CC: rguenth at gcc dot gnu.org, segher at gcc dot gnu.org
  Target Milestone: ---
            Target: sh*-*-*

This is what happens on SH, but it's probably not entirely SH specific.  All
examples below have been compiled with -x c -std=gnu11 -O2 -m4 -ml.

typedef struct
{
  _Bool a : 1;
  _Bool b : 1;
  _Bool c : 1;
  _Bool d : 1;
  unsigned int e : 4;
} S;


_Bool test_00 (S* s)
{
  return s->b | s->c;
}

compiles to:
        mov.l   @r4,r2
        mov     r2,r0
        tst     #2,r0     // bit test 'b'
        mov     #-1,r0
        negc    r0,r1
        mov     r2,r0
        tst     #4,r0     // bit test 'c'
        mov     #-1,r0
        negc    r0,r0
        rts     
        or      r1,r0

while the equivalent


_Bool test_01 (unsigned char* s)
{
  return *s & ((1 << 1) | (1 << 2));
}

compiles to:
        mov.b   @r4,r0
        mov     #-1,r1
        tst     #6,r0    // bit test 'b' | 'c'
        rts     
        negc    r1,r0

For the bitfield case, combine is looking for a pattern:

Failed to match this instruction:
(set (reg:SI 180)
    (ior:SI (zero_extract:SI (reg:SI 170 [ *s_2(D) ])
            (const_int 1 [0x1])
            (const_int 2 [0x2]))
        (zero_extract:SI (reg:SI 170 [ *s_2(D) ])
            (const_int 1 [0x1])
            (const_int 1 [0x1]))))

Adding it to sh.md as:

(define_insn_and_split "*"
  [(set (match_operand:SI 0 "arith_reg_dest")
        (ior:SI (zero_extract:SI (match_operand:SI 1 "arith_reg_operand")
                                 (const_int 1)
                                 (match_operand 2 "const_int_operand"))
                (zero_extract:SI (match_dup 1)
                                 (const_int 1)
                                 (match_operand 3 "const_int_operand"))))
   (clobber (reg:SI T_REG))]
  "TARGET_SH1 && can_create_pseudo_p ()"
  "#"
  "&& 1"
  [(parallel [(set (match_dup 0)
                   (ne:SI (and:SI (match_dup 1) (match_dup 2)) (const_int 0)))
              (clobber (reg:SI T_REG))])]
{
  operands[2] = GEN_INT ((1LL << INTVAL (operands[2]))
                         | (1LL << INTVAL (operands[3])));
})

results in the expected code:

        mov.l   @r4,r0
        tst     #6,r0
        mov     #-1,r0
        rts
        negc    r0,r0


Then...

_Bool test_03 (S* s)
{
  return s->b | s->c | s->d;
}

results in combine looking for something like
Failed to match this instruction:
(set (reg:SI 195)
    (and:SI (ior:SI (ior:SI (lshiftrt:SI (reg:SI 173 [ *s_2(D) ])
                    (const_int 2 [0x2]))
                (lshiftrt:SI (reg:SI 173 [ *s_2(D) ])
                    (const_int 1 [0x1])))
            (lshiftrt:SI (reg:SI 173 [ *s_2(D) ])
                (const_int 3 [0x3])))
        (const_int 1 [0x1])))

and for 4 bits it's

(set (reg:SI 204)
    (and:SI (ior:SI (ior:SI (ior:SI (lshiftrt:SI (reg:SI 173 [ *s_2(D) ])
                        (const_int 2 [0x2]))
                    (lshiftrt:SI (reg:SI 173 [ *s_2(D) ])
                        (const_int 1 [0x1])))
                (lshiftrt:SI (reg:SI 173 [ *s_2(D) ])
                    (const_int 3 [0x3])))
            (lshiftrt:SI (reg:SI 173 [ *s_2(D) ])
                (const_int 4 [0x4])))
        (const_int 1 [0x1])))

and so on.

Although it's of course possible to add these with a recursive predicate the
the backend, maybe it could be a good idea to either do this at the tree-level
or in combine/simplify rtx.  I think this is a problem on every target, not
just SH.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]