Message ID | CAEwic4YZbE-C2Jci-miVQLM30GqxLEb4mgvsmVQ0KY3uXo6dag@mail.gmail.com |
---|---|
State | New |
Headers | show |
On Wed, Jul 13, 2011 at 9:34 AM, Kai Tietz <ktietz70@googlemail.com> wrote: > Hello, > > This patch adds support to fold_binary_loc for one-bit precision > typed bitwise-xor expression. Similar - we don't want to build a TRUTH_NOT_EXPR from a BIT_XOR_EXPR. > ChangeLog > > 2011-07-13 Kai Tietz <ktietz@redhat.com> > > * fold-const.c (fold_binary_loc): Add > support for one-bit bitwise-xor optimizeation. > > Bootstrapped and regression tested with prior patches of this series > for x86_64-pc-linux-gnu. > Ok for apply? > > Regards, > Kai > > Index: gcc/gcc/fold-const.c > =================================================================== > --- gcc.orig/gcc/fold-const.c 2011-07-13 08:38:06.000000000 +0200 > +++ gcc/gcc/fold-const.c 2011-07-13 08:58:52.686620200 +0200 > @@ -10872,11 +10872,35 @@ fold_binary_loc (location_t loc, > case BIT_XOR_EXPR: > if (integer_zerop (arg1)) > return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0)); > - if (integer_all_onesp (arg1)) > - return fold_build1_loc (loc, BIT_NOT_EXPR, type, op0); > if (operand_equal_p (arg0, arg1, 0)) > return omit_one_operand_loc (loc, type, integer_zero_node, arg0); > > + if (TYPE_PRECISION (type) == 1 && INTEGRAL_TYPE_P (type)) > + { > + /* If the second arg is constant true, this is a logical inversion. */ > + if (integer_onep (arg1)) > + { > + tem = invert_truthvalue_loc (loc, arg0); > + return non_lvalue_loc (loc, fold_convert_loc (loc, type, tem)); > + } > + } > + else if (integer_all_onesp (arg1)) > + return fold_build1_loc (loc, BIT_NOT_EXPR, type, op0); > + > + if (TYPE_PRECISION (type) == 1 && INTEGRAL_TYPE_P (type)) > + { > + /* !X ^ X is always true. ~X ^X is always true. */ > + if ((TREE_CODE (arg0) == TRUTH_NOT_EXPR > + || TREE_CODE (arg0) == BIT_NOT_EXPR) > + && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) > + return omit_one_operand_loc (loc, type, integer_one_node, arg1); > + /* X ^ !X is always true. X ^ ~X is always true. */ > + if ((TREE_CODE (arg1) == TRUTH_NOT_EXPR > + || TREE_CODE (arg1) == BIT_NOT_EXPR) > + && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) > + return omit_one_operand_loc (loc, type, integer_one_node, arg0); > + } > + > /* ~X ^ X is -1. */ > if (TREE_CODE (arg0) == BIT_NOT_EXPR > && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) > @@ -10911,7 +10935,7 @@ fold_binary_loc (location_t loc, > goto bit_ior; > } > > - /* (X | Y) ^ X -> Y & ~ X*/ > + /* (X | Y) ^ X -> Y & ~ X. */ > if (TREE_CODE (arg0) == BIT_IOR_EXPR > && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) > { >
Index: gcc/gcc/fold-const.c =================================================================== --- gcc.orig/gcc/fold-const.c 2011-07-13 08:38:06.000000000 +0200 +++ gcc/gcc/fold-const.c 2011-07-13 08:58:52.686620200 +0200 @@ -10872,11 +10872,35 @@ fold_binary_loc (location_t loc, case BIT_XOR_EXPR: if (integer_zerop (arg1)) return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0)); - if (integer_all_onesp (arg1)) - return fold_build1_loc (loc, BIT_NOT_EXPR, type, op0); if (operand_equal_p (arg0, arg1, 0)) return omit_one_operand_loc (loc, type, integer_zero_node, arg0); + if (TYPE_PRECISION (type) == 1 && INTEGRAL_TYPE_P (type)) + { + /* If the second arg is constant true, this is a logical inversion. */ + if (integer_onep (arg1)) + { + tem = invert_truthvalue_loc (loc, arg0); + return non_lvalue_loc (loc, fold_convert_loc (loc, type, tem)); + } + } + else if (integer_all_onesp (arg1)) + return fold_build1_loc (loc, BIT_NOT_EXPR, type, op0); + + if (TYPE_PRECISION (type) == 1 && INTEGRAL_TYPE_P (type)) + { + /* !X ^ X is always true. ~X ^X is always true. */ + if ((TREE_CODE (arg0) == TRUTH_NOT_EXPR + || TREE_CODE (arg0) == BIT_NOT_EXPR) + && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) + return omit_one_operand_loc (loc, type, integer_one_node, arg1); + /* X ^ !X is always true. X ^ ~X is always true. */ + if ((TREE_CODE (arg1) == TRUTH_NOT_EXPR + || TREE_CODE (arg1) == BIT_NOT_EXPR) + && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) + return omit_one_operand_loc (loc, type, integer_one_node, arg0); + } + /* ~X ^ X is -1. */ if (TREE_CODE (arg0) == BIT_NOT_EXPR && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) @@ -10911,7 +10935,7 @@ fold_binary_loc (location_t loc, goto bit_ior; } - /* (X | Y) ^ X -> Y & ~ X*/ + /* (X | Y) ^ X -> Y & ~ X. */ if (TREE_CODE (arg0) == BIT_IOR_EXPR && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) {