在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编译器中启用未对齐访问?
答案 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
中将其转换为寄存器。