This fixes the performance regression introduced by my recent patch that added the X - Y CMP 0 to X CMP Y transformation to the folder for other operators than the equality operators. It turns out that it badly interacts with another one in fold_cond_expr_with_comparison which attempts to synthetize ABS_EXPR. The transformation had been added as a preliminary work for a specific purpose but was made obsolete in the meantime, so the patch simply disables it with a ??? comment.
Tested on x86_64-suse-linux, applied on the mainline. 2014-07-28 Eric Botcazou <ebotca...@adacore.com> PR middle-end/61734 * fold-const.c (fold_comparison): Disable X - Y CMP 0 to X CMP Y for operators other than the equality operators. 2014-07-28 Eric Botcazou <ebotca...@adacore.com> * gcc.dg/fold-abs-5.c: New test. * gcc.dg/Wstrict-overflow-25.c: XFAIL everywhere. * gcc.dg/fold-compare-8.c: Likewise. -- Eric Botcazou
Index: fold-const.c =================================================================== --- fold-const.c (revision 213075) +++ fold-const.c (working copy) @@ -9026,9 +9026,13 @@ fold_comparison (location_t loc, enum tr /* Transform comparisons of the form X - Y CMP 0 to X CMP Y. */ if (TREE_CODE (arg0) == MINUS_EXPR - && (equality_code || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))) + && equality_code && integer_zerop (arg1)) { + /* ??? The transformation is valid for the other operators if overflow + is undefined for the type, but performing it here badly interacts + with the transformation in fold_cond_expr_with_comparison which + attempts to synthetize ABS_EXPR. */ if (!equality_code) fold_overflow_warning ("assuming signed overflow does not occur " "when changing X - Y cmp 0 to X cmp Y", Index: testsuite/gcc.dg/Wstrict-overflow-25.c =================================================================== --- testsuite/gcc.dg/Wstrict-overflow-25.c (revision 213075) +++ testsuite/gcc.dg/Wstrict-overflow-25.c (working copy) @@ -7,5 +7,5 @@ int foo (int x, int y) { - return x - y < 0; /* { dg-warning "assuming signed overflow does not occur" "correct warning" } */ + return x - y < 0; /* { dg-warning "assuming signed overflow does not occur" "correct warning" { xfail *-*-* } } */ } Index: testsuite/gcc.dg/fold-compare-8.c =================================================================== --- testsuite/gcc.dg/fold-compare-8.c (revision 213075) +++ testsuite/gcc.dg/fold-compare-8.c (working copy) @@ -7,5 +7,5 @@ foo (int x, int y) return x - y < 0; } -/* { dg-final { scan-tree-dump "x < y" "original" } } */ +/* { dg-final { scan-tree-dump "x < y" "original" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "original" } } */ Index: testsuite/gcc.dg/fold-abs-5.c =================================================================== --- testsuite/gcc.dg/fold-abs-5.c (revision 0) +++ testsuite/gcc.dg/fold-abs-5.c (revision 0) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-original" } */ + +int test (int a, int b, int sum) +{ + sum += ((a - b) > 0 ? (a - b) : -(a - b)); + return sum; +} + +/* { dg-final { scan-tree-dump "ABS" "original" } } */ +/* { dg-final { cleanup-tree-dump "original" } } */