[llvm-bugs] [Bug 32854] New: Loop-idiom recognition for memset in the inner-loop of a nested-loop interferes with vectorization

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Apr 28 22:18:24 PDT 2017


https://bugs.llvm.org/show_bug.cgi?id=32854

            Bug ID: 32854
           Summary: Loop-idiom recognition for memset in the inner-loop of
                    a nested-loop interferes with vectorization
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Loop Optimizer
          Assignee: unassignedbugs at nondot.org
          Reporter: brycelelbach at gmail.com
                CC: llvm-bugs at lists.llvm.org

Created attachment 18382
  --> https://bugs.llvm.org/attachment.cgi?id=18382&action=edit
Reduced Test Case

Compilation options, build environment, etc are documented in the attached file
and here:

https://wandbox.org/permlink/o06VeIxCKC1qIhUh

Summary: We have a nested loop like this (where A is a double* __restrict__):

    for (ptrdiff_t j = 0; j != N; ++j)
        for (ptrdiff_t i = 0; i != N; ++i)
            A[i + j * N] = 0.0F;

Loop-idiom recognition determines that it can replace the inner loop with
memset, turning the code into:

    for (ptrdiff_t j = 0; j != N; ++j)
        std::memset(A + j * N, 0, sizeof(double) * N); // e.g. @llvm.memset

Later, the vectorizer sees this code and decides to bail out because it cannot
vectorize the inserted call to @llvm.memset.

I have so many questions here :)


0.) The diagnostic that the vectorizer pass remarks give is not very helpful:
'call instruction cannot be vectorized', BUT the source location it points to
isn't a call - it's the users original code. Many users may not divine the fact
that loop-idiom replacement occured and end up fruitfully trying to figure out
why assignment to double (the source location pointed to) is a call that cannot
be vectorized. At the very least, the pass remark (emitted from here:
https://github.com/llvm-mirror/llvm/blob/master/lib/Transforms/Vectorize/LoopVectorize.cpp#L5422)
could give the name of the function in the function call that could not be
vectorized (which I assume would be something like "memset" or "@llvm.memset"
in this case).


1.) Why is there not a vector version of @llvm.memset in addition to the scalar
version? Is this a problem with the underlying C library on my target (x86
Linux)?


2.) Why does the vectorizer give up when it encounters a scalar function call?
If the function is noexcept, it should be able to take something like this:

    // Assume A is an cache-line aligned double* __restrict__
    // and N is divisible by some nice number, say 32. 
    for (ptrdiff_t i = 0; i != N; ++i)
    {
        double tmp = scalar_noexcept_f(i);
        A[i] += B[i] * tmp;
    }

And turn it into something like this:

    // Assume A is an cache-line aligned double* __restrict__
    // and N is divisible by some nice number, say 32. 
    for (ptrdiff_t i = 0; i != N; i += 8)
    {
        // Vectorize "around" the scalar call.
        __m512d tmp = _mm512_set_pd(
            scalar_noexcept_f(i)
          , scalar_noexcept_f(i+1)
          , scalar_noexcept_f(i+2)
          , scalar_noexcept_f(i+3)
          , scalar_noexcept_f(i+4)
          , scalar_noexcept_f(i+5)
          , scalar_noexcept_f(i+6)
          , scalar_noexcept_f(i+7)
        );

        _mm512_store_pd(
            A + i
          , _mm512_fmadd_pd(
                _mm512_load_pd(A + i)
              , _mm512_load_pd(B + i)
              , tmp
            )
        );
    }


3.) Why isn't loop-idiom recognition "nested loop aware"? In this case, my
nested loops could be turned into a single memset.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170429/e6f836c0/attachment.html>


More information about the llvm-bugs mailing list