https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70333

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
Starts to go downhill here:

      /* If these are the same operation types, we can associate them
         assuming no overflow.  */
      if (tcode == code)
        {
          bool overflow_p = false;
          bool overflow_mul_p;
          signop sign = TYPE_SIGN (ctype);
          wide_int mul = wi::mul (op1, c, sign, &overflow_mul_p);
          overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1);
          if (overflow_mul_p
              && ((sign == UNSIGNED && tcode != MULT_EXPR) || sign == SIGNED))
            overflow_p = true;
          if (!overflow_p)
            {
              mul = wide_int::from (mul, TYPE_PRECISION (ctype),
                                    TYPE_SIGN (TREE_TYPE (op1)));
              return fold_build2 (tcode, ctype, fold_convert (ctype, op0),
                                  wide_int_to_tree (ctype, mul));

which generates a too large constant.  op1 == 13, c == 536870912, the
multiplication result is sign-extended to unsigned long here (from int).

Note that "associate them assuming no overflow" sounds wrong here as the
operation does overflow int and this is what makes the result bogus.
We compute the multiplication in unsigned but then still sign-extend.

Sth. is fishy here.

Reply via email to