On Wed, Jul 13, 2011 at 9:33 AM, Kai Tietz <ktiet...@googlemail.com> wrote:
> Hello,
>
> This patch adds support to fold_truth_andor for one-bit precision
> typed bitwise-binary and bitwise-not expressions.

Quickly checking some testcases shows we already perform all
the foldings in other places.  So please _always_ check for
all transformations you add if there is a testcase that fails before
and passes after your patch.

(A|B)&(A|C) is already folded to (B&C)|A.

Richard.

> 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);
>

Reply via email to