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

Reply via email to