This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Committed] Fold -X == -Y as X == Y


This patch implements some more simplifications of relational comparison
operators.  The motivation of the patch was that -X == -Y and ~X == ~Y
can both be simplified to X == Y (for both equality and inequality).
However, reading through simplify-rtx.c, it turns out that for "~",
we can also handle ordering comparisons, such as "~X < ~Y" is equivalent
to "X > Y".  Hence, we can generalize the existing "~X eq/ne C" code.

The following patch has been tested on i686-pc-linux-gnu, with a full
"make bootstrap", all default languages including Ada, and regression
tested with a top-level "make -k check" with no new failures.

Committed to mainline as revision 118158.



2006-10-29  Roger Sayle  <roger@eyesopen.com>

	* fold-const.c (fold_comparison): Fold ~X op ~Y as Y op X.
	Fold ~X op C as X op' ~C, where op' is the swapped comparison.
	(fold_binary): ~X eq/ne C is now handled in fold_comparison.
	Fold -X eq/ne -Y as X eq/ne Y.

	* gcc.dg/fold-compare-1.c: New test case.


Index: fold-const.c
===================================================================
*** fold-const.c	(revision 118098)
--- fold-const.c	(working copy)
*************** fold_comparison (enum tree_code code, tr
*** 8236,8241 ****
--- 8236,8255 ----
  	return tem;
      }

+   /* Fold ~X op ~Y as Y op X.  */
+   if (TREE_CODE (arg0) == BIT_NOT_EXPR
+       && TREE_CODE (arg1) == BIT_NOT_EXPR)
+     return fold_build2 (code, type,
+ 			TREE_OPERAND (arg1, 0),
+ 			TREE_OPERAND (arg0, 0));
+
+   /* Fold ~X op C as X op' ~C, where op' is the swapped comparison.  */
+   if (TREE_CODE (arg0) == BIT_NOT_EXPR
+       && TREE_CODE (arg1) == INTEGER_CST)
+     return fold_build2 (swap_tree_comparison (code), type,
+ 			TREE_OPERAND (arg0, 0),
+ 			fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1), arg1));
+
    return NULL_TREE;
  }

*************** fold_binary (enum tree_code code, tree t
*** 10295,10307 ****
            && code == EQ_EXPR)
          return fold_build1 (TRUTH_NOT_EXPR, type, arg0);

-       /*  ~a != C becomes a != ~C where C is a constant.  Likewise for ==.  */
-       if (TREE_CODE (arg0) == BIT_NOT_EXPR
- 	  && TREE_CODE (arg1) == INTEGER_CST)
- 	return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
- 			    fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1),
- 					 arg1));
-
        /* If this is an equality comparison of the address of a non-weak
  	 object against zero, then we know the result.  */
        if (TREE_CODE (arg0) == ADDR_EXPR
--- 10309,10314 ----
*************** fold_binary (enum tree_code code, tree t
*** 10667,10672 ****
--- 10674,10687 ----
  	  tree res = constant_boolean_node (code==NE_EXPR, type);
  	  return omit_one_operand (type, res, arg0);
  	}
+
+       /* Fold -X op -Y as X op Y, where op is eq/ne.  */
+       if (TREE_CODE (arg0) == NEGATE_EXPR
+           && TREE_CODE (arg1) == NEGATE_EXPR)
+ 	return fold_build2 (code, type,
+ 			    TREE_OPERAND (arg0, 0),
+ 			    TREE_OPERAND (arg1, 0));
+
        return NULL_TREE;

      case LT_EXPR:



/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-original" } */

int test1(int a, int b)
{
  return ~a == ~b;
}

int test2(int c, int d)
{
  return -c == -d;
}

int test3(int e)
{
  return -e == 5;
}

int test4(int f)
{
  return ~f == 5;
}

int test5(int g, int h)
{
  return ~g < ~h;
}

int test6(int i, int j)
{
  return ~i >= ~j;
}

int test7(int k)
{
  return ~k < 3;
}

int test8(int l)
{
  return ~l >= 2;
}

/* { dg-final { scan-tree-dump-times "b == a" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "c == d" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "e == -5" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "f == -6" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "h < g" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "j >= i" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "k > -4" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "l <= -3" 1 "original" } } */
/* { dg-final { cleanup-tree-dump "original" } } */


Roger
--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]