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

Daniel Henrique Barboza <daniel.barboza at oss dot qualcomm.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |daniel.barboza at oss dot 
qualcomm
                   |                            |.com

--- Comment #22 from Daniel Henrique Barboza <daniel.barboza at oss dot 
qualcomm.com> ---
So I have sent a patch for PR93150 that happens to touch on this bug:

https://gcc.gnu.org/pipermail/gcc-patches/2026-May/715406.html

Mostly because I ended up handling this pattern in that patch:

((A & M) == X) & ((A & N) == Y) -> ((A & (M|N)) == (X | Y))


But the patch alone isn't enough to optimize the example from the description. 
The reason is that the code already reaches 'original' with this format:

----
    charD.8 bD.4592 = (aD.4589 & 8) != 0;
    charD.8 cD.4593 = (aD.4589 & 2) != 0;
    charD.8 dD.4594 = (aD.4589 & 4) != 0;
  return (intD.7) (((unsigned charD.21) bD.4592 & (unsigned charD.21) cD.4593)
& (unsigned charD.21) dD.4594);
----

This happens because there's a match.pd pattern that turns "(A & pow2) == pow2"
into "(A & pow2) != 0":

-------
/* If we have (A & C) == C where C is a power of 2, convert this into
   (A & C) != 0.  Similarly for NE_EXPR.  */
(for cmp (eq ne)
     icmp (ne eq)
 (simplify
  (cmp (bit_and@2 @0 integer_pow2p@1) @1)
  (icmp @2 { build_zero_cst (TREE_TYPE (@0)); })))
-------

Inserting that new pattern before this one doesn't work.  The new pattern is
applied during forwprop, too late to get the code in the format we want (it is
already turned to != 0).

For every other case that doesn't match "A & pow2 == pow2" the new pattern is
able to simplify.  E.g. this:

int f2 (int a)
{
  char b = (a&5) == 5;
  char c = (a&7) == 7;
  char d = (a&9) == 9;
  char e = (a&13) == 13;
  char f = (a&23) == 23;
  return b&c&d&e&f;
}


Is reduced to:

   ;;   basic block 2
  _29 = a_15(D) & 31;
  _30 = _29 == 31;
  # RANGE [irange] int [0, 1] MASK 0x1 VALUE 0x0
  _21 = (intD.7) _30;
  # VUSE <.MEM_22(D)>
  return _21;
  • [Bug tree-optimization... pinskia at gcc dot gnu.org via Gcc-bugs
    • [Bug tree-optimiz... daniel.barboza at oss dot qualcomm.com via Gcc-bugs

Reply via email to