On Wed, Jul 13, 2011 at 11:04 AM, Kai Tietz <ktiet...@googlemail.com> wrote: > Sorrty, the TRUTH_NOT_EXPR isn't here the point at all. The underlying > issue is that fold-const re-inttroduces TRUTH_AND/OR and co.
I'm very sure it doesn't re-constrct TRUTH_ variants out of thin air when you present it with BIT_ variants as input. To avoid > it, it needs to learn to handle 1-bit precision folding for those > bitwise-operation on 1-bit integer types special. > As gimple replies on this FE fold for now, it has to be learn about > that. As soon as gimple_fold (and other passes) don't rely anymore on > FE's fold-const, then we can remove those parts again. Otherwise this > boolification of compares (and also the transition of TRUTH_NOT -> > BIT_NOT, simply doesn't work so long. I do not believe that. > > Regards, > Kai > > 2011/7/13 Richard Guenther <richard.guent...@gmail.com>: >> On Wed, Jul 13, 2011 at 9:32 AM, Kai Tietz <ktiet...@googlemail.com> wrote: >>> 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. >> >> It seems this is only necessary because we still have TRUTH_NOT_EXPR >> in our IL and did not replace that with BIT_NOT_EXPR consistently yet. >> >> So no, this is not ok. fold-const.c is really mostly supposed to deal >> with GENERIC where we distinguish TRUTH_* and BIT_* variants. >> >> Please instead lower TRUTH_NOT_EXPR to BIT_NOT_EXPR for gimple. >> >> Richard. >> >>> 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); >>> >> > > > > -- > | (\_/) This is Bunny. Copy and paste > | (='.'=) Bunny into your signature to help > | (")_(") him gain world domination >