Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Passing by value to inlined function inhibits optimisation when it should not #37186

Open Quuxplusone opened 6 years ago

Quuxplusone commented 6 years ago
Bugzilla Link PR38213
Status NEW
Importance P normal
Reported by Niall Douglas (s_bugzilla@nedprod.com)
Reported on 2018-07-18 11:40:08 -0700
Last modified on 2018-07-19 18:15:03 -0700
Version trunk
Hardware PC Linux
CC vittorio.romeo@outlook.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
#include <string>

inline size_t calc(std::string a, std::string b)
{
    return a.size() + b.size();
}

int main()
{
    std::string a = "Hello world", b = "Goodbye world";
    return calc(a, b);
}

This should generate:

main:                                   # @main
        mov     eax, 24
        ret

But it instead generates this spew with clang trunk:

https://godbolt.org/g/2nU993
Quuxplusone commented 6 years ago

Added data points:

The GCC bug tracker found that GCC trunk when in C++ 11 or C++ 14 mode compiles the below to the single instruction. See https://godbolt.org/g/TPBHhH. However, in C++ 17 or later mode, you get spew like with clang.

I've asked them if they think the cause is libstdc++, or GCC. I'll come back with an answer when I know.

Quuxplusone commented 6 years ago

So, in C++ 17 and later, libstdc++'s string implementation does not use extern templates like it does in C++ 14 and below. This causes GCC's optimiser to give up when it should not.

clang generates spew for any language edition. It should generate the exact one instruction, same as GCC.