如何在LLVM编译器中为ARM NEON启用UnAligned Access?

时间:2015-07-02 06:04:16

标签: xcode llvm memory-alignment neon

在LLVM编译器中为ARM NEON启用未对齐内存访问的标志是什么。 我在Xcode中测试了我的ARM NEON内在程序。我正在从未对齐的内存中访问数据:

char TempMemory[32] = {0};
char * pTempMem = TempMemory;
pTempMem += 7;
int32x2_t i32x2_value = vld1_lane_s32((int32_t const *) pTempMem, i32x2_offset, 0);

内在函数的等效汇编应为VLD1.32 {d0[0]}, [pTempMem],但编译器将其与下一个32的多个对齐并访问数据。因此,我的程序运行不正常。

那么,如何在LLVM编译器中启用未对齐访问?

1 个答案:

答案 0 :(得分:1)

这实际上不是一个NEON问题,它是一个C问题,问题是:

 vld1_lane_s32((int32_t const *) pTempMem , i32x2_offset, 0);

投射指针是给编译器的一条消息说"嘿,我知道这看起来很糟糕,但相信我,我真的知道我在做什么"。将指向类型A的指针转换为指向类型B的指针,如果指针没有适合类型B的对齐,则会给出未定义的行为。因此,编译器可以自由地假设vld_1_lane_s32的参数始终是32位对齐的,因为它没有任何有效的方式(而且你已经答应过你知道你是什么&# #39;重做),因此它会发出带有对齐提示的指令。

现在,你可以摆弄选项以试图获得与你想要的不同的未定义行为,但这只是躲避问题而不是修复它。底层NEON指令集可以支持未对齐访问,不会影响C语言对数据对齐的定义和限制。

我不熟悉LLVM的巧妙程度,所以我不确定是否只是省略指针转换就行了(从技术上讲,C允许将char *转换为任何其他类型的数据指针,所以它能够整理对齐本身)。否则,解决方案是使用适当的vld*_u8操作通过正确的类型将数据加载到向量中,然后在vreinterpret_s32_u8中将其转换为寄存器。