我有一些看起来像这样的 C 代码(Compiler-Explorer 上的完整代码:https://godbolt.org/z/aTGac8fco):
void foo(const float *restrict const input,
float *restrict const output,
const size_t input_buffer_size)
{
#pragma omp simd
for (size_t i = 0; i < input_buffer_size; i++)
{
float x;
bool predicate;
x = input[i]; // The [i] access is upsetting gcc but not clang.
x = predicate ? x : -x; // The warning goes away if I comment out this line.
...
}
}
尝试让 gcc-14 在较大的代码中向量化这个循环,但它给出了抱怨
missed: not vectorized: unsupported control flow in loop
。然而,Clang-19 能够很好地矢量化这一点。
如果我将
[i]
更改为 [0]
,投诉就会消失。同样,如果我删除谓词,它就会消失。我怀疑 GCC 不相信访问始终有效,但无法确认这一点,或者它不喜欢三元。
有一个非常相关的问题,但没有任何技巧有帮助。 循环中的gcc自动矢量化控制流程
目前我还无法隔离出 MWE。 (正在努力)。
编辑
如果在函数体中我设置了
const float inputs[100] = {0};
(并重命名函数签名以避免重新定义),那么投诉就会消失。这进一步加深了我对数组长度不满意的怀疑。
自从将代码放在编译器-解析器上后,我的怀疑也转向了三元。
令人沮丧的是,编译器消息并不是最精确的。
看起来我能够通过编写自己的三元运算符版本来安抚 GCC。
更换
float x = p ? t : f;
与更粗暴的
#pragma omp declare simd
static inline float ternary(bool p, const float t, const float f) {
return p * t + (!p) * f;
}