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