aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2014-05-28 12:44:11 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2014-05-28 12:44:11 +0000
commitb017a17489a1e89510a224a3796275ec5cac97c4 (patch)
tree1be500648cca150639fee9e44beec23154844c0d /gcc
parenta4d6bf7e9fb614acec6d0df6932b60a88c13007c (diff)
downloadgcc-b017a17489a1e89510a224a3796275ec5cac97c4.zip
gcc-b017a17489a1e89510a224a3796275ec5cac97c4.tar.gz
gcc-b017a17489a1e89510a224a3796275ec5cac97c4.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/fold-const.c25
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr61045.c12
4 files changed, 38 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2fed7e8..76d4a66 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index b300934..0451b6a 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 ad6490a..ab46413 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/pr61045.c b/gcc/testsuite/gcc.dg/pr61045.c
new file mode 100644
index 0000000..1808cdc
--- /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;
+}