[Bug middle-end/68067] [4.9/5/6 Regression] Wrong constant folding
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Oct 26 12:19:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68067
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok, so we transform a - (b - c) to (c - b) + a, that's invalid of course. This
also started with GCC 4.3.0.
negate_expr_p has
case MINUS_EXPR:
/* 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))
&& reorder_operands_p (TREE_OPERAND (t, 0),
TREE_OPERAND (t, 1));
and fold_binary:
/* A - B -> A + (-B) if B is easily negatable. */
if (negate_expr_p (arg1)
&& !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))))
|| 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)));
we can see "!TYPE_OVERFLOW_SANITIZED" here, a clear sign that sth is wrong.
I think the PLUS_EXPR case of negate_expr_p has the same issue
A + B negated as -B - A or -A - B as as if A == INT_MIN and B == 0 we
again get -0 - INT_MIN instead of INT_MIN + 0.
Testcase:
int main(void)
{
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;
}
More information about the Gcc-bugs
mailing list