Patchwork wide-int branch updated

login
register
mail settings
Submitter Kenneth Zadeck
Date Aug. 26, 2013, 12:10 p.m.
Message ID <521B45A3.5010201@naturalbridge.com>
Download mbox | patch
Permalink /patch/269872/
State New
Headers show

Comments

Kenneth Zadeck - Aug. 26, 2013, 12:10 p.m.
fixed fits_uhwi_p.

tested on x86-64.

kenny
Richard Sandiford - Aug. 27, 2013, 6:31 p.m.
Kenneth Zadeck <zadeck@naturalbridge.com> writes:
> fixed fits_uhwi_p.
>
> tested on x86-64.
>
> kenny
>
> Index: gcc/wide-int.h
> ===================================================================
> --- gcc/wide-int.h	(revision 201985)
> +++ gcc/wide-int.h	(working copy)
> @@ -1650,7 +1650,7 @@ wide_int_ro::fits_shwi_p () const
>  inline bool
>  wide_int_ro::fits_uhwi_p () const
>  {
> -  return len == 1 || (len == 2 && val[1] == 0);
> +  return (len == 1 && val[0] >= 0) || (len == 2 && val[1] == 0);
>  }

With upper bits being undefined, it doesn't seem safe to check
val[0] or val[1] like this.   I was thinking along the lines of:

inline bool
wide_int_ro::fits_uhwi_p () const
{
  if (precision <= HOST_BITS_PER_WIDE_INT)
    return true;
  if (len == 1)
    return val[0] >= 0;
  if (precision < HOST_BITS_PER_WIDE_INT * 2)
    return ((unsigned HOST_WIDE_INT) val[1]
	    << (HOST_BITS_PER_WIDE_INT * 2 - precision)) == 0;
  return val[1] == 0;
}

Since we don't have a sign, everything HWI-sized or smaller fits in a
uhwi without loss of precision.

I've tested the above on x86_64-linux-gnu FWIW, in case it looks OK.

Thanks,
Richard
Kenneth Zadeck - Aug. 27, 2013, 6:36 p.m.
you are about an hour behind in reading your email.   I had just 
committed a patch that is very close to this.

On 08/27/2013 02:31 PM, Richard Sandiford wrote:
> Kenneth Zadeck <zadeck@naturalbridge.com> writes:
>> fixed fits_uhwi_p.
>>
>> tested on x86-64.
>>
>> kenny
>>
>> Index: gcc/wide-int.h
>> ===================================================================
>> --- gcc/wide-int.h	(revision 201985)
>> +++ gcc/wide-int.h	(working copy)
>> @@ -1650,7 +1650,7 @@ wide_int_ro::fits_shwi_p () const
>>   inline bool
>>   wide_int_ro::fits_uhwi_p () const
>>   {
>> -  return len == 1 || (len == 2 && val[1] == 0);
>> +  return (len == 1 && val[0] >= 0) || (len == 2 && val[1] == 0);
>>   }
> With upper bits being undefined, it doesn't seem safe to check
> val[0] or val[1] like this.   I was thinking along the lines of:
>
> inline bool
> wide_int_ro::fits_uhwi_p () const
> {
>    if (precision <= HOST_BITS_PER_WIDE_INT)
>      return true;
>    if (len == 1)
>      return val[0] >= 0;
>    if (precision < HOST_BITS_PER_WIDE_INT * 2)
>      return ((unsigned HOST_WIDE_INT) val[1]
> 	    << (HOST_BITS_PER_WIDE_INT * 2 - precision)) == 0;
>    return val[1] == 0;
> }
>
> Since we don't have a sign, everything HWI-sized or smaller fits in a
> uhwi without loss of precision.
>
> I've tested the above on x86_64-linux-gnu FWIW, in case it looks OK.
>
> Thanks,
> Richard
Richard Guenther - Aug. 28, 2013, 7:50 a.m.
On Tue, 27 Aug 2013, Richard Sandiford wrote:

> Kenneth Zadeck <zadeck@naturalbridge.com> writes:
> > fixed fits_uhwi_p.
> >
> > tested on x86-64.
> >
> > kenny
> >
> > Index: gcc/wide-int.h
> > ===================================================================
> > --- gcc/wide-int.h	(revision 201985)
> > +++ gcc/wide-int.h	(working copy)
> > @@ -1650,7 +1650,7 @@ wide_int_ro::fits_shwi_p () const
> >  inline bool
> >  wide_int_ro::fits_uhwi_p () const
> >  {
> > -  return len == 1 || (len == 2 && val[1] == 0);
> > +  return (len == 1 && val[0] >= 0) || (len == 2 && val[1] == 0);
> >  }
> 
> With upper bits being undefined, it doesn't seem safe to check

Err - we're back at upper bits being undefined?  Ugh.  Then
having both fits_uhwi_p and fits_shwi_p doesn't make sense.

> val[0] or val[1] like this.   I was thinking along the lines of:
> 
> inline bool
> wide_int_ro::fits_uhwi_p () const
> {
>   if (precision <= HOST_BITS_PER_WIDE_INT)
>     return true;
>   if (len == 1)
>     return val[0] >= 0;
>   if (precision < HOST_BITS_PER_WIDE_INT * 2)
>     return ((unsigned HOST_WIDE_INT) val[1]
> 	    << (HOST_BITS_PER_WIDE_INT * 2 - precision)) == 0;
>   return val[1] == 0;
> }
> 
> Since we don't have a sign, everything HWI-sized or smaller fits in a
> uhwi without loss of precision.

Which then means fits_hwi_p () is simply

  if (precision <= HOST_BITS_PER_WIDE_INT)
    return true;
  zext ();  // ick, modification in a predicate!  stupid undefined bits!
  return len == 1 || (len == 2 && val[1] == 0);

but if upper bits are undefined then the whole encoding and len
business is broken.

Richard.
Kenneth Zadeck - Aug. 28, 2013, 12:11 p.m.
On 08/28/2013 03:50 AM, Richard Biener wrote:
> On Tue, 27 Aug 2013, Richard Sandiford wrote:
>
>> Kenneth Zadeck <zadeck@naturalbridge.com> writes:
>>> fixed fits_uhwi_p.
>>>
>>> tested on x86-64.
>>>
>>> kenny
>>>
>>> Index: gcc/wide-int.h
>>> ===================================================================
>>> --- gcc/wide-int.h	(revision 201985)
>>> +++ gcc/wide-int.h	(working copy)
>>> @@ -1650,7 +1650,7 @@ wide_int_ro::fits_shwi_p () const
>>>   inline bool
>>>   wide_int_ro::fits_uhwi_p () const
>>>   {
>>> -  return len == 1 || (len == 2 && val[1] == 0);
>>> +  return (len == 1 && val[0] >= 0) || (len == 2 && val[1] == 0);
>>>   }
>> With upper bits being undefined, it doesn't seem safe to check
> Err - we're back at upper bits being undefined?  Ugh.  Then
> having both fits_uhwi_p and fits_shwi_p doesn't make sense.

yes, that is the problem.   Richard is going to look into what it might 
take to make rtl always have the upper bits canonized as sign 
extended.   if he/we can do this, then we will change everything so that 
it is always canonized above the precision.   Every one thinks this is a 
good plan, assuming you do not have to rewrite ever back end to do it.

>
>> val[0] or val[1] like this.   I was thinking along the lines of:
>>
>> inline bool
>> wide_int_ro::fits_uhwi_p () const
>> {
>>    if (precision <= HOST_BITS_PER_WIDE_INT)
>>      return true;
>>    if (len == 1)
>>      return val[0] >= 0;
>>    if (precision < HOST_BITS_PER_WIDE_INT * 2)
>>      return ((unsigned HOST_WIDE_INT) val[1]
>> 	    << (HOST_BITS_PER_WIDE_INT * 2 - precision)) == 0;
>>    return val[1] == 0;
>> }
>>
>> Since we don't have a sign, everything HWI-sized or smaller fits in a
>> uhwi without loss of precision.
> Which then means fits_hwi_p () is simply
>
>    if (precision <= HOST_BITS_PER_WIDE_INT)
>      return true;
>    zext ();  // ick, modification in a predicate!  stupid undefined bits!
>    return len == 1 || (len == 2 && val[1] == 0);
we do not ever do this.  where are you looking.

> but if upper bits are undefined then the whole encoding and len
> business is broken.
no it is not.


btw - welcome back.  we have missed you.
> Richard.

Patch

Index: gcc/wide-int.h
===================================================================
--- gcc/wide-int.h	(revision 201985)
+++ gcc/wide-int.h	(working copy)
@@ -1650,7 +1650,7 @@  wide_int_ro::fits_shwi_p () const
 inline bool
 wide_int_ro::fits_uhwi_p () const
 {
-  return len == 1 || (len == 2 && val[1] == 0);
+  return (len == 1 && val[0] >= 0) || (len == 2 && val[1] == 0);
 }
 
 /* Return the signed or unsigned min of THIS and C.  */