Hello, I split my old patch into 8 speparate pieces for easier review. These patches are a prerequist for enabling boolification of comparisons in gimplifier and the necessary type-cast preserving in gimple from/to boolean-type.
This patch adds support to fold_truth_not_expr 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_not_expr): Add support for one-bit bitwise operations. Bootstrapped and regression tested 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 07:48:29.000000000 +0200 +++ gcc/gcc/fold-const.c 2011-07-13 08:59:36.865620200 +0200 @@ -3074,20 +3074,36 @@ fold_truth_not_expr (location_t loc, tre case INTEGER_CST: return constant_boolean_node (integer_zerop (arg), type); + case BIT_AND_EXPR: + if (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) != 1) + return NULL_TREE; + if (integer_onep (TREE_OPERAND (arg, 1))) + return build2_loc (loc, EQ_EXPR, type, arg, build_int_cst (type, 0)); + /* fall through */ case TRUTH_AND_EXPR: loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc); loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc); - return build2_loc (loc, TRUTH_OR_EXPR, type, + return build2_loc (loc, (code == BIT_AND_EXPR ? BIT_IOR_EXPR + : TRUTH_OR_EXPR), type, invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)), invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1))); + case BIT_IOR_EXPR: + if (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) != 1) + return NULL_TREE; + /* fall through. */ case TRUTH_OR_EXPR: loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc); loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc); - return build2_loc (loc, TRUTH_AND_EXPR, type, + return build2_loc (loc, (code == BIT_IOR_EXPR ? BIT_AND_EXPR + : TRUTH_AND_EXPR), type, invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)), invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1))); + case BIT_XOR_EXPR: + if (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) != 1) + return NULL_TREE; + /* fall through. */ case TRUTH_XOR_EXPR: /* Here we can invert either operand. We invert the first operand unless the second operand is a TRUTH_NOT_EXPR in which case our @@ -3095,10 +3111,14 @@ fold_truth_not_expr (location_t loc, tre negation of the second operand. */ if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR) - return build2_loc (loc, TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0), + return build2_loc (loc, code, type, TREE_OPERAND (arg, 0), + TREE_OPERAND (TREE_OPERAND (arg, 1), 0)); + else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BIT_NOT_EXPR + && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 1))) == 1) + return build2_loc (loc, code, type, TREE_OPERAND (arg, 0), TREE_OPERAND (TREE_OPERAND (arg, 1), 0)); else - return build2_loc (loc, TRUTH_XOR_EXPR, type, + return build2_loc (loc, code, type, invert_truthvalue_loc (loc, TREE_OPERAND (arg, 0)), TREE_OPERAND (arg, 1)); @@ -3116,6 +3136,10 @@ fold_truth_not_expr (location_t loc, tre invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)), invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1))); + case BIT_NOT_EXPR: + if (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) != 1) + return NULL_TREE; + /* fall through */ case TRUTH_NOT_EXPR: return TREE_OPERAND (arg, 0); @@ -3158,11 +3182,6 @@ fold_truth_not_expr (location_t loc, tre return build1_loc (loc, TREE_CODE (arg), type, invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0))); - case BIT_AND_EXPR: - if (!integer_onep (TREE_OPERAND (arg, 1))) - return NULL_TREE; - return build2_loc (loc, EQ_EXPR, type, arg, build_int_cst (type, 0)); - case SAVE_EXPR: return build1_loc (loc, TRUTH_NOT_EXPR, type, arg);