mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-20 17:40:46 +08:00
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
This commit is contained in:
parent
a4d6bf7e9f
commit
b017a17489
gcc
@ -1,3 +1,10 @@
|
||||
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>
|
||||
|
||||
* config/rl78/rl78.h (TARGET_CPU_CPP_BUILTINS): Define
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
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>
|
||||
|
||||
* lib/clearcap.exp: New file.
|
||||
|
12
gcc/testsuite/gcc.dg/pr61045.c
Normal file
12
gcc/testsuite/gcc.dg/pr61045.c
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user