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]

[PATCH] Fix PR31029, fold C - X CMP X and X +- Y CMP X


This adds two new equality comparison foldings as suggested in PR31029.
We can fold C - X ==/!= X for odd C as well as X +- Y CMP X as
generalization to X +- C CMP X.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2009-03-31  Richard Guenther  <rguenther@suse.de>

	PR middle-end/31029
	* fold-const.c (fold_binary): Fold X +- Y CMP X to Y CMP 0 for
	equality comparisons.  Fold C - X CMP X if C % 2 == 1.

	* gcc.dg/fold-compare-4.c: New testcase.
	* gcc.dg/fold-compare-5.c: Likewise.

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c.orig	2009-03-31 14:28:57.000000000 +0200
--- gcc/fold-const.c	2009-03-31 14:29:16.000000000 +0200
*************** fold_binary (enum tree_code code, tree t
*** 12191,12212 ****
  					 fold_convert (TREE_TYPE (arg0), arg1),
  					 TREE_OPERAND (arg0, 1)));
  
!       /* Transform comparisons of the form X +- C CMP X.  */
!       if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
  	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
- 	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
  	  && (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
  	      || POINTER_TYPE_P (TREE_TYPE (arg0))))
  	{
! 	  tree cst = TREE_OPERAND (arg0, 1);
  
! 	  if (code == EQ_EXPR
! 	      && !integer_zerop (cst))
! 	    return omit_two_operands (type, boolean_false_node,
! 				      TREE_OPERAND (arg0, 0), arg1);
! 	  else
! 	    return omit_two_operands (type, boolean_true_node,
! 				      TREE_OPERAND (arg0, 0), arg1);
  	}
  
        /* If we have X - Y == 0, we can convert that to X == Y and similarly
--- 12191,12223 ----
  					 fold_convert (TREE_TYPE (arg0), arg1),
  					 TREE_OPERAND (arg0, 1)));
  
!       /* Transform comparisons of the form X +- Y CMP X to Y CMP 0.  */
!       if ((TREE_CODE (arg0) == PLUS_EXPR
! 	   || TREE_CODE (arg0) == POINTER_PLUS_EXPR
! 	   || TREE_CODE (arg0) == MINUS_EXPR)
  	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
  	  && (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
  	      || POINTER_TYPE_P (TREE_TYPE (arg0))))
  	{
! 	  tree val = TREE_OPERAND (arg0, 1);
! 	  return omit_two_operands (type,
! 				    fold_build2 (code, type,
! 						 val,
! 						 build_int_cst (TREE_TYPE (val),
! 								0)),
! 				    TREE_OPERAND (arg0, 0), arg1);
! 	}
  
!       /* Transform comparisons of the form C - X CMP X if C % 2 == 1.  */
!       if (TREE_CODE (arg0) == MINUS_EXPR
! 	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == INTEGER_CST
! 	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0)
! 	  && (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 0)) & 1) == 1)
! 	{
! 	  return omit_two_operands (type,
! 				    code == NE_EXPR
! 				    ? boolean_true_node : boolean_false_node,
! 				    TREE_OPERAND (arg0, 1), arg1);
  	}
  
        /* If we have X - Y == 0, we can convert that to X == Y and similarly
Index: gcc/testsuite/gcc.dg/fold-compare-4.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/fold-compare-4.c	2009-03-31 14:29:07.000000000 +0200
***************
*** 0 ****
--- 1,23 ----
+ /* { dg-do compile } */
+ /* { dg-options "-fdump-tree-original" } */
+ 
+ int test1 (int a, int b)
+ {
+   return a - b == a;
+ }
+ int test2 (int a, int b)
+ {
+   return a + b == a;
+ }
+ int test3 (int a)
+ {
+   return a + 5 == a;
+ }
+ int test4 (int a)
+ {
+   return a - 5 == a;
+ }
+ 
+ /* { dg-final { scan-tree-dump-times "b == 0" 2 "original" } } */
+ /* { dg-final { scan-tree-dump-times "return 0" 2 "original" } } */
+ /* { dg-final { cleanup-tree-dump "original" } } */
Index: gcc/testsuite/gcc.dg/fold-compare-5.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/fold-compare-5.c	2009-03-31 14:29:07.000000000 +0200
***************
*** 0 ****
--- 1,20 ----
+ /* { dg-do compile } */
+ /* { dg-options "-fdump-tree-original" } */
+ 
+ int test1 (int a)
+ {
+   return 2 - a == a;
+ }
+ int test2 (int a)
+ {
+   return 1 - a == a;
+ }
+ int test3 (int a)
+ {
+   return 1 - a != a;
+ }
+ 
+ /* { dg-final { scan-tree-dump-times "return 2 - a == a" 1 "original" } } */
+ /* { dg-final { scan-tree-dump-times "return 0" 1 "original" } } */
+ /* { dg-final { scan-tree-dump-times "return 1" 1 "original" } } */
+ /* { dg-final { cleanup-tree-dump "original" } } */


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