Richard Biener <richard.guent...@gmail.com> writes: > On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford > <rdsandif...@googlemail.com> wrote: >> Richard Biener <richard.guent...@gmail.com> writes: >>> On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford >>> <rdsandif...@googlemail.com> wrote: >>>> In other words, one of the reasons wide_int can't be exactly 1:1 >>>> in practice is because it is clearing out these mistakes (GEN_INT >>>> rather than gen_int_mode) and missing features (non-power-of-2 widths). >>> >>> Note that the argument should be about CONST_WIDE_INT here, >>> not wide-int. Indeed CONST_WIDE_INT has the desired feature >>> and can be properly truncated/extended according to mode at the time >>> we build it >>> via immed_wide_int_cst (w, mode). I don't see the requirement that >>> wide-int itself is automagically providing that truncation/extension >>> (though it is a possibility, one that does not match existing behavior of >>> HWI for CONST_INT or double-int for CONST_DOUBLE). >> >> I agree it doesn't match the existing behaviour of HWI for CONST_INT or >> double-int for CONST_DOUBLE, but I think that's very much a good thing. >> The model for HWIs at the moment is that you have to truncate results >> to the canonical form after every operation where it matters. As you >> proved in your earlier message about the plus_constant bug, that's easily >> forgotten. I don't think the rtl code is doing all CONST_INT arithmetic >> on full HWIs because it wants to: it's doing it because that's the way >> C/C++ arithmetic on primitive types works. In other words, the current >> CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime N) >> using a single primitive integer type. wide_int gives us N-bit arithmetic >> directly; no emulation is needed. > > Ok, so what wide-int provides is integer values encoded in 'len' HWI > words that fit in 'precision' or more bits (and often in less). wide-int > also provides N-bit arithmetic operations. IMHO both are tied > too closely together. A give constant doesn't really have a precision.
I disagree. All rtl objects have a precision. REGs, MEMs, SYMBOL_REFs, LABEL_REFs and CONSTs all have precisions, and the last three are run-time constants. Why should CONST_INT and CONST_DOUBLE be different? See e.g. the hoops that cselib has to jump through: /* We need to pass down the mode of constants through the hash table functions. For that purpose, wrap them in a CONST of the appropriate mode. */ static rtx wrap_constant (enum machine_mode mode, rtx x) { if ((!CONST_SCALAR_INT_P (x)) && GET_CODE (x) != CONST_FIXED) return x; gcc_assert (mode != VOIDmode); return gen_rtx_CONST (mode, x); } That is, cselib locally converts (const_int X) into (const:M (const_int X)), purely so that it doesn't lose track of the CONST_INT's mode. (const:M (const_int ...)) is invalid rtl elsewhere, but a necessary hack here all the same. > What RTL currently has looks better to me - operations have > explicitely specified precisions. But that isn't enough to determine the precision of all operands. A classic case is ZERO_EXTEND. Something like: (zero_extend:DI (reg:SI X)) is unambiguous. But if you substitute (reg:SI X) with a CONST_INT, the result becomes ambiguous. E.g. we could end up with: (zero_extend:DI (const_int -1)) The ZERO_EXTEND operand still has SImode, but that fact is not explicit in the rtl, and is certainly not explicit in the ZERO_EXTEND operation. So if we just see the result above, we no longer know whether the result should be (const_int 0xff), (const_int 0xffff), or what. The same goes for: (zero_extend:DI (const_int 256)) where (const_int 0) and (const_int 256) are both potential results. It's not just ZERO_EXTEND. E.g.: (zero_extract:SI ...) tells you that an SImode value is being extracted, but it doesn't tell you what precision you're extracting from. So for: (zero_extract:SI (const_int -1) (const_int X) (const_int 3)) how many 1 bits should be the result have? Because of the sign-extension canonicalisation, the answer depends on the precision of the (const_int -1), which has now been lost. If instead CONST_INTs were stored in zero-extended form, the same ambiguity would apply to SIGN_EXTRACT. This sort of thing has been a constant headache in rtl. I can't stress how much I feel it is _not_ better than recording the precision of the constant :-) Richard