https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118483
--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> --- I am not sure we need the :S in the end. I noticed the other patterns that do `a OP ~a` have an optional convert assiocated with it: e.g.: ``` /* ~x | x -> -1 */ /* ~x ^ x -> -1 */ (for op (bit_ior bit_xor) (simplify (op:c (convert? @0) (convert? (maybe_bit_not @1))) (with { bool wascmp; } (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1)) && bitwise_inverted_equal_p (@0, @1, wascmp)) (convert { wascmp ? constant_boolean_node (true, type) : build_all_ones_cst (TREE_TYPE (@0)); }))))) ``` and ``` /* Simplify ~X & X as zero. */ (simplify (bit_and:c (convert? @0) (convert? (maybe_bit_not @1))) (with { bool wascmp; } (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1)) && bitwise_inverted_equal_p (@0, @1, wascmp)) { wascmp ? constant_boolean_node (false, type) : build_zero_cst (type); }))) ``` So we should be able to just do: ``` (for cmp (eq ne) (simplify (cmp:c (convert? @0) (convert? (maybe_bit_not @1))) (with { bool was_cmp; } (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1)) && bitwise_inverted_equal_p (@0, @1, wascmp)) { constant_boolean_node (eqne == NE_EXPR, type); })))) ``` I will add/modify the pattern in 2 steps though.