Mike Stump <mikest...@comcast.net> 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

Reply via email to