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.