https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70450
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- Ok, so signop sign = TYPE_SIGN (ctype); unsigned prec = TYPE_PRECISION (ctype); wide_int mul = wi::mul (wide_int::from (op1, prec, sign), wide_int::from (c, prec, sign), sign, &overflow_mul_p); doesn't sign-extend the int -2 op1. It's representation _is_ sign-extended though. Looks like 1066 wide_int_storage::from (const wide_int_ref &x, unsigned int precision, 1067 signop sgn) 1068 { 1069 wide_int result = wide_int::create (precision); 1070 result.set_len (wi::force_to_size (result.write_val (), x.val, x.len, 1071 x.precision, precision, sgn)); 1072 return result; 1073 } called with sng == UNSIGNED, precision == 64 and x.precision being 32 assumes it has to zero-extend from x.precision. Ah, that's what ::from is documented to do.