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 PR26898, folding of X +- C1 CMP Y +- C2


Bootstrapped and tested on x86_64-unknown-linux-gnu.

Ok for mainline?

Thanks,
Richard.

2006-03-29  Richard Guenther  <rguenther@suse.de>

	PR middle-end/26898
	* fold-const.c (fold_comparison): Fold signed comparisons
	of the form X +- C1 CMP Y +- C2.

	* gcc.dg/pr26898.c: New testcase.

Index: fold-const.c
===================================================================
*** fold-const.c	(revision 112415)
--- fold-const.c	(working copy)
*************** fold_comparison (enum tree_code code, tr
*** 7340,7345 ****
--- 7340,7372 ----
  	return fold_build2 (code, type, variable, lhs);
      }
  
+   /* Transform comparisons of the form X +- C1 CMP Y +- C2 to
+      X CMP Y +- C2 +- C1 for signed X, Y.  */
+   if (!(flag_wrapv || flag_trapv)
+       && !TYPE_UNSIGNED (TREE_TYPE (arg0))
+       && (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
+       && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
+ 	  && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)))
+       && (TREE_CODE (arg1) == PLUS_EXPR || TREE_CODE (arg1) == MINUS_EXPR)
+       && (TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
+ 	  && !TREE_OVERFLOW (TREE_OPERAND (arg1, 1))))
+     {
+       tree const1 = TREE_OPERAND (arg0, 1);
+       tree variable1 = TREE_OPERAND (arg0, 0);
+       tree lhs;
+       int lhs_add;
+       lhs_add = TREE_CODE (arg0) != PLUS_EXPR;
+       lhs = fold_build2 (lhs_add ? PLUS_EXPR : MINUS_EXPR,
+ 			 TREE_TYPE (arg0), arg1, const1);
+       /* Either we were able to produce X CMP Y, or X CMP Y +- CST, in
+ 	 which case we need to check for possible overflows of CST.  */
+       if ((TREE_CODE (lhs) != PLUS_EXPR
+ 	   && TREE_CODE (lhs) != MINUS_EXPR)
+ 	  || (TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
+ 	      && !TREE_OVERFLOW (TREE_OPERAND (lhs, 1))))
+ 	return fold_build2 (code, type, variable1, lhs);
+     }
+ 
    if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
      {
        tree targ0 = strip_float_extensions (arg0);

/* { dg-do link } */
/* { dg-options "-O2" } */

extern void link_error(void);
int main()
{
  int i0, i1;
  if (!(i0 + 1 < i1 + 1 == i0 < i1))
    link_error ();
  return 0;
}


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