Message ID | 525F3984.4080907@naturalbridge.com |
---|---|
State | New |
Headers | show |
Kenneth Zadeck <zadeck@naturalbridge.com> writes: > On 10/15/2013 02:30 PM, Richard Sandiford wrote: >> Richard Sandiford <rdsandiford@googlemail.com> writes: >>> if (small_prec) >>> ; >>> else if (precision == xprecision) >>> while (len >= 0 && val[len - 1] == -1) >>> len--; >> Err, len > 0 obviously. > you were only close. Bah. > patch tested on ppc and committed as revision 203739. Thanks. So that should have got rid of the last use of scratch in tree->addr_wide_int and tree->max_wide_int. Richard
On Wed, 16 Oct 2013, Kenneth Zadeck wrote: > On 10/15/2013 02:30 PM, Richard Sandiford wrote: > > Richard Sandiford <rdsandiford@googlemail.com> writes: > > > if (small_prec) > > > ; > > > else if (precision == xprecision) > > > while (len >= 0 && val[len - 1] == -1) > > > len--; > > Err, len > 0 obviously. > you were only close. patch tested on ppc and committed as revision 203739. > > Index: gcc/tree.c > =================================================================== > --- gcc/tree.c (revision 203701) > +++ gcc/tree.c (working copy) > @@ -1204,7 +1204,7 @@ wide_int_to_tree (tree type, const wide_ > } > > wide_int cst = wide_int::from (pcst, prec, sgn); > - unsigned int len = int (cst.get_len ()); > + unsigned int len = cst.get_len (); > unsigned int small_prec = prec & (HOST_BITS_PER_WIDE_INT - 1); > bool recanonize = sgn == UNSIGNED > && small_prec > Index: gcc/tree.h > =================================================================== > --- gcc/tree.h (revision 203701) > +++ gcc/tree.h (working copy) > @@ -5204,13 +5204,13 @@ wi::int_traits <const_tree>::decompose ( > scratch[len - 1] = sext_hwi (val[len - 1], precision); > return wi::storage_ref (scratch, len, precision); > } > - } > - > - if (precision < xprecision + HOST_BITS_PER_WIDE_INT) > - { > - len = wi::force_to_size (scratch, val, len, xprecision, precision, > UNS > IGNED); > - return wi::storage_ref (scratch, len, precision); > - } > + } > + /* We have to futz here because a large unsigned int with > + precision 128 may look (0x0 0xFFFFFFFFFFFFFFFF 0xF...) as a > + tree-cst and as (0xF...) as a wide-int. */ > + else if (precision == xprecision && len == max_len) > + while (len > 1 && val[len - 1] == (HOST_WIDE_INT)-1) > + len--; > } Err, that now undoes the extra zero word thing? Or was I confused about the previous code and this "append extra zero word for MSB set unsigned constants"? Richard.
Richard Biener <rguenther@suse.de> writes: > On Wed, 16 Oct 2013, Kenneth Zadeck wrote: > >> On 10/15/2013 02:30 PM, Richard Sandiford wrote: >> > Richard Sandiford <rdsandiford@googlemail.com> writes: >> > > if (small_prec) >> > > ; >> > > else if (precision == xprecision) >> > > while (len >= 0 && val[len - 1] == -1) >> > > len--; >> > Err, len > 0 obviously. >> you were only close. patch tested on ppc and committed as revision 203739. >> >> Index: gcc/tree.c >> =================================================================== >> --- gcc/tree.c (revision 203701) >> +++ gcc/tree.c (working copy) >> @@ -1204,7 +1204,7 @@ wide_int_to_tree (tree type, const wide_ >> } >> >> wide_int cst = wide_int::from (pcst, prec, sgn); >> - unsigned int len = int (cst.get_len ()); >> + unsigned int len = cst.get_len (); >> unsigned int small_prec = prec & (HOST_BITS_PER_WIDE_INT - 1); >> bool recanonize = sgn == UNSIGNED >> && small_prec >> Index: gcc/tree.h >> =================================================================== >> --- gcc/tree.h (revision 203701) >> +++ gcc/tree.h (working copy) >> @@ -5204,13 +5204,13 @@ wi::int_traits <const_tree>::decompose ( >> scratch[len - 1] = sext_hwi (val[len - 1], precision); >> return wi::storage_ref (scratch, len, precision); >> } >> - } >> - >> - if (precision < xprecision + HOST_BITS_PER_WIDE_INT) >> - { >> - len = wi::force_to_size (scratch, val, len, xprecision, precision, >> UNS >> IGNED); >> - return wi::storage_ref (scratch, len, precision); >> - } >> + } >> + /* We have to futz here because a large unsigned int with >> + precision 128 may look (0x0 0xFFFFFFFFFFFFFFFF 0xF...) as a >> + tree-cst and as (0xF...) as a wide-int. */ >> + else if (precision == xprecision && len == max_len) >> + while (len > 1 && val[len - 1] == (HOST_WIDE_INT)-1) >> + len--; >> } > > Err, that now undoes the extra zero word thing? Or was I confused > about the previous code and this "append extra zero word for > MSB set unsigned constants"? When the precision == xprecision yes. Please see the discussion from yesterday about this: > >> The fundamental problem here is that we're trying to support two cases: > >> > >> (a) doing N-bit arithemtic in cases where the inputs have N bits > >> (b) doing N-bit arithmetic in cases where the inputs have fewer than N bits > >> and are extended according to TYPE_SIGN. > >> > >> Let's assume 32-bit HWIs. The 16-bit (4-hex-digit) constant 0x8000 is > >> 0x8000 regardless of whether the type is signed or unsigned. But if it's > >> extended to 32-bits you get two different numbers 0xffff8000 and 0x00008000, > >> depending on the sign. > [...] > But extending the precision can change the right value of "len". > Take the same example with 16-bit HWIs. In wide_int terms, and with > the original tree representation, the constant is a single HWI: > > 0x8000 > > with len 1. And in case (a) -- where we're asking for a 16-bit wide_int -- > this single HWI is all we want. The signed and unsigned constants give > the same wide_int. > > But the same constant extended to 32 bits and left "uncompressed" would be > two HWIs: > > 0x0000 0x8000 for unsigned constants > 0xffff 0x8000 for signed constants > > Compressed according to the sign scheme they are: > > 0x0000 0x8000 (len == 2) for unsigned constants > 0x8000 (len == 1) for signed constants > > which is also the new tree representation. > > So the unsigned case is different for (a) and (b). Thanks, Richard
Index: gcc/tree.c =================================================================== --- gcc/tree.c (revision 203701) +++ gcc/tree.c (working copy) @@ -1204,7 +1204,7 @@ wide_int_to_tree (tree type, const wide_ } wide_int cst = wide_int::from (pcst, prec, sgn); - unsigned int len = int (cst.get_len ()); + unsigned int len = cst.get_len (); unsigned int small_prec = prec & (HOST_BITS_PER_WIDE_INT - 1); bool recanonize = sgn == UNSIGNED && small_prec Index: gcc/tree.h =================================================================== --- gcc/tree.h (revision 203701) +++ gcc/tree.h (working copy) @@ -5204,13 +5204,13 @@ wi::int_traits <const_tree>::decompose ( scratch[len - 1] = sext_hwi (val[len - 1], precision); return wi::storage_ref (scratch, len, precision); } - } - - if (precision < xprecision + HOST_BITS_PER_WIDE_INT) - { - len = wi::force_to_size (scratch, val, len, xprecision, precision, UNS IGNED); - return wi::storage_ref (scratch, len, precision); - } + } + /* We have to futz here because a large unsigned int with + precision 128 may look (0x0 0xFFFFFFFFFFFFFFFF 0xF...) as a + tree-cst and as (0xF...) as a wide-int. */ + else if (precision == xprecision && len == max_len) + while (len > 1 && val[len - 1] == (HOST_WIDE_INT)-1) + len--; }