On Wed, Apr 20, 2011 at 05:22:31PM +0200, Kai Tietz wrote:
> --- gcc.orig/gcc/fold-const.c 2011-04-20 17:10:39.478091900 +0200
> +++ gcc/gcc/fold-const.c      2011-04-20 17:11:22.901039400 +0200
> @@ -10660,6 +10660,28 @@ fold_binary_loc (location_t loc,
>         && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
>       return omit_one_operand_loc (loc, type, arg0, TREE_OPERAND (arg1, 0));
>  
> +      /* (X & ~Y) | (~X & Y) is X ^ Y */
> +      if (TREE_CODE (arg0) == BIT_AND_EXPR
> +       && TREE_CODE (arg1) == BIT_AND_EXPR)
> +        {
> +       tree a0, a1, l0, l1, n0, n1;
> +
> +       a0 = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 0));
> +       a1 = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 1));
> +
> +       l0 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
> +       l1 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1));
> +       
> +       n0 = fold_build1_loc (loc, BIT_NOT_EXPR, type, l0);
> +       n1 = fold_build1_loc (loc, BIT_NOT_EXPR, type, l1);
> +       
> +       if ((operand_equal_p (n0, a0, 0)
> +            && operand_equal_p (n1, a1, 0))
> +           || (operand_equal_p (n0, a1, 0)
> +               && operand_equal_p (n1, a0, 0)))
> +         return fold_build2_loc (loc, TRUTH_XOR_EXPR, type, l0, n1);
> +     }
> +
I must say I don't like first folding/building new trees, then testing
and then maybe optimizing, that is slow and creates unnecessary garbage
in the likely case the optimization can't do anything.

Wouldn't something like:
    int arg0_not = TREE_CODE (TREE_OPERAND (arg0, 1)) == BIT_NOT_EXPR;
    int arg1_not = TREE_CODE (TREE_OPERAND (arg1, 1)) == BIT_NOT_EXPR;
    if (TREE_CODE (TREE_OPERAND (arg0, arg0_not)) == BIT_NOT_EXPR
        && TREE_CODE (TREE_OPERAND (arg1, arg1_not)) == BIT_NOT_EXPR
        && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, arg0_not), 0),
                            TREE_OPERAND (arg1, 1 - arg1_not), 0)
        && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg1, arg1_not), 0),
                            TREE_OPERAND (arg0, 1 - arg0_not), 0))
      return fold_build2_loc (loc, TRUTH_XOR_EXPR, type,
                              fold_convert_loc (loc, type,
                                                TREE_OPERAND (arg0, 1 - 
arg0_not)),
                              fold_convert_loc (loc, type,
                                                TREE_OPERAND (arg1, 1 - 
arg1_not)));
work better?

        Jakub

Reply via email to