Patchwork Fix PR48183, NEON ICE in emit-rtl.c:immed_double_const() under -g

login
register
mail settings
Submitter Julian Brown
Date March 24, 2011, 1:49 p.m.
Message ID <20110324134910.19d9c755@rex.config>
Download mbox | patch
Permalink /patch/88199/
State New
Headers show

Comments

Julian Brown - March 24, 2011, 1:49 p.m.
On Thu, 24 Mar 2011 10:57:06 +0000
Richard Sandiford <richard.sandiford@linaro.org> wrote:

> Chung-Lin Tang <cltang@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  <cltang@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

Patch

--- 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);