循环中的gcc自动矢量化控制流程

use*_*814 6 c gcc avx2 auto-vectorization

在下面的代码中,为什么第二个循环能够自动矢量化但第一个不能?如何修改代码以便自动进行矢量化?gcc说:

注意:没有矢量化:控制循环中的流程.

我使用的是gcc 8.2,标志是-O3 -fopt-info-vec-all.我正在编译x86-64 avx2.

#include <stdlib.h>
#include <math.h>

void foo(const float * x, const float * y, const int * v, float * vec, float * novec, size_t size) {
    size_t i;
    float bar;
    for (i=0 ; i<size ; ++i){
        bar = x[i] - y[i];
        novec[i] = v[i] ? bar : NAN;
    }
    for (i=0 ; i<size ; ++i){
        bar = x[i];
        vec[i] = v[i] ? bar : NAN;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:这会自动执行:

for (i=0 ; i<size ; ++i){
    bar = x[i];
    novec[i] = v[i] ? bar : NAN;
    novec[i] -= y[i];
}
Run Code Online (Sandbox Code Playgroud)

我仍然想知道为什么gcc说第一个循环的控制流程.

Pet*_*des 5

clang自动向量化甚至第一个循环,但gcc8.2没有.(https://godbolt.org/z/cnlwuO)

gcc矢量化-ffast-math.也许它担心从减法中保留FP异常标志状态?

-fno-trapping-math足以让gcc自动进行矢量化(没有其余的东西-ffast-math),所以显然它担心FP异常.(https://godbolt.org/z/804ykV).我认为它过于谨慎,因为无论是否使用,C源都会每次都进行计算bar.

gcc将自动矢量化简单的FP a[i] = b[i]+c[i]循环,而无需任何FP数学选项.