[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