From: rguenth Date: Wed, 25 Nov 2015 14:21:25 +0000 (+0000) Subject: 2015-11-25 Richard Biener X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=783ad65314f279a3868db8969ca3ec703898ef68;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@230870 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b0c09fb48116..d6b749be7fad 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 698062ee814c..16bff5f07be9 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 789058a6f73d..47ed2acef545 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 000000000000..d69d600f43bd --- /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; +}