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>
* config/nvptx/nvptx.c (walk_args_for_params): Delete.
......@@ -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
......
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>
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