diff mbox

[5/8,tree-optimization] : Bitwise xor logic for fold_binary_loc.

Message ID CAEwic4YZbE-C2Jci-miVQLM30GqxLEb4mgvsmVQ0KY3uXo6dag@mail.gmail.com
State New
Headers show

Commit Message

Kai Tietz July 13, 2011, 7:34 a.m. UTC
Hello,

This patch adds support to fold_binary_loc for one-bit precision
typed bitwise-xor expression.

ChangeLog

2011-07-13  Kai Tietz  <ktietz@redhat.com>

	* fold-const.c (fold_binary_loc): Add
	support for one-bit bitwise-xor optimizeation.

Bootstrapped and regression tested with prior patches of this series
for x86_64-pc-linux-gnu.
Ok for apply?

Regards,
Kai

Comments

Richard Biener July 13, 2011, 10:29 a.m. UTC | #1
On Wed, Jul 13, 2011 at 9:34 AM, Kai Tietz <ktietz70@googlemail.com> wrote:
> Hello,
>
> This patch adds support to fold_binary_loc for one-bit precision
> typed bitwise-xor expression.

Similar - we don't want to build a TRUTH_NOT_EXPR from a BIT_XOR_EXPR.

> ChangeLog
>
> 2011-07-13  Kai Tietz  <ktietz@redhat.com>
>
>        * fold-const.c (fold_binary_loc): Add
>        support for one-bit bitwise-xor optimizeation.
>
> 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:38:06.000000000 +0200
> +++ gcc/gcc/fold-const.c        2011-07-13 08:58:52.686620200 +0200
> @@ -10872,11 +10872,35 @@ fold_binary_loc (location_t loc,
>     case BIT_XOR_EXPR:
>       if (integer_zerop (arg1))
>        return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0));
> -      if (integer_all_onesp (arg1))
> -       return fold_build1_loc (loc, BIT_NOT_EXPR, type, op0);
>       if (operand_equal_p (arg0, arg1, 0))
>        return omit_one_operand_loc (loc, type, integer_zero_node, arg0);
>
> +      if (TYPE_PRECISION (type) == 1 && INTEGRAL_TYPE_P (type))
> +        {
> +         /* If the second arg is constant true, this is a logical inversion.  */
> +         if (integer_onep (arg1))
> +           {
> +             tem = invert_truthvalue_loc (loc, arg0);
> +             return non_lvalue_loc (loc, fold_convert_loc (loc, type, tem));
> +           }
> +       }
> +      else if (integer_all_onesp (arg1))
> +       return fold_build1_loc (loc, BIT_NOT_EXPR, type, op0);
> +
> +      if (TYPE_PRECISION (type) == 1 && INTEGRAL_TYPE_P (type))
> +        {
> +         /* !X ^ X is always true.  ~X ^X is always true.  */
> +         if ((TREE_CODE (arg0) == TRUTH_NOT_EXPR
> +              || TREE_CODE (arg0) == BIT_NOT_EXPR)
> +             && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
> +           return omit_one_operand_loc (loc, type, integer_one_node, arg1);
> +         /* X ^ !X is always true.  X ^ ~X is always true.  */
> +         if ((TREE_CODE (arg1) == TRUTH_NOT_EXPR
> +              || TREE_CODE (arg1) == BIT_NOT_EXPR)
> +             && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
> +           return omit_one_operand_loc (loc, type, integer_one_node, arg0);
> +       }
> +
>       /* ~X ^ X is -1.  */
>       if (TREE_CODE (arg0) == BIT_NOT_EXPR
>          && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
> @@ -10911,7 +10935,7 @@ fold_binary_loc (location_t loc,
>          goto bit_ior;
>        }
>
> -      /* (X | Y) ^ X -> Y & ~ X*/
> +      /* (X | Y) ^ X -> Y & ~ X.  */
>       if (TREE_CODE (arg0) == BIT_IOR_EXPR
>           && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
>         {
>
diff mbox

Patch

Index: gcc/gcc/fold-const.c
===================================================================
--- gcc.orig/gcc/fold-const.c	2011-07-13 08:38:06.000000000 +0200
+++ gcc/gcc/fold-const.c	2011-07-13 08:58:52.686620200 +0200
@@ -10872,11 +10872,35 @@  fold_binary_loc (location_t loc,
     case BIT_XOR_EXPR:
       if (integer_zerop (arg1))
 	return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0));
-      if (integer_all_onesp (arg1))
-	return fold_build1_loc (loc, BIT_NOT_EXPR, type, op0);
       if (operand_equal_p (arg0, arg1, 0))
 	return omit_one_operand_loc (loc, type, integer_zero_node, arg0);

+      if (TYPE_PRECISION (type) == 1 && INTEGRAL_TYPE_P (type))
+        {
+	  /* If the second arg is constant true, this is a logical inversion.  */
+	  if (integer_onep (arg1))
+	    {
+	      tem = invert_truthvalue_loc (loc, arg0);
+	      return non_lvalue_loc (loc, fold_convert_loc (loc, type, tem));
+	    }
+	}
+      else if (integer_all_onesp (arg1))
+	return fold_build1_loc (loc, BIT_NOT_EXPR, type, op0);
+
+      if (TYPE_PRECISION (type) == 1 && INTEGRAL_TYPE_P (type))
+        {
+	  /* !X ^ X is always true.  ~X ^X is always true.  */
+	  if ((TREE_CODE (arg0) == TRUTH_NOT_EXPR
+	       || TREE_CODE (arg0) == BIT_NOT_EXPR)
+	      && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
+	    return omit_one_operand_loc (loc, type, integer_one_node, arg1);
+	  /* X ^ !X is always true.  X ^ ~X is always true.  */
+	  if ((TREE_CODE (arg1) == TRUTH_NOT_EXPR
+	       || TREE_CODE (arg1) == BIT_NOT_EXPR)
+	      && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
+	    return omit_one_operand_loc (loc, type, integer_one_node, arg0);
+	}
+
       /* ~X ^ X is -1.  */
       if (TREE_CODE (arg0) == BIT_NOT_EXPR
 	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
@@ -10911,7 +10935,7 @@  fold_binary_loc (location_t loc,
 	  goto bit_ior;
 	}

-      /* (X | Y) ^ X -> Y & ~ X*/
+      /* (X | Y) ^ X -> Y & ~ X.  */
       if (TREE_CODE (arg0) == BIT_IOR_EXPR
           && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
         {