public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug rtl-optimization/67731] New: Combine of OR'ed bitfields should use bit-test
@ 2015-09-27 11:19 olegendo at gcc dot gnu.org
  2015-09-28 11:12 ` [Bug rtl-optimization/67731] " rguenth at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: olegendo at gcc dot gnu.org @ 2015-09-27 11:19 UTC (permalink / raw)
  To: gcc-bugs

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.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-06-01 22:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-27 11:19 [Bug rtl-optimization/67731] New: Combine of OR'ed bitfields should use bit-test olegendo at gcc dot gnu.org
2015-09-28 11:12 ` [Bug rtl-optimization/67731] " rguenth at gcc dot gnu.org
2015-09-28 14:15 ` olegendo at gcc dot gnu.org
2015-09-28 14:28 ` rguenther at suse dot de
2021-06-01 22:04 ` [Bug tree-optimization/67731] " pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).