我需要使用 GCC vector 扩展访问未对齐的值
下面的程序崩溃 - 在 clang 和 gcc 中
typedef int __attribute__((vector_size(16))) int4;
typedef int __attribute__((vector_size(16),aligned(4))) *int4p;
int main()
{
int v[64] __attribute__((aligned(16))) = {};
int4p ptr = reinterpret_cast<int4p>(&v[7]);
int4 val = *ptr;
}
但是如果我改变
typedef int __attribute__((vector_size(16),aligned(4))) *int4p;
至
typedef int __attribute__((vector_size(16),aligned(4))) int4u;
typedef int4u *int4up;
生成的汇编代码是正确的(使用未对齐的加载) - 在 clang 和 gcc 中。
单一定义有什么问题或我错过了什么?它可以是 clang 和 gcc 中的相同错误吗?
注意: 它发生在 clang 和 gcc 中
最佳答案
TL; 博士
您改变了指针类型本身的对齐方式,而不是指针类型 。这与 vector_size
属性无关,而与 aligned
属性有关。它也不是错误,并且在 GCC 和 Clang 中都正确实现。
很长的故事
从 GCC 文档中,§ 6.33.1 Common Type Attributes(强调):
有问题的类型是被声明的类型, 而不是 被声明的类型所指向的类型。所以,
typedef int __attribute__((vector_size(16),aligned(4))) *int4p;
声明一个指向 *T 类型对象的新类型 T,其中:
同时,§ 6.49 Using Vector Instructions through Built-in Functions 说(强调):
演示
#include <stdio.h>
typedef int __attribute__((aligned(128))) * batcrazyptr;
struct batcrazystruct{
batcrazyptr ptr;
};
int main()
{
printf("Ptr: %zu\n", sizeof(batcrazyptr));
printf("Struct: %zu\n", sizeof(batcrazystruct));
}
输出:
Ptr: 8
Struct: 128
这与
batcrazyptr ptr
本身的对齐要求改变了一致,而不是它的指针,并且与文档一致。解决方案
恐怕您将被迫使用一连串
typedef
,就像您对 int4u
所做的那样。使用单独的属性来指定 typedef
中每个指针级别的对齐方式是不合理的。关于c++ - gcc vector 扩展中未对齐的加载/存储,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41931278/