On Thu, Dec 17, 2015 at 12:33:22PM +0100, Richard Biener wrote: > > @@ -1245,11 +1245,9 @@ static unsigned int > > get_int_cst_ext_nunits (tree type, const wide_int &cst) > > { > > gcc_checking_assert (cst.get_precision () == TYPE_PRECISION (type)); > > - /* We need an extra zero HWI if CST is an unsigned integer with its > > - upper bit set, and if CST occupies a whole number of HWIs. */ > > - if (TYPE_UNSIGNED (type) > > - && wi::neg_p (cst) > > - && (cst.get_precision () % HOST_BITS_PER_WIDE_INT) == 0) > > + /* We need extra HWIs if CST is an unsigned integer with its > > + upper bit set. */ > > + if (TYPE_UNSIGNED (type) && wi::neg_p (cst)) > > return cst.get_precision () / HOST_BITS_PER_WIDE_INT + 1; > > return cst.get_len (); > > } > > I don't see why this is necessary - if there are enough bits to > always have a zero MSB for unsigned types then we don't need an > extra element.
But there aren't enough bits in that case. Let's consider how is -2 casted to unsigned type with precision 64, 65, 127, 128 and 129 is encoded. cst.get_len () is in each case 1, the first element is -2. So, what get_int_cst_ext_nunits before my change does is that for precision 64 and 128 return 2 and 3, for all other precisions (talking just about < 129) returns 1. So, before my patch we have: precision TREE_INT_CST_NUNITS TREE_INT_CST_EXT_NUNITS TREE_INT_CST_ELT 64 1 2 -2, 0 65 1 1 -2 127 1 1 -2 128 1 3 -2, -1, 0 129 1 1 -2 and with the patch we have: 64 1 2 -2, 0 65 1 2 -2, 1 127 1 2 -2, -1ULL / 2 128 1 3 -2, -1, 0 129 1 3 -2, -1, 1 Thus, before the patch there was nothing that in the ext units would tell the users the value is actually large unsigned one rather than negative. I really don't see what is so special on precisions divisible by HOST_BITS_PER_WIDE_INT. The > TREE_INT_CST_NUNITS elements aren't guaranteed to be all 0s anyway, they are all -1s and for the precisions divisible by HOST_BITS_PER_WIDE_INT the last one is 0. That is what is special on those, with my patch for the other precisions the last one is simply always some power of two - 1 (other than -1). Now, if the value is not in between maximum and maximum - 0x8000000000000000ULL TREE_INT_CST_NUNITS will not be 1, but say 2 or more, and perhaps again the len is still smaller than precision / HOST_BITS_PER_WIDE_INT + 1, but if it is again negative, we want to have some way to add the ext elements (a series of -1, followed by 0 or other power of two - 1 other than -1). > > > @@ -1266,7 +1264,8 @@ build_new_int_cst (tree type, const wide > > if (len < ext_len) > > { > > --ext_len; > > - TREE_INT_CST_ELT (nt, ext_len) = 0; > > + TREE_INT_CST_ELT (nt, ext_len) > > + = zext_hwi (-1, cst.get_precision () % HOST_BITS_PER_WIDE_INT); > > isn't this enough? No. This is the len < ext_len case, without the first hunk if len < ext_len then cst.get_precision () % HOST_BITS_PER_WIDE_INT is guaranteed to be 0, and thus zext_hwi will return 0. Jakub