我需要使用 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,其中:
  • *T 是一个 16 字节的 vector ,其大小(16 字节)具有默认对齐方式
  • T 是一种指针类型,这种类型的变量可能会异常对齐存储到低至 4 字节的边界(即使它们指向的是一种更对齐的 *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/

    10-11 22:42
    查看更多