From 254b22cc79c594756343f645cbcf7163e39cf5b4 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 28 Oct 2015 10:01:23 +0000 Subject: [PATCH] re PR middle-end/68067 (Wrong constant folding) 2015-10-28 Richard Biener 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 --- gcc/ChangeLog | 8 ++++++++ gcc/fold-const.c | 19 ++++++++++++++++--- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/torture/pr68067-1.c | 12 ++++++++++++ gcc/testsuite/gcc.dg/torture/pr68067-2.c | 13 +++++++++++++ 5 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr68067-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr68067-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 463e6012d00..af9963f9688 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-10-28 Richard Biener + + 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 * omp-low.c (struct omp_context): Remove gwv_below, gwv_this diff --git a/gcc/fold-const.c b/gcc/fold-const.c index e8ff1de13b6..61801cbefee 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 59633302423..9d7a47c6b3b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-10-28 Richard Biener + + PR middle-end/68067 + * gcc.dg/torture/pr68067-1.c: New testcase. + * gcc.dg/torture/pr68067-2.c: Likewise. + 2015-10-28 Segher Boessenkool * 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 00000000000..a7b6aa041d9 --- /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 00000000000..38a459bf7f1 --- /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; +} + -- 2.30.2