Thanks for doing this. Kenneth Zadeck <zad...@naturalbridge.com> writes: > @@ -1204,11 +1204,11 @@ wide_int_to_tree (tree type, const wide_ > } > > wide_int cst = wide_int::from (pcst, prec, sgn); > - int len = int (cst.get_len ()); > - int small_prec = prec & (HOST_BITS_PER_WIDE_INT - 1); > + unsigned int len = int (cst.get_len ());
The cast to int is redundant now (get_len () is unsigned int). > @@ -5172,39 +5173,48 @@ wi::int_traits <const_tree>::get_precisi > return TYPE_PRECISION (TREE_TYPE (tcst)); > } > > -/* Convert the tree_cst X into a wide_int. */ > +/* Convert the tree_cst X into a wide_int of PRECISION. */ > inline wi::storage_ref > wi::int_traits <const_tree>::decompose (HOST_WIDE_INT *scratch, > unsigned int precision, const_tree x) > { > - unsigned int xprecision = get_precision (x); > unsigned int len = TREE_INT_CST_NUNITS (x); > const HOST_WIDE_INT *val = (const HOST_WIDE_INT *) &TREE_INT_CST_ELT (x, > 0); > unsigned int max_len = ((precision + HOST_BITS_PER_WIDE_INT - 1) > / HOST_BITS_PER_WIDE_INT); > - /* Truncate the constant if necessary. */ > - if (len > max_len) > - return wi::storage_ref (val, max_len, precision); > + unsigned int xprecision = get_precision (x); > + > + gcc_assert (precision >= xprecision); > > - if (precision <= xprecision) > + /* Got to be careful of precision 0 values. */ > + if (precision) > + len = MIN (len, max_len); > + if (TYPE_SIGN (TREE_TYPE (x)) == UNSIGNED) > { > - if (precision < HOST_BITS_PER_WIDE_INT > - && TYPE_SIGN (TREE_TYPE (x)) == UNSIGNED) > + unsigned int small_prec = precision & (HOST_BITS_PER_WIDE_INT - 1); > + if (small_prec) > + { > + /* We have to futz with this because the canonization for > + short unsigned numbers in wide-int is different from the > + canonized short unsigned numbers in the tree-cst. */ > + if (len == max_len) > + { > + for (unsigned int i = 0; i < len - 1; i++) > + scratch[i] = val[i]; > + scratch[len - 1] = sext_hwi (val[len - 1], precision); > + return wi::storage_ref (scratch, len, precision); > + } > + } > + > + if (precision < xprecision + HOST_BITS_PER_WIDE_INT) > { > - /* The rep of wide-int is signed, so if the value comes from > - an unsigned int_cst, we have to sign extend it to make it > - correct. */ > - scratch[0] = sext_hwi (val[0], precision); > - return wi::storage_ref (scratch, 1, precision); > + len = wi::force_to_size (scratch, val, len, xprecision, precision, > UNSIGNED); > + return wi::storage_ref (scratch, len, precision); > } AFAICT, with the assert, this last case is only needed when !small_prec && precision == xprecision, and the only situation it handles is where the top bit is set. Is that right? If so, we can use the original val as-is and just trim the length. I.e. if (small_prec) ; else if (precision == xprecision) while (len >= 0 && val[len - 1] == -1) len--; Sorry if I've got that wrong -- it's taking a while to page the wide-int stuff back in. Thanks, Richard