public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/54571] New: Missed optimization converting between bit sets
@ 2012-09-13 21:25 rth at gcc dot gnu.org
  2012-09-13 21:25 ` [Bug middle-end/54571] " rth at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: rth at gcc dot gnu.org @ 2012-09-13 21:25 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54571

             Bug #: 54571
           Summary: Missed optimization converting between bit sets
    Classification: Unclassified
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: rth@gcc.gnu.org


When converting a bit set from one domain to another,code such as

  if (old & OLD_X) new |= NEW_X;
  if (old & OLD_Y) new |= NEW_Y;

is common.  If OLD_X and NEW_X are single bits, then this conversion
need not include any conditional code.  One can mask out OLD_X and
shift it left or right to become NEW_X.  Or, vice versa, shift left
or right and then mask out NEW_X.

Indeed, it's probably preferable to perform the mask with the smaller
of OLD_X and NEW_X in order to maximize the possibility of having a
valid immediate operand to the logical insn.

A test case that would seem to cover the all the cases, including 
converting logical not to bitwise not, would seem to be

int f1(int x, int y) { if (x & 1) y |= 1; return y; }
int f2(int x, int y) { if (x & 1) y |= 2; return y; }
int f3(int x, int y) { if (x & 2) y |= 1; return y; }
int g1(int x, int y) { if (!(x & 1)) y |= 1; return y; }
int g2(int x, int y) { if (!(x & 1)) y |= 2; return y; }
int g3(int x, int y) { if (!(x & 2)) y |= 1; return y; }

I'll also note that on the (presumably) preferred alternatives:

int h1(int x, int y) { return (x & 1) | y; }
int h2(int x, int y) { return ((x & 1) << 1) | y; }
int h3(int x, int y) { return ((x & 2) >> 1) | y; }
int k1(int x, int y) { return (~x & 1) | y; }
int k2(int x, int y) { return ((~x & 1) << 1) | y; }
int k3(int x, int y) { return ((~x >> 1) & 1) | y; }

there's some less-than-optimial code generated for k1 and k2.


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

end of thread, other threads:[~2023-06-07 15:20 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-13 21:25 [Bug middle-end/54571] New: Missed optimization converting between bit sets rth at gcc dot gnu.org
2012-09-13 21:25 ` [Bug middle-end/54571] " rth at gcc dot gnu.org
2012-09-14  8:40 ` rguenth at gcc dot gnu.org
2021-07-06  8:39 ` pinskia at gcc dot gnu.org
2021-07-20  3:16 ` pinskia at gcc dot gnu.org
2021-11-15  0:52 ` pinskia at gcc dot gnu.org
2023-06-07 15:20 ` 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).