Commit b017a174 by Richard Biener Committed by Richard Biener

re PR middle-end/61045 (Wrong constant folding)

2014-05-28  Richard Biener  <rguenther@suse.de>

	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
parent a4d6bf7e
2014-05-28 Richard Biener <rguenther@suse.de>
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 <kaushik.phatak@kpit.com> 2014-05-28 Kaushik Phatak <kaushik.phatak@kpit.com>
* config/rl78/rl78.h (TARGET_CPU_CPP_BUILTINS): Define * config/rl78/rl78.h (TARGET_CPU_CPP_BUILTINS): Define
......
...@@ -9239,7 +9239,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type, ...@@ -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 /* Transform comparisons of the form X +- C1 CMP Y +- C2 to
X CMP Y +- C2 +- C1 for signed X, Y. This is valid if X CMP Y +- C2 +- C1 for signed X, Y. This is valid if
the resulting offset is smaller in absolute value than the 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)) if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
&& (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) && (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
&& (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
...@@ -9258,32 +9258,35 @@ fold_comparison (location_t loc, enum tree_code code, tree type, ...@@ -9258,32 +9258,35 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
"a comparison"); "a comparison");
/* Put the constant on the side where it doesn't overflow and is /* 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) cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1)
? MINUS_EXPR : PLUS_EXPR, ? MINUS_EXPR : PLUS_EXPR,
const2, const1); const2, const1);
if (!TREE_OVERFLOW (cst) 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); fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_COMPARISON);
return fold_build2_loc (loc, code, type, return fold_build2_loc (loc, code, type,
variable1, variable1,
fold_build2_loc (loc, fold_build2_loc (loc, TREE_CODE (arg1),
TREE_CODE (arg1), TREE_TYPE (arg1), TREE_TYPE (arg1),
variable2, cst)); variable2, cst));
} }
cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1) cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1)
? MINUS_EXPR : PLUS_EXPR, ? MINUS_EXPR : PLUS_EXPR,
const1, const2); const1, const2);
if (!TREE_OVERFLOW (cst) 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); fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_COMPARISON);
return fold_build2_loc (loc, code, type, return fold_build2_loc (loc, code, type,
fold_build2_loc (loc, TREE_CODE (arg0), TREE_TYPE (arg0), fold_build2_loc (loc, TREE_CODE (arg0),
variable1, cst), TREE_TYPE (arg0),
variable2); variable1, cst),
variable2);
} }
} }
......
2014-05-28 Richard Biener <rguenther@suse.de>
PR middle-end/61045
* gcc.dg/pr61045.c: New testcase.
2014-05-28 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2014-05-28 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* lib/clearcap.exp: New file. * lib/clearcap.exp: New file.
......
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment