This is the mail archive of the
mailing list for the GCC project.
Re: wide-int branch now up for public comment and review
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: Mike Stump <mikestump at comcast dot net>
- Cc: Kenneth Zadeck <zadeck at naturalbridge dot com>, rguenther at suse dot de, gcc-patches <gcc-patches at gcc dot gnu dot org>, r dot sandiford at uk dot ibm dot com
- Date: Sat, 24 Aug 2013 09:30:24 +0100
- Subject: Re: wide-int branch now up for public comment and review
- References: <520A9DCC dot 6080609 at naturalbridge dot com> <87ppt4e9hg dot fsf at talisman dot default> <E6AC8DB1-54FC-4809-8675-CF9344E75AE1 at comcast dot net>
Mike Stump <email@example.com> writes:
> On Aug 23, 2013, at 8:02 AM, Richard Sandiford
> <firstname.lastname@example.org> wrote:
>>> * When a constant that has an integer type is converted to a
>>> wide-int it comes in with precision 0. For these constants the
>>> top bit does accurately reflect the sign of that constant; this
>>> is an exception to the normal rule that the signedness is not
>>> represented. When used in a binary operation, the wide-int
>>> implementation properly extends these constants so that they
>>> properly match the other operand of the computation. This allows
>>> you write:
>>> tree t = ...
>>> wide_int x = t + 6;
>>> assuming t is a int_cst.
>> This seems dangerous. Not all code that uses "unsigned HOST_WIDE_INT"
>> actually wants it to be an unsigned value. Some code uses it to avoid
>> the undefinedness of signed overflow. So these overloads could lead
>> to us accidentally zero-extending what's conceptually a signed value
>> without any obvious indication that that's happening. Also, hex constants
>> are unsigned int, but it doesn't seem safe to assume that 0x80000000 was
>> meant to be zero-extended.
>> I realise the same thing can happen if you mix "unsigned int" with
>> HOST_WIDE_INT, but the point is that you shouldn't really do that
>> in general, whereas we're defining these overloads precisely so that
>> a mixture can be used.
> So, I don't like penalizing all users, because one user might write
> incorrect code. We have the simple operators so that users can retain
> some of the simplicity and beauty that is the underlying language.
> Those semantics are well known and reasonable. We reasonably match
> those semantics. At the end of the day, we have to be able to trust
> what the user writes. Now, a user that doesn't trust themselves, can
> elect to not use these functions; they aren't required to use them.
But the point of my "unsigned HOST_WIDE_INT" example is that the
semantics of the language can also get in the way. If you're adding
or multiplying two smallish constants, you should generally use
"unsigned HOST_WIDE_INT" in order to avoid the undefinedness of signed
overflow. In that kind of case the "unsigned" in no way implies that
you want the value to be extended to the wider types that we're
adding with this patch. I'm worried about making that assumption
just to provide a bit of syntactic sugar, especially when any
wrong-code bug would be highly value-dependent. When this kind of
thing is done at the rtl level, the original constant (in a CONST_INT)
is also HOST_WIDE_INT-sized, so the kind of code that I'm talking about
did not do any promotion before the wide-int conversion. That changes
if we generalise one of the values to a wide_int.
It isn't just a case of being confident when writing new code.
It's a case of us changing a large body of existing code in one go,
some of which uses unsigned values for the reason above.
Like I say, all this objection is for "unsigned int and above".
If we provide the syntactic sugar for plain "int" and use templates
to force a compiler error for "higher" types then that would still allow
things like "x + 2" but force a bit of analysis for "x + y" in cases
where "x" and "y" are not the same type and one is wide_int.