On Mon, 19 Mar 2012, Eric Botcazou wrote:
> > It does make sense to give the target control over the mode used for
> > sizetype. Of course a global change of the default (for example to
> > use Pmode as Ada did) will require testing each affected target,
> > so I think it makes sense to keep the default as-is.
>
> No disagreement here.
>
> > Btw, we still have the issue on which _precision_ we should use for
> > sizetype -- if we expect modulo-semantics of arithmetic using it
> > (thus basically sign-less arithmetic) then the precision has to match
> > the expectation the C frontend (and other frontends) assume how pointer
> > offsets are handled. Currently the C frontend gets this not correct
> > which means negative offsets will be not correctly handled.
>
> Is this theoritical or practical? Are you talking about GET_MODE_BITSIZE vs
> GET_MODE_PRECISION wrt TYPE_PRECISION?
No, about the disagreement of the precision of ptrdiff_t and that
of sizetype. See c-common.c:pointer_int_sum:
/* Convert the integer argument to a type the same size as sizetype
so the multiply won't overflow spuriously. */
if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
|| TYPE_UNSIGNED (TREE_TYPE (intop)) != TYPE_UNSIGNED (sizetype))
intop = convert (c_common_type_for_size (TYPE_PRECISION (sizetype),
TYPE_UNSIGNED (sizetype)),
intop);
and consider what happens for example on m32c - we truncate the
24bit ptrdiff_t to the 16bit sizetype, losing bits. And we are
performing the index * size multiplication in a maybe artificially
large type, losing information about overflow behavior and possibly
generating slow code for no good reason.
ISTR there was a correctness issue here, too, but maybe I've fixed
that already.
> > Similar issues arise from the mode/precision chosen for the bitsize
> > types. We choose a way to wide precision for them, so the
> > modulo-semantics assumption does not usually hold for bitsize
> > quantities.
>
> Again because of GET_MODE_PRECISION vs GET_MODE_BITSIZE? Otherwise we round
> up
> the precision since GCC 4.5 so there should be no more weird precision.
Well, because if sizetype is SImode (with -m32) and bitsizetype DImode
(we round up its precision to 64bits) then a negative byte-offset
in the unsigned sizetype is 0xffff for example. When we then perform
arithmetic on bits, say (bitsizetype)sz * BITS_PER_UNIT + 9 we get
0xffff * 8 == 0x80001 (oops) + 9 == 0x80001. bitsizetype is of too
large precision to be a modulo-arithmetic bit-equivalent to sizetype
(at least for our constant-folding code) for "negative" offsets.
Probably one of the reasons of the weird
sizetype-is-unsigned-but-constants-are-sign-extended rule.
Richard.