patch to fix constant math - 4th patch - the wide-int class.
Lawrence Crowl
crowl@google.com
Tue Oct 23 20:51:00 GMT 2012
On 10/23/12, Kenneth Zadeck <zadeck@naturalbridge.com> wrote:
> On 10/23/2012 02:38 PM, Lawrence Crowl wrote:
>> On 10/23/12, Kenneth Zadeck <zadeck@naturalbridge.com> wrote:
>>> On 10/23/2012 10:12 AM, Richard Biener wrote:
>>>> + inline bool minus_one_p () const;
>>>> + inline bool zero_p () const;
>>>> + inline bool one_p () const;
>>>> + inline bool neg_p () const;
>>>>
>>>> what's wrong with w == -1, w == 0, w == 1, etc.?
>>> I would love to do this and you seem to be somewhat knowledgeable
>>> of c++. But i cannot for the life of me figure out how to do it.
>> Starting from the simple case, you write an operator ==.
>>
>> as global operator: bool operator == (wide_int w, int i);
>> as member operator: bool wide_int::operator == (int i);
>>
>> In the simple case,
>>
>> bool operator == (wide_int w, int i)
>> {
>> switch (i)
>> {
>> case -1: return w.minus_one_p ();
>> case 0: return w.zero_p ();
>> case 1: return w.one_p ();
>> default: unexpected....
>> }
>> }
>
> no, this seems wrong. you do not want to write code that can only
> fail at runtime unless there is a damn good reason to do that.
Well, that's because it's the oversimplified case. :-)
>>> say i have a TImode number, which must be represented in 4 ints
>>> on a 32 bit host (the same issue happens on 64 bit hosts, but
>>> the examples are simpler on 32 bit hosts) and i compare it to -1.
>>> The value that i am going to see as the argument of the function
>>> is going have the value 0xffffffff. but the value that i have
>>> internally is 128 bits. do i take this and 0 or sign extend it?
>>
>> What would you have done with w.minus_one_p ()?
>
> the code "knows" that -1 is a negative number and it knows the
> precision of w. That is enough information. So it logically
> builds a -1 that has enough bits to do the conversion.
And the code could also know that '-n' is a negative number and do
the identical conversion. It would certainly be more difficult to
write and get all the edge cases.
>>> in particular if someone wants to compare a number to 0xdeadbeef i
>>> have no idea what to do. I tried defining two different functions,
>>> one that took a signed and one that took and unsigned number but
>>> then i wanted a cast in front of all the positive numbers.
>> This is where it does get tricky. For signed arguments, you should sign
>> extend. For unsigned arguments, you should not. At present, we need
>> multiple overloads to avoid type ambiguities.
>>
>> bool operator == (wide_int w, long long int i);
>> bool operator == (wide_int w, unsigned long long int i);
>> inline bool operator == (wide_int w, long int i)
>> { return w == (long long int) i; }
>> inline bool operator (wide_int w, unsigned long int i)
>> { return w == (unsigned long long int) i; }
>> inline bool operator == (wide_int w, int i)
>> { return w == (long long int) i; }
>> inline bool operator (wide_int w, unsigned int i)
>> { return w == (unsigned long long int) i; }
>>
>> (There is a proposal before the C++ committee to fix this problem.)
>>
>> Even so, there is room for potential bugs when wide_int does not
>> carry around whether or not it is signed. The problem is that
>> regardless of what the programmer thinks of the sign of the wide int,
>> the comparison will use the sign of the int.
>
> when they do we can revisit this. but i looked at this and i said the
> potential bugs were not worth the effort.
I won't disagree. I was answering what I thought were questions on
what was possible.
>>> If there is a way to do this, then i will do it, but it is going
>>> to have to work properly for things larger than a HOST_WIDE_INT.
>> The long-term solution, IMHO, is to either carry the sign information
>> around in either the type or the class data. (I prefer type, but
>> with a mechanism to carry it as data when needed.) Such comparisons
>> would then require consistency in signedness between the wide int
>> and the plain int.
>
> carrying the sign information is a non starter. The rtl level does
> not have it and the middle end violates it more often than not. My
> view was to design this having looked at all of the usage. I have
> basically converted the whole compiler before i released the abi. I am
> still getting out the errors and breaking it up in reviewable sized
> patches, but i knew very very well who my clients were before i wrote
> the abi.
Okay.
>>> I know that double-int does some of this and it does not carry
>>> around a notion of signedness either. is this just code that has
>>> not been fully tested or is there a trick in c++ that i am missing?
>> The double int class only provides == and !=, and only with other
>> double ints. Otherwise, it has the same value query functions that
>> you do above. In the case of double int, the goal was to simplify
>> use of the existing semantics. If you are changing the semantics,
>> consider incorporating sign explicitly.
>
> i have, and it does not work.
Unfortunate.
--
Lawrence Crowl
More information about the Gcc-patches
mailing list