Jakub Jelinek <ja...@redhat.com> writes: > @@ -2036,11 +2075,20 @@ wi::lrshift_large (HOST_WIDE_INT *val, c > unsigned int xlen, unsigned int xprecision, > unsigned int precision, unsigned int shift) > { > - unsigned int len = rshift_large_common (val, xval, xlen, xprecision, > shift); > + /* Work out how many blocks are needed to store the significant bits > + (excluding the upper zeros or signs). */ > + unsigned int blocks_needed = BLOCKS_NEEDED (xprecision - shift); > + unsigned int len = blocks_needed; > + if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS) > + && len > xlen > + && xval[xlen - 1] >= 0) > + len = xlen;
I think here too it would be worth dropping the: UNLIKELY (len > WIDE_INT_MAX_INL_ELTS) part of the condition, since presumably the change should be safe regardless of that. > + > + rshift_large_common (val, xval, xlen, shift, len); > > /* The value we just created has precision XPRECISION - SHIFT. > Zero-extend it to wider precisions. */ > - if (precision > xprecision - shift) > + if (precision > xprecision - shift && len == blocks_needed) > { > unsigned int small_prec = (xprecision - shift) % > HOST_BITS_PER_WIDE_INT; > if (small_prec) > @@ -2063,11 +2111,18 @@ wi::arshift_large (HOST_WIDE_INT *val, c > unsigned int xlen, unsigned int xprecision, > unsigned int precision, unsigned int shift) > { > - unsigned int len = rshift_large_common (val, xval, xlen, xprecision, > shift); > + /* Work out how many blocks are needed to store the significant bits > + (excluding the upper zeros or signs). */ > + unsigned int blocks_needed = BLOCKS_NEEDED (xprecision - shift); > + unsigned int len = blocks_needed; > + if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS) && len > xlen) > + len = xlen; > + Same here. OK for thw wide-int parts with those changes. Thanks, Richard