On Tue, Mar 29, 2011 at 1:52 PM, Richard Sandiford <richard.sandif...@linaro.org> wrote: > Richard Guenther <richard.guent...@gmail.com> writes: >> On Thu, Mar 24, 2011 at 11:57 AM, 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. >>> >>> For this particular case, the problem is that vst2q_s32 and the >>> like initialise a union directly: >>> >>> union { int32x4x2_t __i; __builtin_neon_oi __o; } __bu = { __b; }; >>> >>> and this gets translated into a zeroing of the whole union followed >>> by an assignment to __i: >>> >>> __bu = {}; >>> __bu.__i = __b; >> >> Btw, this looks like a missed optimization in gimplification. Worth >> a bugreport (or even a fix). Might be a target but as well, dependent >> on how __builtin_neon_oi looks like. Do you have a complete testcase >> that reproduces the above with a cross? > > Yeah, build cc1 for arm-linux-gnueabi and compile the attached > testcase (from Chung-Lin) using: > > -O2 -g -mfpu=neon -mfloat-abi=softfp
It seems that count_type_elements is confused by unions and thus clearing is always performed. I fail to see why count_type_elements could not simply return 1 for all unions (non-initialized parts have undefined rather than zero content). categorize_ctor_elements also counts 8 elements for some reason. The following fixes it for me: Index: gcc/expr.c =================================================================== --- gcc/expr.c (revision 171606) +++ gcc/expr.c (working copy) @@ -5059,7 +5059,7 @@ count_type_elements (const_tree type, bo case UNION_TYPE: case QUAL_UNION_TYPE: - return -1; + return 1; case COMPLEX_TYPE: return 2; disclaimer: completely untested, might confuse the hell out of output_init_constructor and friends. Richard. > Rchard > >