[Bug tree-optimization/83269] [8 Regression] Wrong constant folding
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Dec 14 16:29:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83269
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
With -sanitize=signed-integer-overflow, we get in *.original:
volatile unsigned char a = 1;
long long int b = 2147483648;
int c = (int) a * -2147483647 - (int) -b;
instead of what we get without it:
volatile unsigned char a = 1;
long long int b = 2147483648;
int c = (int) b + (int) a * -2147483647;
and the testcase works in the former case, while fails with the latter.
I see fold_binary_loc called with MINUS_EXPR on
op0: (int) -(unsigned int) b
op1: (int) a * -2147483647
and it returns
(int) a * 2147483647 - (int) b
which looks wrong if (int) b is INT_MIN.
I believe it is the:
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR
&& negate_expr_p (op1))
return fold_build2_loc (loc, MINUS_EXPR, type,
negate_expr (op1),
fold_convert_loc (loc, type,
TREE_OPERAND (arg0, 0)));
case in fold-const.c, supposedly we should either punt it
TYPE_OVERFLOW_UNDEFINED (type) && !TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0)),
or do it in that case in unsigned type instead?
More information about the Gcc-bugs
mailing list