矢量化因循环中不受支持的控制流而失败

问题描述 投票:0回答:1

我有一些看起来像这样的 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};
(并重命名函数签名以避免重新定义),那么投诉就会消失。这进一步加深了我对数组长度不满意的怀疑。

自从将代码放在编译器-解析器上后,我的怀疑也转向了三元。

令人沮丧的是,编译器消息并不是最精确的。

c gcc vectorization
1个回答
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;
}
© www.soinside.com 2019 - 2024. All rights reserved.