0
votes

I'm trying to cross-compile some code with NEON datatypes with g++ 4.9.1, but I keep crashing the compiler. Is this type of operation not allowed, or is this a compiler problem? My OS is Ubuntu 12.04, and I'm using arm-gcc "gcc version 4.9.1 (Ubuntu/Linaro 4.9.1-10ubuntu2)"

Filename: crash.cpp

#include <arm_neon.h>

void crash(
  const unsigned short * in,
  unsigned short * out,
  const int shift)
{
  for(int x=0; x<200; x+=8) {
    const uint16x8_t inValue = vld1q_u16(&in[x]);

    const uint16x8_t normalizedValue = inValue >> shift;

    vst1q_u16(&out[x], normalizedValue);
  }
}

Compile options:

arm-linux-gnueabihf-g++-4.9 -mfpu=neon-vfpv4 -c crash.cpp -o crash.o

Output:

crash.cpp: In function ‘void crash(const short unsigned int*, short unsigned int*, int)’:
crash.cpp:11:51: internal compiler error: in copy_to_mode_reg, at explow.c:654
     const uint16x8_t normalizedValue = inValue >> shift;
                                                   ^
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.9/README.Bugs> for instructions.
Preprocessed source stored into /tmp/ccfz4aZr.out file, please attach this to your bugreport.

This code compiles fine if I replace the "unsigned short" with "unsigned int", the "uint16x8_t" with "uint32x4_t", and the "_u16" suffixes with "_u32" suffixes.

1
Does GCC even offer automagically-overloaded operators for intrinsic types? I'd have thought you have to do everything with explicit intrisics (vshl in this case).Notlikethat
The automagic shift works with normal ints, though it crashes with the 16-bit short ints.Pete
Did you create a bug report on GCC?auselen
I don't have a Bugzilla account, and it isn't letting me create a new one. I tried on two computers on two networks, and it fails with the error " User account creation has been restricted. Contact your administrator or the maintainer ([email protected]) for information about creating an account." Emailing that address bounces due to "552 spam score exceeded threshold". (I'll make my above problem a separate stack overflow question.)Pete
gcc.gnu.org bugzilla account creation is restricted (done by administrator hand) due to spammer abuse from e.g. gmail.com. Please stick with it, email overseers, or all else failing, a gcc maintainer.fche

1 Answers

2
votes

That is a compiler bug, you should not get an internal compiler error.

You should be able to work around it by performing the shift with the NEON intrinsics. This is also more portable to other compilers, as the NEON intrinsics definition does not include using C operators on the NEON types - it's a GCC extension.

#include <arm_neon.h>

void crash(
  const unsigned short * in,
  unsigned short * out,
  const int shift)
{
  int16x8_t vshift = vdupq_n_s16(-shift);
  for(int x=0; x<200; x+=8) {
    const uint16x8_t inValue = vld1q_u16(&in[x]);

    const uint16x8_t normalizedValue = vshlq_u16(inValue, vshift);

    vst1q_u16(&out[x], normalizedValue);
  }
}