1
votes

I'm trying to use the Visual C++ 2017 auto-vectorizer to make the following loop vectorized (/arch:AVX2) :

void fun(char* data, char* threshold, char* output, int64_t len)
{
    // Assumes output filled with 0

    for (int64_t c = 0, mm = len; c < mm; ++c)
    {
        output[c] = (data[c] < threshold[c])
                            ? (threshold[c] - data[c]) 
                            : output[c];
    }
}

This code is used to compare 2 arrays (data and threshold), and store their difference in output if data < threshold, 0 otherwise.

This loop does not auto-vectorize :

info C5002: loop not vectorized due to reason '1100'

Meaning : Loop contains control flow—for example, "if" or "?".

Ok, I get that, I need to rewrite my loop so I remove the control flow or I simplify it for the compiler. BUT :

  • GCC has no problem vectorizing it

  • Visual Studio accepts to vectorize it if I change the code that way :

code:

for (int64_t c = 0, mm = len; c < mm; ++c)
{
    output[c] = (data[c] < threshold[c])
                        ? (char)(threshold[c] - data[c]) 
                        : output[c];
}

Why does this (char) cast would change anything for Visual Studio auto-vectorizer ? Is that a bug of the auto-vectorizer or am I missing something ?

Moreover, if I change the type of the output array from char to int, I cannot get Visual Studio to vectorize my loop anymore, whereas GCC does :

void fun(char* data, char* threshold, int* output, int64_t len)
{
    // Assumes output filled with 0
    for (int64_t c = 0, mm = len; c < mm; ++c)
    {
        output[c] = (data[c] < threshold[c])
                            ? (int)(threshold[c] - data[c]) 
                            : output[c];
    }
}

Is Visual Studio 2017 auto-vectorizer lacking compared to GCC ? Or Am I trying to do something I should not be doing ?

1
Have you checked the assembly to make sure it's really vectorized? - Matthieu Brucher
And yes, VS vectorizer is very inferior to gcc's and clang's, and very far behind Intel's. - Matthieu Brucher
@MatthieuBrucher Yes I checked, it is really vectorized when I cast - Yoann Nicod

1 Answers

1
votes

This is simply a missed optimization opportunity. The VS vectorizer has improved a lot since 2012 but it's still quite lacking compared to gcc or clang. Keep in mind that their compiler is based on an ancient codebase, e.g. they didn't even have an SSA representation until lately.