[llvm-bugs] [Bug 37449] New: clang++ fails to optimize variadic template constructor with fold expression

via llvm-bugs llvm-bugs at lists.llvm.org
Mon May 14 04:03:02 PDT 2018


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

            Bug ID: 37449
           Summary: clang++ fails to optimize variadic template
                    constructor with fold expression
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: -New Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: vittorio.romeo at outlook.com
                CC: llvm-bugs at lists.llvm.org

Consider the following wrapper around `std::vector`:

    #include <vector>

    struct init { };

    template <typename T>
    struct vec : std::vector<T>
    {
        using std::vector<T>::vector;

        template <typename... Xs>
        vec(init, Xs&&... xs) 
        {
            this->reserve(sizeof...(Xs));
            (this->emplace_back(std::forward<Xs>(xs)), ...);
        }
    };

When compiling the following code `clang++-trunk -Ofast -std=c++2a`...

    void foo() 
    {
    #ifndef VARIADIC
        vec<std::string> v;
        v.reserve(2);
        v.emplace_back("hello");
        v.emplace_back("world");
    #else
        vec<std::string> v{init{}, "hello", "world"};
    #endif
    }

...the variadic version produces roughly 5x more assembly instructions and is
around 46% slower at run-time.

Marking `vec`'s constructor as `__attribute__((always_inline))` makes both
versions produce the same assembly.

Live assembly comparison on godbolt.org:
https://godbolt.org/g/YwM86C

Live run-time benchmark on quick-bench.com:
http://quick-bench.com/C5_4Bm5Crsqg1ykE0YmoHFOwmLs

I think that this is a very reasonable/common usage of a variadic template
constructor + fold expression - it is surprising to me as a developer that
clang++ doesn't optimize this. This *should* be a better alternative in terms
of run-time performance to `std::initalizer_list`, which prevents moves and has
other significant drawbacks - it is disappointing to see `always_inline` being
required here.

-- 
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/20180514/9cbb6beb/attachment.html>


More information about the llvm-bugs mailing list