https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93504
--- Comment #4 from Marc Glisse <glisse at gcc dot gnu.org> --- /* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */ I guess several transformations like this one which match (unary m) could do with a second version for the case where m is constant (and thus (unary m) is already constant folded). That is, unless we come up with a trick to avoid that duplication, like (untested) (match (my_not @0) (bit_not @0)) (match (my_not @0) INTEGER_CST@0 (with { @0 = fold_unary (BIT_NOT_EXPR, TREE_TYPE(@0), @0); } (if (true)))) although that's hackish, the commutative version is redundant, it builds a tree unnecessarily, the conditions (single_use?) to make the transformation worth it may be different, etc.