编译带有AVX矢量警告的遗留GCC代码

Compiling legacy GCC code with AVX vector warnings

本文关键字:GCC 代码 警告 AVX 编译      更新时间:2023-10-16

我一直在谷歌上搜索,但找不到任何有用的。

typedef int64_t v4si __attribute__ ((vector_size(32)));
//warning: AVX vector return without AVX enabled changes the ABI [-Wpsabi]
// so isn't AVX already automatically enabled? 
// What does it mean "without AVX enabled"?
// What does it mean "changes the ABI"?
inline v4si v4si_gt0(v4si x_);
//warning: The ABI for passing parameters with 32-byte alignment has changed in GCC 4.6
//So why there's warning and what does it mean? 
// Why only this parameter got warning?
// And all other v4si parameter/arguments got no warning?
void set_quota(v4si quota);

这不是遗留代码。__attribute__ ((vector_size(32)))表示32字节向量,即256位,在x86上表示AVX。(GNU C向量扩展)

AVX不启用,除非您使用-mavx(或包含它的-march设置)。否则,编译器不允许生成使用AVX指令的代码,因为这些代码会在不支持AVX的旧cpu上触发非法指令错误。

所以编译器不能像常规调用约定那样在寄存器中传递或返回256b向量。它可能将它们视为与value传递的相同大小的结构体。

请参阅x86标签wiki中的ABI链接,或维基百科上的x86调用约定页面(大多没有提到向量寄存器)。


由于GNU C向量扩展语法与任何特定的硬件无关,使用32字节的向量仍然可以编译成正确的代码。它的性能很差,但即使编译器只能使用SSE指令,它仍然可以工作。(据我所知,gcc在生成处理超出目标机器支持范围的向量的代码方面做得非常糟糕。通过手动使用vector_size(16),您可以为具有16B向量的机器获得更好的代码。)

无论如何,关键是你得到一个警告,而不是编译器错误,因为 __attribute__ ((vector_size(32)))并不意味着AVX特别,但AVX或其他256b向量指令集需要它编译成好的代码。