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. 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.
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