From: Richard Biener Date: Wed, 28 May 2014 12:44:11 +0000 (+0000) Subject: re PR middle-end/61045 (Wrong constant folding) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b017a17489a1e89510a224a3796275ec5cac97c4;p=gcc.git re PR middle-end/61045 (Wrong constant folding) 2014-05-28 Richard Biener PR middle-end/61045 * fold-const.c (fold_comparison): When folding X +- C1 CMP Y +- C2 to X CMP Y +- C2 +- C1 also ensure the sign of the remaining constant operand stays the same. * gcc.dg/pr61045.c: New testcase. From-SVN: r211018 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2fed7e80fec..76d4a66f322 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-05-28 Richard Biener + + PR middle-end/61045 + * fold-const.c (fold_comparison): When folding + X +- C1 CMP Y +- C2 to X CMP Y +- C2 +- C1 also ensure + the sign of the remaining constant operand stays the same. + 2014-05-28 Kaushik Phatak * config/rl78/rl78.h (TARGET_CPU_CPP_BUILTINS): Define diff --git a/gcc/fold-const.c b/gcc/fold-const.c index b3009340e3e..0451b6a90be 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -9239,7 +9239,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type, /* 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. */ + original one and has the same sign. */ if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0)) && (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST @@ -9258,32 +9258,35 @@ fold_comparison (location_t loc, enum tree_code code, tree type, "a comparison"); /* Put the constant on the side where it doesn't overflow and is - of lower absolute value than before. */ + of lower absolute value and of same sign than before. */ cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1) ? MINUS_EXPR : PLUS_EXPR, const2, const1); if (!TREE_OVERFLOW (cst) - && tree_int_cst_compare (const2, cst) == tree_int_cst_sgn (const2)) + && tree_int_cst_compare (const2, cst) == tree_int_cst_sgn (const2) + && tree_int_cst_sgn (cst) == tree_int_cst_sgn (const2)) { fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_COMPARISON); return fold_build2_loc (loc, code, type, - variable1, - fold_build2_loc (loc, - TREE_CODE (arg1), TREE_TYPE (arg1), - variable2, cst)); + variable1, + fold_build2_loc (loc, TREE_CODE (arg1), + TREE_TYPE (arg1), + variable2, cst)); } cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1) ? MINUS_EXPR : PLUS_EXPR, const1, const2); if (!TREE_OVERFLOW (cst) - && tree_int_cst_compare (const1, cst) == tree_int_cst_sgn (const1)) + && tree_int_cst_compare (const1, cst) == tree_int_cst_sgn (const1) + && tree_int_cst_sgn (cst) == tree_int_cst_sgn (const1)) { fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_COMPARISON); return fold_build2_loc (loc, code, type, - fold_build2_loc (loc, TREE_CODE (arg0), TREE_TYPE (arg0), - variable1, cst), - variable2); + fold_build2_loc (loc, TREE_CODE (arg0), + TREE_TYPE (arg0), + variable1, cst), + variable2); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ad6490ab48f..ab4641343a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-05-28 Richard Biener + + PR middle-end/61045 + * gcc.dg/pr61045.c: New testcase. + 2014-05-28 Rainer Orth * lib/clearcap.exp: New file. diff --git a/gcc/testsuite/gcc.dg/pr61045.c b/gcc/testsuite/gcc.dg/pr61045.c new file mode 100644 index 00000000000..1808cdc259f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr61045.c @@ -0,0 +1,12 @@ +/* { dg-do run } */ +/* { dg-options "-fstrict-overflow" } */ + +int main () +{ + int a = 0; + int b = __INT_MAX__; + int t = (a - 2) > (b - 1); + if (t != 0) + __builtin_abort(); + return 0; +}