https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94718
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- --- gcc/fold-const.c.jj 2020-03-31 11:06:14.063512214 +0200 +++ gcc/fold-const.c 2020-04-23 18:39:15.399738420 +0200 @@ -11631,50 +11631,6 @@ fold_binary_loc (location_t loc, enum tr return omit_one_operand_loc (loc, type, res, arg0); } - /* Fold (X & C) op (Y & C) as (X ^ Y) & C op 0", and symmetries. */ - if (TREE_CODE (arg0) == BIT_AND_EXPR - && TREE_CODE (arg1) == BIT_AND_EXPR) - { - tree arg00 = TREE_OPERAND (arg0, 0); - tree arg01 = TREE_OPERAND (arg0, 1); - tree arg10 = TREE_OPERAND (arg1, 0); - tree arg11 = TREE_OPERAND (arg1, 1); - tree itype = TREE_TYPE (arg0); - - if (operand_equal_p (arg01, arg11, 0)) - { - tem = fold_convert_loc (loc, itype, arg10); - tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00, tem); - tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, tem, arg01); - return fold_build2_loc (loc, code, type, tem, - build_zero_cst (itype)); - } - if (operand_equal_p (arg01, arg10, 0)) - { - tem = fold_convert_loc (loc, itype, arg11); - tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00, tem); - tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, tem, arg01); - return fold_build2_loc (loc, code, type, tem, - build_zero_cst (itype)); - } - if (operand_equal_p (arg00, arg11, 0)) - { - tem = fold_convert_loc (loc, itype, arg10); - tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg01, tem); - tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, tem, arg00); - return fold_build2_loc (loc, code, type, tem, - build_zero_cst (itype)); - } - if (operand_equal_p (arg00, arg10, 0)) - { - tem = fold_convert_loc (loc, itype, arg11); - tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg01, tem); - tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, tem, arg00); - return fold_build2_loc (loc, code, type, tem, - build_zero_cst (itype)); - } - } - if (TREE_CODE (arg0) == BIT_XOR_EXPR && TREE_CODE (arg1) == BIT_XOR_EXPR) { --- gcc/match.pd.jj 2020-03-11 18:33:50.341663648 +0100 +++ gcc/match.pd 2020-04-23 19:17:37.954208051 +0200 @@ -4335,7 +4335,12 @@ (define_operator_list COND_TERNARY (simplify (cmp (convert? addr@0) integer_zerop) (if (tree_single_nonzero_warnv_p (@0, NULL)) - { constant_boolean_node (cmp == NE_EXPR, type); }))) + { constant_boolean_node (cmp == NE_EXPR, type); })) + + /* (X & C) op (Y & C) into (X ^ Y) & C op 0. */ + (simplify + (cmp (bit_and:cs @0 @2) (bit_and:cs @1 @2)) + (cmp (bit_and (bit_xor @0 @1) @2) { build_zero_cst (TREE_TYPE (@2)); }))) /* If we have (A & C) == C where C is a power of 2, convert this into (A & C) != 0. Similarly for NE_EXPR. */ is untested part without testsuite coverage that optimizes the above #c2 third test the same as #c2 second test. Unsure about :s.