ARM NEON 数据类型导致编译器崩溃

Posted

技术标签:

【中文标题】ARM NEON 数据类型导致编译器崩溃【英文标题】:Compiler crash with ARM NEON datatypes 【发布时间】:2014-10-20 20:38:39 【问题描述】:

我正在尝试使用 NEON 数据类型与 g++ 4.9.1 交叉编译一些代码,但我一直在使编译器崩溃。是不允许这种类型的操作,还是编译器的问题?我的操作系统是 Ubuntu 12.04,我正在使用 arm-gcc "gcc version 4.9.1 (Ubuntu/Linaro 4.9.1-10ubuntu2)"

文件名: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);
  

编译选项:

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

输出:

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.

如果我将“unsigned short”替换为“unsigned int”,将“uint16x8_t”替换为“uint32x4_t”,并将“_u16”后缀替换为“_u32”后缀,则此代码编译良好。

【问题讨论】:

GCC 是否甚至为内在类型提供自动重载的运算符?我原以为你必须用显式的内部函数来做所有事情(在这种情况下是vshl)。 自动转换适用于普通整数,但它会因 16 位短整数而崩溃。 您是否创建了关于 GCC 的错误报告? 我没有 Bugzilla 帐户,它不允许我创建一个新帐户。我在两个网络上的两台计算机上进行了尝试,但失败并显示错误“用户帐户创建已受到限制。请联系您的管理员或维护者 (overeers@gcc.gnu.org) 以获取有关创建帐户的信息。”由于“552 垃圾邮件分数超过阈值”,通过电子邮件发送该地址被退回。 (我将把上述问题作为一个单独的堆栈溢出问题。) gcc.gnu.org bugzilla 帐户创建受到限制(由管理员手工完成),因为垃圾邮件发送者滥用例如gmail.com。请坚持下去,电子邮件监督者,或者其他所有失败的 gcc 维护者。 【参考方案1】:

这是一个编译器错误,你不应该得到一个内部编译器错误。

您应该能够通过使用 NEON 内部函数执行转换来解决它。这也更便于其他编译器移植,因为 NEON 内在函数定义不包括在 NEON 类型上使用 C 运算符 - 它是 GCC 扩展。

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

【讨论】:

以上是关于ARM NEON 数据类型导致编译器崩溃的主要内容,如果未能解决你的问题,请参考以下文章

arm NEON 数据类型中的 I8(未指定类型的整数)是啥?

arm_neon.h 是不是缺少所有 float16_t 类型?

ARM 中的 NEON 实现

仅在使用设备 arm_neon.h 时 Xcode6 编译错误

NEON 矢量数据类型的别名

为 ARM NEON 编译时出现未知的 GCC 错误(严重)