On Wed, Apr 20, 2011 at 5:58 PM, Kai Tietz <ktiet...@googlemail.com> wrote: > 2011/4/20 Jakub Jelinek <ja...@redhat.com>: >> 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 >> > > Well, as special case we could use that, but we have here also to > handle integer-values, so I used fold to make sure I get inverse. Also > there might be some transformations, which otherwise might be not > caught, like !(X || Y) == !X && !Y ...
Btw, I agree with Jakub. Fold is suppose to not create any garbage if a folding does not apply. So I don't like your patch either. Richard. > Regards, > Kai > > > -- > | (\_/) This is Bunny. Copy and paste > | (='.'=) Bunny into your signature to help > | (")_(") him gain world domination >