aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-10-28 10:01:23 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-10-28 10:01:23 +0000
commit254b22cc79c594756343f645cbcf7163e39cf5b4 (patch)
tree7ab6a96e8d54ebc23cadb2b7c7cab37e3c07e38a /gcc
parentaf7ff91b2425e201c00333f0343fd7e28297d8dc (diff)
downloadgcc-254b22cc79c594756343f645cbcf7163e39cf5b4.zip
gcc-254b22cc79c594756343f645cbcf7163e39cf5b4.tar.gz
gcc-254b22cc79c594756343f645cbcf7163e39cf5b4.tar.bz2
re PR middle-end/68067 (Wrong constant folding)
2015-10-28 Richard Biener <rguenther@suse.de> PR middle-end/68067 * fold-const.c (negate_expr_p): We cannot negate plus or minus if overflow is not wrapping. Likewise multiplication unless one operand is constant and not power of two. (fold_negate_expr): Adjust accordingly. * gcc.dg/torture/pr68067-1.c: New testcase. * gcc.dg/torture/pr68067-2.c: Likewise. From-SVN: r229479
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/fold-const.c19
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr68067-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr68067-2.c13
5 files changed, 55 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 463e601..af9963f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2015-10-28 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/68067
+ * fold-const.c (negate_expr_p): We cannot negate plus or minus
+ if overflow is not wrapping. Likewise multiplication unless
+ one operand is constant and not power of two.
+ (fold_negate_expr): Adjust accordingly.
+
2015-10-27 Nathan Sidwell <nathan@codesourcery.com>
* omp-low.c (struct omp_context): Remove gwv_below, gwv_this
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index e8ff1de..61801cb 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -443,7 +443,9 @@ negate_expr_p (tree t)
case PLUS_EXPR:
if (HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
- || HONOR_SIGNED_ZEROS (element_mode (type)))
+ || HONOR_SIGNED_ZEROS (element_mode (type))
+ || (INTEGRAL_TYPE_P (type)
+ && ! TYPE_OVERFLOW_WRAPS (type)))
return false;
/* -(A + B) -> (-B) - A. */
if (negate_expr_p (TREE_OPERAND (t, 1))
@@ -457,12 +459,23 @@ negate_expr_p (tree t)
/* We can't turn -(A-B) into B-A when we honor signed zeros. */
return !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
&& !HONOR_SIGNED_ZEROS (element_mode (type))
+ && (! INTEGRAL_TYPE_P (type)
+ || TYPE_OVERFLOW_WRAPS (type))
&& reorder_operands_p (TREE_OPERAND (t, 0),
TREE_OPERAND (t, 1));
case MULT_EXPR:
- if (TYPE_UNSIGNED (TREE_TYPE (t)))
- break;
+ if (TYPE_UNSIGNED (type))
+ break;
+ /* INT_MIN/n * n doesn't overflow while negating one operand it does
+ if n is a power of two. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (t))
+ && ! TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
+ && ! ((TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
+ && ! integer_pow2p (TREE_OPERAND (t, 0)))
+ || (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
+ && ! integer_pow2p (TREE_OPERAND (t, 1)))))
+ break;
/* Fall through. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5963330..9d7a47c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-10-28 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/68067
+ * gcc.dg/torture/pr68067-1.c: New testcase.
+ * gcc.dg/torture/pr68067-2.c: Likewise.
+
2015-10-28 Segher Boessenkool <segher@kernel.crashing.org>
* gcc.target/powerpc/p8vector-builtin-8.c: Add "target int128".
diff --git a/gcc/testsuite/gcc.dg/torture/pr68067-1.c b/gcc/testsuite/gcc.dg/torture/pr68067-1.c
new file mode 100644
index 0000000..a7b6aa0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr68067-1.c
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+int main()
+{
+ int a = -1;
+ static int b = -2147483647 - 1;
+ static int c = 0;
+ int t = a - (b - c);
+ if (t != 2147483647)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr68067-2.c b/gcc/testsuite/gcc.dg/torture/pr68067-2.c
new file mode 100644
index 0000000..38a459b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr68067-2.c
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+
+int main()
+{
+ int a = -1;
+ static int b = -2147483647 - 1;
+ static int c = 0;
+ int t = a - (b + c*-2);
+ if (t != 2147483647)
+ __builtin_abort();
+ return 0;
+}
+