This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR26898, folding of X +- C1 CMP Y +- C2
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 30 Mar 2006 15:16:44 +0200 (CEST)
- Subject: [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;
}