On Wed, Jul 13, 2011 at 9:33 AM, Kai Tietz <ktiet...@googlemail.com> wrote: > Hello, > > This patch adds support to fold_truth_andor for one-bit precision > typed bitwise-binary and bitwise-not expressions.
Quickly checking some testcases shows we already perform all the foldings in other places. So please _always_ check for all transformations you add if there is a testcase that fails before and passes after your patch. (A|B)&(A|C) is already folded to (B&C)|A. Richard. > ChangeLog > > 2011-07-13 Kai Tietz <kti...@redhat.com> > > * fold-const.c (fold_truth_andor): Add > support for one-bit bitwise operations. > > 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:19:22.000000000 +0200 > +++ gcc/gcc/fold-const.c 2011-07-13 08:59:14.261620200 +0200 > @@ -8248,6 +8248,12 @@ fold_truth_andor (location_t loc, enum t > if (!optimize) > return NULL_TREE; > > + /* If code is BIT_AND_EXPR or BIT_IOR_EXPR, type precision has to be > + one. Otherwise return NULL_TREE. */ > + if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR) > + && (!INTEGRAL_TYPE_P (type) || TYPE_PRECISION (type) != 1)) > + return NULL_TREE; > + > /* Check for things like (A || B) && (A || C). We can convert this > to A || (B && C). Note that either operator can be any of the four > truth and/or operations and the transformation will still be > @@ -8258,7 +8264,9 @@ fold_truth_andor (location_t loc, enum t > && (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR > || TREE_CODE (arg0) == TRUTH_ORIF_EXPR > || TREE_CODE (arg0) == TRUTH_AND_EXPR > - || TREE_CODE (arg0) == TRUTH_OR_EXPR) > + || TREE_CODE (arg0) == TRUTH_OR_EXPR > + || TREE_CODE (arg0) == BIT_AND_EXPR > + || TREE_CODE (arg0) == BIT_IOR_EXPR) > && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1))) > { > tree a00 = TREE_OPERAND (arg0, 0); > @@ -8266,9 +8274,13 @@ fold_truth_andor (location_t loc, enum t > tree a10 = TREE_OPERAND (arg1, 0); > tree a11 = TREE_OPERAND (arg1, 1); > int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR > - || TREE_CODE (arg0) == TRUTH_AND_EXPR) > + || TREE_CODE (arg0) == TRUTH_AND_EXPR > + || TREE_CODE (arg0) == BIT_IOR_EXPR > + || TREE_CODE (arg0) == BIT_AND_EXPR) > && (code == TRUTH_AND_EXPR > - || code == TRUTH_OR_EXPR)); > + || code == TRUTH_OR_EXPR > + || code == BIT_AND_EXPR > + || code == BIT_IOR_EXPR)); > > if (operand_equal_p (a00, a10, 0)) > return fold_build2_loc (loc, TREE_CODE (arg0), type, a00, > @@ -9484,21 +9496,29 @@ fold_binary_loc (location_t loc, > > if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR > || code == EQ_EXPR || code == NE_EXPR) > - && ((truth_value_p (TREE_CODE (arg0)) > - && (truth_value_p (TREE_CODE (arg1)) > + && ((truth_value_type_p (TREE_CODE (arg0), TREE_TYPE (arg0)) > + && (truth_value_type_p (TREE_CODE (arg1), TREE_TYPE (arg1)) > || (TREE_CODE (arg1) == BIT_AND_EXPR > && integer_onep (TREE_OPERAND (arg1, 1))))) > - || (truth_value_p (TREE_CODE (arg1)) > - && (truth_value_p (TREE_CODE (arg0)) > + || (truth_value_type_p (TREE_CODE (arg1), TREE_TYPE (arg1)) > + && (truth_value_type_p (TREE_CODE (arg0), TREE_TYPE (arg0)) > || (TREE_CODE (arg0) == BIT_AND_EXPR > && integer_onep (TREE_OPERAND (arg0, 1))))))) > { > - tem = fold_build2_loc (loc, code == BIT_AND_EXPR ? TRUTH_AND_EXPR > - : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR > - : TRUTH_XOR_EXPR, > - boolean_type_node, > - fold_convert_loc (loc, boolean_type_node, arg0), > - fold_convert_loc (loc, boolean_type_node, arg1)); > + enum tree_code ncode; > + > + /* Do we operate on a non-boolified tree? */ > + if (!INTEGRAL_TYPE_P (type) || TYPE_PRECISION (type) != 1) > + ncode = code == BIT_AND_EXPR ? TRUTH_AND_EXPR > + : (code == BIT_IOR_EXPR > + ? TRUTH_OR_EXPR : TRUTH_XOR_EXPR); > + else > + ncode = (code == BIT_AND_EXPR || code == BIT_IOR_EXPR) ? code > + : BIT_XOR_EXPR; > + tem = fold_build2_loc (loc, ncode, > + boolean_type_node, > + fold_convert_loc (loc, boolean_type_node, arg0), > + fold_convert_loc (loc, boolean_type_node, arg1)); > > if (code == EQ_EXPR) > tem = invert_truthvalue_loc (loc, tem); >