On Thu, 24 Mar 2011 10:57:06 +0000
Richard Sandiford <richard.sandif...@linaro.org> wrote:
> Chung-Lin Tang <clt...@codesourcery.com> writes:
> > PR48183 is a case where ARM NEON instrinsics, under -O -g, produce
> > debug insns that tries to expand OImode (32-byte integer) zero
> > constants, much too large to represent as two HOST_WIDE_INTs; as
> > the internals manual indicates, such large constants are not
> > supported in general, and ICEs on the GET_MODE_BITSIZE(mode) ==
> > 2*HOST_BITS_PER_WIDE_INT assertion.
> >
> > This patch allows the cases where the large integer constant is
> > still representable using a single CONST_INT, such as zero(0).
> > Bootstrapped and tested on i686 and x86_64, cross-tested on ARM,
> > all without regressions. Okay for trunk?
> >
> > Thanks,
> > Chung-Lin
> >
> > 2011-03-20 Chung-Lin Tang <clt...@codesourcery.com>
> >
> > * emit-rtl.c (immed_double_const): Allow wider than
> > 2*HOST_BITS_PER_WIDE_INT mode constants when they are
> > representable as a single const_int RTX.
>
> I realise this might be seen as a good expedient fix, but it makes
> me a bit uneasy. Not a very constructive rationale, sorry.
FWIW I also had a "fix" for this issue, which is equivalent to
Chung-Lin's patch apart from only allowing constant-zero (attached).
That's not really a vote from me for this approach, but maybe limiting
the extent to which we pretend to support wide-integer constants like
this is sensible, if we do go that way.
Julian
--- gcc/expr.c (revision 314639)
+++ gcc/expr.c (working copy)
@@ -8458,6 +8458,18 @@ expand_expr_real_1 (tree exp, rtx target
return decl_rtl;
case INTEGER_CST:
+ if (GET_MODE_BITSIZE (mode) > 2 * HOST_BITS_PER_WIDE_INT)
+ {
+ /* FIXME: We can't generally represent wide integer constants,
+ but GCC sometimes tries to initialise wide integer values (such
+ as used by the ARM NEON support) with zero. Handle that as a
+ special case here. */
+ if (initializer_zerop (exp))
+ return CONST0_RTX (mode);
+
+ gcc_unreachable ();
+ }
+
temp = immed_double_const (TREE_INT_CST_LOW (exp),
TREE_INT_CST_HIGH (exp), mode);