re PR middle-end/26898 (Fold does not fold signed + CST1 CMP signed + CST2)

2006-10-21  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/torture/pr26898-1.c: New testcase.
	* gcc.dg/torture/pr26898-2.c: Likewise.

From-SVN: r117931
This commit is contained in:
Richard Guenther 2006-10-21 13:21:06 +00:00 committed by Richard Biener
parent 5a4171a01d
commit 8a1eca0803
5 changed files with 80 additions and 0 deletions

View file

@ -1,3 +1,9 @@
2006-10-21 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.
2006-10-21 Richard Guenther <rguenther@suse.de>
PR target/19116

View file

@ -7835,6 +7835,48 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
}
}
/* Transform comparisons of the form X +- C1 CMP Y +- C2 to
X CMP Y +- C2 +- C1 for signed X, Y. This is valid if
the resulting offset is smaller in absolute value than the
original one. */
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 const2 = TREE_OPERAND (arg1, 1);
tree variable1 = TREE_OPERAND (arg0, 0);
tree variable2 = TREE_OPERAND (arg1, 0);
tree cst;
/* Put the constant on the side where it doesn't overflow and is
of lower absolute value than before. */
cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1)
? MINUS_EXPR : PLUS_EXPR,
const2, const1, 0);
if (!TREE_OVERFLOW (cst)
&& tree_int_cst_compare (const2, cst) == tree_int_cst_sgn (const2))
return fold_build2 (code, type,
variable1,
fold_build2 (TREE_CODE (arg1), TREE_TYPE (arg1),
variable2, cst));
cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1)
? MINUS_EXPR : PLUS_EXPR,
const1, const2, 0);
if (!TREE_OVERFLOW (cst)
&& tree_int_cst_compare (const1, cst) == tree_int_cst_sgn (const1))
return fold_build2 (code, type,
fold_build2 (TREE_CODE (arg0), TREE_TYPE (arg0),
variable1, cst),
variable2);
}
if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
{
tree targ0 = strip_float_extensions (arg0);

View file

@ -1,3 +1,9 @@
2006-10-21 Richard Guenther <rguenther@suse.de>
PR middle-end/26898
* gcc.dg/torture/pr26898-1.c: New testcase.
* gcc.dg/torture/pr26898-2.c: Likewise.
2006-10-20 Lee Millward <lee.millward@codesourcery.com>
PR c++/28053

View file

@ -0,0 +1,14 @@
/* { dg-do link } */
#include <limits.h>
extern void link_error(void);
int main()
{
int i0, i1;
if (!(i0 + 1 < i1 + 1 == i0 < i1))
link_error ();
if (!(i0 + INT_MIN < i1 - INT_MAX == i0 < i1 - -1))
link_error ();
return 0;
}

View file

@ -0,0 +1,12 @@
/* { dg-do run } */
#include <limits.h>
int a = 0, b = INT_MAX - 1;
extern void abort(void);
int main()
{
if (a - 1 > b + 1)
abort();
return 0;
}