Kenneth Zadeck <zad...@naturalbridge.com> writes: > + /* 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) > { > - /* 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); > + /* 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); > + } > } > - /* Otherwise we can use the constant as-is when not extending. */ > - return wi::storage_ref (val, len, precision); > + > + unsigned int xprecision = get_precision (x); > + len = wi::force_to_size (scratch, val, len, xprecision, precision, > UNSIGNED); > + return wi::storage_ref (scratch, len, precision); > } > > - /* Widen the constant according to its sign. */ > - len = wi::force_to_size (scratch, val, len, xprecision, precision, > - TYPE_SIGN (TREE_TYPE (x))); > - return wi::storage_ref (scratch, len, precision); > + /* Signed and the rest of the unsigned cases are easy. */ > + return wi::storage_ref (val, len, precision);
AFAICT, no unsigned cases fall through to the "rest of the unsigned cases" statement. Changing the representation of unsigned constants is only worthwhile if we can avoid the force_to_size for some unsigned cases. I think we can avoid it for precision >= xprecision && !small_prec. Either we should take the hit of doing that comparison (but see below) or the change isn't worthwhile. I was thinking that we should always be able to use the constant as-is for max_wide_int-based and addr_wide_int-based operations. The small_prec case will get optimised away (because precision is a compile-time constant) and the force_to_size shouldn't be necessary (because "max" and "addr" should always be wide enough). Could we assert for precision >= xprecision instead of the force_to_size? Or are there cases in which we implicitly truncate tree constants for (variable-precision) wide_int-based operations? Thanks, Richard