`__m256`的包装器使用构造函数生成分段错误 - Windows 64 + MinGW + AVX问题

Tho*_*mas 6 c++ g++ avx windows64 mingw-w64

我有一个看起来像这样的联盟

 union bareVec8f { 
    __m256 m256; //avx 8x float vector
    float floats[8];
    int ints[8];
    inline bareVec8f(){
    }
    inline bareVec8f(__m256 vec){
        this->m256 = vec;
    }
    inline bareVec8f &operator=(__m256 m256) {
        this->m256 = m256;
        return *this;
    }

    inline operator __m256 &() {
        return m256;
    }
}
Run Code Online (Sandbox Code Playgroud)

__m256需要在32字节边界上对齐以与SSE函数一起使用,并且应该是自动的,即使在联合内也是如此.

而当我这样做

bareVec8f test = _mm256_set1_ps(1.0f);
Run Code Online (Sandbox Code Playgroud)

我遇到了分段错误.由于我制作的构造函数,此代码应该可以工作.但是,当我这样做

bareVec8f test;
test.m256 = _mm256_set1_ps(8.f);
Run Code Online (Sandbox Code Playgroud)

我没有得到分段错误.

因此,因为工作正常,所以联合可能正确对齐,但是看起来构造函数只会导致一些分段错误

我正在使用gcc 64bit windows编译器

---------------------------------编辑Matt设法生成了这里似乎发生的最简单的错误示例.

#include <immintrin.h>

void foo(__m256 x) {}

int main()
{
    __m256 r = _mm256_set1_ps(0.0f);
    foo(r);
}
Run Code Online (Sandbox Code Playgroud)

我正在编译 -std=c++11 -mavx

M.M*_*M.M 7

这是g ++ for Windows中的一个错误.它应该在执行时不执行32字节堆栈对齐. 错误49001 错误54412


这个SO线程上,有人制作了一个Python脚本来处理g ++的程序集输出以解决问题,因此这将是一个选项.

否则,为了在你的联合中避免这种情况,你可以创建__m256按值获取的函数,而不是通过引用来获取它.除非优化很低/不合适,否则不应该有任何性能损失.

如果你不知道 - 联合别名导致C++中的未定义行为,则不允许写入m256然后读取floats或者ints例如.所以也许你的问题有一个不同的解决方案.