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.