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

--- Comment #2 from Drea Pinski <pinskia at gcc dot gnu.org> ---
(a^b) <= 3

is the same as:
b ? (a^1 <= 3) : (a <= 3)

For the a^1 <= 3 side:
(a&1) ? (a&(~1) <= 3) : (a|1 <= 3)

`a&(~1) <= 3` is just `a <= 3` so is `a|1 <= 3`

Note we have a pattern for the &~1 case (added by r17-2951-g1c71996e6e067a):
```
/* Fold (X & HIGHMASK) >/<= C into X >/<= (C | ~HIGHMASK).  Clearing the
   low bits of X rounds it down, and a rounded value passes the comparison
   exactly when X passes it against the constant with those bits set.  */
(for cmp (gt le)
 (simplify
  (cmp (bit_and:s @0 INTEGER_CST@1) INTEGER_CST@2)
  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
       && bitmask_inv_cst_vector_p (@1))
   (with { wide_int c = wi::to_wide (@2) | wi::bit_not (wi::to_wide (@1)); }
    (cmp @0 { wide_int_to_tree (TREE_TYPE (@0), c); })))))
```

We don't have one for the `a|LOWMASK` case or the `a^LOWMASK` case either.

That is:
unsigned f2(unsigned a)
{
 a |= 0x2; // CST1
 return a <= 0x13; // CST2
}

// CST2&CST1 == CST1 and CST1 has to be a shifted mask.

Reply via email to