Richard Biener <richard.guent...@gmail.com> writes: > On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford > <rdsandif...@googlemail.com> wrote: >> Richard Biener <richard.guent...@gmail.com> writes: >>> Can we in such cases please to a preparatory patch and change the >>> CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to >>> mode precision first? >> >> I'm not sure what you mean here. CONST_INT HWIs are already sign-extended >> from mode precision to HWI precision. The 8-bit value 0xb10000000 must be >> represented as (const_int -128); nothing else is allowed. >> E.g. (const_int 128) >> is not a valid QImode value on BITS_PER_UNIT==8 targets. > > Yes, that's what I understand. But consider you get a CONST_INT that is > _not_ a valid QImode value.
But that's invalid :-) It is not valid to call: plus_constant (QImode, GEN_INT (128), 1) The point is that, even though it's invalid, we can't assert for it. plus_constant is not for arbitrary precision arithmetic. It's for arithmetic in a given non-VOIDmode mode. > Effectively a CONST_INT and CONST_DOUBLE is valid in multiple > modes and thus "arbitrary precision" with a limit set by the limit > of the encoding. The same CONST_INT and CONST_DOUBLE can be shared for several constants in different modes, yes, which is presumably what motivated making them VOIDmode in the first place. E.g. zero is const0_rtx for every integer mode. But in any given context, including plus_constant, the CONST_INT or CONST_DOUBLE has a specific mode. >>> Btw, plus_constant asserts that mode is either VOIDmode (I suppose >>> semantically do "arbitrary precision") >> >> No, not arbitrary precision. It's always the precision specified >> by the "mode" parameter. The assert is: >> >> gcc_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode); >> >> This is because GET_MODE always returns VOIDmode for CONST_INT and >> CONST_DOUBLE integers. The mode parameter is needed to tell us what >> precision those CONST_INTs and CONST_DOUBLEs actually have, because >> the rtx itself doesn't tell us. The mode parameter serves no purpose >> beyond that. > > That doesn't make sense. The only thing we could then do with the mode > is assert that the CONST_INT/CONST_DOUBLE is valid for mode. No, we have to generate a correct CONST_INT or CONST_DOUBLE result. If we are adding 1 to a QImode (const_int 127), we must return (const_int -128). If we are adding 1 to HImode (const_int 127), we must return (const_int 128). However... > mode does not constrain the result in any way, thus it happily produces > a CONST_INT (128) from QImode CONST_INT (127) + 1. So, does the > caller of plus_constant have to verify the result is actually valid in the > mode it expects? And what should it do if the result is not "valid"? ...good spot. That's a bug. It should be: return gen_int_mode (INTVAL (x) + c, mode); rather than: return GEN_INT (INTVAL (x) + c); It's a long-standing bug, because in the old days we didn't have the mode to hand. It was missed when the mode was added. But the mode is also used in: if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT) { double_int di_x = double_int::from_shwi (INTVAL (x)); double_int di_c = double_int::from_shwi (c); bool overflow; double_int v = di_x.add_with_sign (di_c, false, &overflow); if (overflow) gcc_unreachable (); return immed_double_int_const (v, VOIDmode); } which is deciding whether the result should be kept as a HWI even in cases where the addition overflows. It isn't arbitrary precision. Richard