This is the mail archive of the
mailing list for the GCC project.
Re: [PATCH] Fix optimization regression in constant folder
Richard Kenner wrote:
>> That begs the question: why aren't they signed
> I think because you run into problems in corner cases in C if size_t and
> sizetype don't have the same precision and signedness or, more precisely,
> if you can't encode a value that's a valid result of size_t in sizetype.
That's why C has size_t and ptrdiff_t. I'd expect that DECL_SIZE and
friends to have an unsigned sizetype. I'd expect things like the
difference between two field offsets to have a signed sizetype.
Obviously, if we need to represent all possible differences, then you
need a wider type than sizetype to represent that -- just as ptrdiff_t
cannot represent all possible differences between pointers in C.
In any case, I think we've just about answered what the semantics of the
current sizetype are:
1. Unsigned sizetypes are sign-extended, as if they were signed. (See
So, in particular, when you pass (0, 0xffffffff) to fit_double_type,
using an unsigned sizetype as a the type, you end up with (0xffffffff,
0xffffffff) as your representation, assuming 32-bit HOST_WIDE_INT and
32-bit sizetype. Other checks seem to be consequences of that; you
cannot make certain assumptions about widening, you can ignore the
sign-extended bits when doing host_integerp, etc.
2. TREE_OVERFLOW is set for operations that overflow on an unsigned
sizetype, as if they were signed. (See int_const_binop.)
3. Unsigned sizetypes are treated as if TYPE_OVERFLOW_UNDEFINED (i.e.,
as if they were signed) was defined in the case of multiply/division
that cancel. (See extract_muldiv_1.)
I don't think we know the *why* for (1) and (2) at this point. We do
have a justification for (3); this is your claim that when we generate
these combinations we mean to allow reassociation.
I'm not sure how sizetype is a win over representing sizes as size_t,
differences between sizes as ptrdiff_t, and performing operations on
sizes by first doing a bit-preserving cast from size_t to ptrdiff_t,
then doing all the operations on ptrdiff_t, and then casting back if
(650) 331-3385 x713