Commit 7dd663f5 by Richard Biener Committed by Richard Biener

re PR middle-end/68528 ([5 Only] Wrong constant folding)

2015-11-25  Richard Biener  <rguenther@suse.de>

	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
parent 5ab662d5
2015-11-25 Richard Biener <rguenther@suse.de>
PR middle-end/68528
* fold-const.c (fold_binary_loc): Do not call negate_expr_p
on stripped operands.
2015-11-25 Nathan Sidwell <nathan@acm.org> 2015-11-25 Nathan Sidwell <nathan@acm.org>
* config/nvptx/nvptx.c (walk_args_for_params): Delete. * config/nvptx/nvptx.c (walk_args_for_params): Delete.
...@@ -9681,13 +9681,12 @@ fold_binary_loc (location_t loc, ...@@ -9681,13 +9681,12 @@ fold_binary_loc (location_t loc,
case MINUS_EXPR: case MINUS_EXPR:
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */ /* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR if (TREE_CODE (arg0) == NEGATE_EXPR
&& negate_expr_p (arg1) && negate_expr_p (op1)
&& reorder_operands_p (arg0, arg1)) && reorder_operands_p (arg0, arg1))
return fold_build2_loc (loc, MINUS_EXPR, type, return fold_build2_loc (loc, MINUS_EXPR, type,
fold_convert_loc (loc, type, negate_expr (op1),
negate_expr (arg1)), fold_convert_loc (loc, type,
fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)));
TREE_OPERAND (arg0, 0)));
/* Fold __complex__ ( x, 0 ) - __complex__ ( 0, y ) to /* Fold __complex__ ( x, 0 ) - __complex__ ( 0, y ) to
__complex__ ( x, -y ). This is not the same for SNaNs or if __complex__ ( x, -y ). This is not the same for SNaNs or if
...@@ -9727,17 +9726,16 @@ fold_binary_loc (location_t loc, ...@@ -9727,17 +9726,16 @@ fold_binary_loc (location_t loc,
} }
/* A - B -> A + (-B) if B is easily negatable. */ /* A - B -> A + (-B) if B is easily negatable. */
if (negate_expr_p (arg1) if (negate_expr_p (op1)
&& !TYPE_OVERFLOW_SANITIZED (type) && ! TYPE_OVERFLOW_SANITIZED (type)
&& ((FLOAT_TYPE_P (type) && ((FLOAT_TYPE_P (type)
/* Avoid this transformation if B is a positive REAL_CST. */ /* Avoid this transformation if B is a positive REAL_CST. */
&& (TREE_CODE (arg1) != REAL_CST && (TREE_CODE (op1) != REAL_CST
|| REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1)))) || REAL_VALUE_NEGATIVE (TREE_REAL_CST (op1))))
|| INTEGRAL_TYPE_P (type))) || INTEGRAL_TYPE_P (type)))
return fold_build2_loc (loc, PLUS_EXPR, type, return fold_build2_loc (loc, PLUS_EXPR, type,
fold_convert_loc (loc, type, arg0), fold_convert_loc (loc, type, arg0),
fold_convert_loc (loc, type, negate_expr (op1));
negate_expr (arg1)));
/* Fold &a[i] - &a[j] to i-j. */ /* Fold &a[i] - &a[j] to i-j. */
if (TREE_CODE (arg0) == ADDR_EXPR if (TREE_CODE (arg0) == ADDR_EXPR
...@@ -9781,15 +9779,14 @@ fold_binary_loc (location_t loc, ...@@ -9781,15 +9779,14 @@ fold_binary_loc (location_t loc,
if (! FLOAT_TYPE_P (type)) if (! FLOAT_TYPE_P (type))
{ {
/* Transform x * -C into -x * C if x is easily negatable. */ /* Transform x * -C into -x * C if x is easily negatable. */
if (TREE_CODE (arg1) == INTEGER_CST if (TREE_CODE (op1) == INTEGER_CST
&& tree_int_cst_sgn (arg1) == -1 && tree_int_cst_sgn (op1) == -1
&& negate_expr_p (arg0) && negate_expr_p (op0)
&& (tem = negate_expr (arg1)) != arg1 && (tem = negate_expr (op1)) != op1
&& !TREE_OVERFLOW (tem)) && ! TREE_OVERFLOW (tem))
return fold_build2_loc (loc, MULT_EXPR, type, return fold_build2_loc (loc, MULT_EXPR, type,
fold_convert_loc (loc, type, fold_convert_loc (loc, type,
negate_expr (arg0)), negate_expr (op0)), tem);
tem);
/* (A + A) * C -> A * 2 * C */ /* (A + A) * C -> A * 2 * C */
if (TREE_CODE (arg0) == PLUS_EXPR if (TREE_CODE (arg0) == PLUS_EXPR
...@@ -10259,7 +10256,7 @@ fold_binary_loc (location_t loc, ...@@ -10259,7 +10256,7 @@ fold_binary_loc (location_t loc,
undefined. */ undefined. */
if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type)) if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
&& TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg0) == NEGATE_EXPR
&& negate_expr_p (arg1)) && negate_expr_p (op1))
{ {
if (INTEGRAL_TYPE_P (type)) if (INTEGRAL_TYPE_P (type))
fold_overflow_warning (("assuming signed overflow does not occur " fold_overflow_warning (("assuming signed overflow does not occur "
...@@ -10267,14 +10264,13 @@ fold_binary_loc (location_t loc, ...@@ -10267,14 +10264,13 @@ fold_binary_loc (location_t loc,
"division"), "division"),
WARN_STRICT_OVERFLOW_MISC); WARN_STRICT_OVERFLOW_MISC);
return fold_build2_loc (loc, code, type, return fold_build2_loc (loc, code, type,
fold_convert_loc (loc, type, fold_convert_loc (loc, type,
TREE_OPERAND (arg0, 0)), TREE_OPERAND (arg0, 0)),
fold_convert_loc (loc, type, negate_expr (op1));
negate_expr (arg1)));
} }
if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type)) if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
&& TREE_CODE (arg1) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR
&& negate_expr_p (arg0)) && negate_expr_p (op0))
{ {
if (INTEGRAL_TYPE_P (type)) if (INTEGRAL_TYPE_P (type))
fold_overflow_warning (("assuming signed overflow does not occur " fold_overflow_warning (("assuming signed overflow does not occur "
...@@ -10282,10 +10278,9 @@ fold_binary_loc (location_t loc, ...@@ -10282,10 +10278,9 @@ fold_binary_loc (location_t loc,
"division"), "division"),
WARN_STRICT_OVERFLOW_MISC); WARN_STRICT_OVERFLOW_MISC);
return fold_build2_loc (loc, code, type, return fold_build2_loc (loc, code, type,
fold_convert_loc (loc, type, negate_expr (op0),
negate_expr (arg0)), fold_convert_loc (loc, type,
fold_convert_loc (loc, type, TREE_OPERAND (arg1, 0)));
TREE_OPERAND (arg1, 0)));
} }
/* If arg0 is a multiple of arg1, then rewrite to the fastest div /* If arg0 is a multiple of arg1, then rewrite to the fastest div
......
2015-11-25 Richard Biener <rguenther@suse.de>
PR middle-end/68528
* gcc.dg/torture/pr68528.c: New testcase.
2015-11-25 Paolo Carlini <paolo.carlini@oracle.com> 2015-11-25 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58910 PR c++/58910
......
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment