Mike Stump <[email protected]> writes:
>> We currently only support constant integer
>> widths <= 2*HOST_BITS_PER_WIDE_INT, and the assert is correctly
>> triggering if we try to build a wider constant.
>
> Can you give me a concrete example of what will fail with the constant
> 0 generated by:
>
> return GEN_INT (i0);
>
> when the mode is 2*HOST_BITS_PER_WIDE_INT? When the mode is larger than this?
I think the assert is more saying that things have already gone wrong
if we have reached this point. immed_double_const is only designed
to handle two HOST_WIDE_INTs, so what exactly is the caller trying to do?
E.g. do we apply sign or zero extension to the 2 HOST_WIDE_INTs? If we're
going to remove the assert, we need to define stuff like that.
All ones is a pretty common constant, so if I was going to guess,
I'd have expected we'd sign extend, just like we do for CONST_INT.
So immed_double_const (-1, -1, int_mode) would always be GEN_INT (-1).
But if we do that, we need to define the high HOST_WIDE_INT of a
CONST_DOUBLE to be sign-extended too. And at the moment we don't;
the CONST_DOUBLE case of simplify_immed_subreg says:
/* It shouldn't matter what's done here, so fill it with
zero. */
for (; i < elem_bitsize; i += value_bit)
*vp++ = 0;
Compare with the CONST_INT case:
/* CONST_INTs are always logically sign-extended. */
for (; i < elem_bitsize; i += value_bit)
*vp++ = INTVAL (el) < 0 ? -1 : 0;
So...
> See, we already shorten the width of wide constants and expect that to
> work. This is just another instance of shortening. Now, just to see
> what lurks in there, I when through 100% of the uses of CONST_DOUBLE
> in *.c to get a feel for what might go wrong, the code is as benign as
> I expected, every instance I saw, looked reasonably safe. It doesn't
> get any better than this.
...I'm not sure about.
>From a quick grep, it looks like the case where I saw the immed_double_const
assert triggering -- the expansion of INTEGER_CST -- is the only case
where it could trigger. So I suppose the question shifts to the tree level.
Are callers to build_int_cst_wide and double_int_to_tree already
expected to check that constants wider than a double_int would not
be truncated? If so, then great. And if so, what are the rules
there regarding sign vs. zero extension beyond the high HOST_WIDE_INT?
>> FWIW, here's another case where this came up:
>>
>> http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01220.html
>
> Yes, and surprisingly, or not it is the exact same case as I can into.
I'd expect it to be a slightly different case. The original testcase was
a union constructor that was unnecessarily initialised to zero. That has
since been fixed.
Richard