From 7dd663f547b9b69755ba9b3bcadcc96f82e830e4 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 25 Nov 2015 14:21:25 +0000 Subject: [PATCH] re PR middle-end/68528 ([5 Only] Wrong constant folding) 2015-11-25 Richard Biener PR middle-end/68528 * fold-const.c (fold_binary_loc): Do not call negate_expr_p on stripped operands. * gcc.dg/torture/pr68528.c: New testcase. From-SVN: r230870 --- gcc/ChangeLog | 6 +++ gcc/fold-const.c | 55 ++++++++++++-------------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/torture/pr68528.c | 17 ++++++++ 4 files changed, 53 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr68528.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b0c09fb4811..d6b749be7fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-11-25 Richard Biener + + PR middle-end/68528 + * fold-const.c (fold_binary_loc): Do not call negate_expr_p + on stripped operands. + 2015-11-25 Nathan Sidwell * config/nvptx/nvptx.c (walk_args_for_params): Delete. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 698062ee814..16bff5f07be 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -9681,13 +9681,12 @@ fold_binary_loc (location_t loc, case MINUS_EXPR: /* (-A) - B -> (-B) - A where B is easily negated and we can swap. */ if (TREE_CODE (arg0) == NEGATE_EXPR - && negate_expr_p (arg1) + && negate_expr_p (op1) && reorder_operands_p (arg0, arg1)) return fold_build2_loc (loc, MINUS_EXPR, type, - fold_convert_loc (loc, type, - negate_expr (arg1)), - fold_convert_loc (loc, type, - TREE_OPERAND (arg0, 0))); + negate_expr (op1), + fold_convert_loc (loc, type, + TREE_OPERAND (arg0, 0))); /* Fold __complex__ ( x, 0 ) - __complex__ ( 0, y ) to __complex__ ( x, -y ). This is not the same for SNaNs or if @@ -9727,17 +9726,16 @@ fold_binary_loc (location_t loc, } /* A - B -> A + (-B) if B is easily negatable. */ - if (negate_expr_p (arg1) - && !TYPE_OVERFLOW_SANITIZED (type) + if (negate_expr_p (op1) + && ! TYPE_OVERFLOW_SANITIZED (type) && ((FLOAT_TYPE_P (type) /* Avoid this transformation if B is a positive REAL_CST. */ - && (TREE_CODE (arg1) != REAL_CST - || REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1)))) + && (TREE_CODE (op1) != REAL_CST + || REAL_VALUE_NEGATIVE (TREE_REAL_CST (op1)))) || INTEGRAL_TYPE_P (type))) return fold_build2_loc (loc, PLUS_EXPR, type, - fold_convert_loc (loc, type, arg0), - fold_convert_loc (loc, type, - negate_expr (arg1))); + fold_convert_loc (loc, type, arg0), + negate_expr (op1)); /* Fold &a[i] - &a[j] to i-j. */ if (TREE_CODE (arg0) == ADDR_EXPR @@ -9781,15 +9779,14 @@ fold_binary_loc (location_t loc, if (! FLOAT_TYPE_P (type)) { /* Transform x * -C into -x * C if x is easily negatable. */ - if (TREE_CODE (arg1) == INTEGER_CST - && tree_int_cst_sgn (arg1) == -1 - && negate_expr_p (arg0) - && (tem = negate_expr (arg1)) != arg1 - && !TREE_OVERFLOW (tem)) + if (TREE_CODE (op1) == INTEGER_CST + && tree_int_cst_sgn (op1) == -1 + && negate_expr_p (op0) + && (tem = negate_expr (op1)) != op1 + && ! TREE_OVERFLOW (tem)) return fold_build2_loc (loc, MULT_EXPR, type, - fold_convert_loc (loc, type, - negate_expr (arg0)), - tem); + fold_convert_loc (loc, type, + negate_expr (op0)), tem); /* (A + A) * C -> A * 2 * C */ if (TREE_CODE (arg0) == PLUS_EXPR @@ -10259,7 +10256,7 @@ fold_binary_loc (location_t loc, undefined. */ if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type)) && TREE_CODE (arg0) == NEGATE_EXPR - && negate_expr_p (arg1)) + && negate_expr_p (op1)) { if (INTEGRAL_TYPE_P (type)) fold_overflow_warning (("assuming signed overflow does not occur " @@ -10267,14 +10264,13 @@ fold_binary_loc (location_t loc, "division"), WARN_STRICT_OVERFLOW_MISC); return fold_build2_loc (loc, code, type, - fold_convert_loc (loc, type, - TREE_OPERAND (arg0, 0)), - fold_convert_loc (loc, type, - negate_expr (arg1))); + fold_convert_loc (loc, type, + TREE_OPERAND (arg0, 0)), + negate_expr (op1)); } if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type)) && TREE_CODE (arg1) == NEGATE_EXPR - && negate_expr_p (arg0)) + && negate_expr_p (op0)) { if (INTEGRAL_TYPE_P (type)) fold_overflow_warning (("assuming signed overflow does not occur " @@ -10282,10 +10278,9 @@ fold_binary_loc (location_t loc, "division"), WARN_STRICT_OVERFLOW_MISC); return fold_build2_loc (loc, code, type, - fold_convert_loc (loc, type, - negate_expr (arg0)), - fold_convert_loc (loc, type, - TREE_OPERAND (arg1, 0))); + negate_expr (op0), + fold_convert_loc (loc, type, + TREE_OPERAND (arg1, 0))); } /* If arg0 is a multiple of arg1, then rewrite to the fastest div diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 789058a6f73..47ed2acef54 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-11-25 Richard Biener + + PR middle-end/68528 + * gcc.dg/torture/pr68528.c: New testcase. + 2015-11-25 Paolo Carlini PR c++/58910 diff --git a/gcc/testsuite/gcc.dg/torture/pr68528.c b/gcc/testsuite/gcc.dg/torture/pr68528.c new file mode 100644 index 00000000000..d69d600f43b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr68528.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ + +#define INT_MIN ( -__INT_MAX__ - 1 ) + +extern void abort (void); + +int main (void) +{ + int x0 = INT_MIN; + long x1 = 0L; + int x2 = 0; + int t = ( 0 || ( INT_MIN - (int) ( x0 - x1 ) ) ); + + if ( t != 0 ) { x2 = t; abort(); } + + return 0; +} -- 2.30.2