Hello, This patch adds support to fold_truth_andor for one-bit precision typed bitwise-binary and bitwise-not expressions.
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);