https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92077

            Bug ID: 92077
           Summary: Multiple independent functions degrades optimizations
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: stinkingmadgod at gmail dot com
  Target Milestone: ---

#include<string>

auto f()
{
    std::string s1 = "abcdefg";
    std::string s2 = "12345678";
    return (s1 + s2).size();
}

#ifdef G
auto g()
{
    std::string s1 = "abcdefg";
    std::string s2 = "1234567";
    return (s1 + s2).size();
}
#endif

Discovered on godbolt.org/z/6BTbMk, with target x86_64-linux-gnu built on
20191011. The definition of g() heavily influences assembly for f(). I assume
that this shouldn't happen in any case, hence the report.

AFAIK the optimization on f() is dependent on SSO.

g++ -std=c++2a -O2 gives:
f():
        mov     eax, 15
        ret

g++ -std=c++2a -O2 -DG gives:
f():
        push    r12
        mov     eax, 26213
        push    rbp
        push    rbx
        sub     rsp, 96
        mov     WORD PTR [rsp+20], ax
        lea     rbx, [rsp+16]
        lea     rbp, [rsp+48]
        mov     rsi, rsp
        lea     rdx, [rsp+32]
        lea     rdi, [rsp+64]
        mov     QWORD PTR [rsp], rbx
        movabs  rax, 4050765991979987505
        mov     DWORD PTR [rsp+16], 1684234849
        mov     BYTE PTR [rsp+22], 103
        mov     QWORD PTR [rsp+8], 7
        mov     BYTE PTR [rsp+23], 0
        mov     QWORD PTR [rsp+32], rbp
        mov     QWORD PTR [rsp+48], rax
        mov     QWORD PTR [rsp+40], 8
        mov     BYTE PTR [rsp+56], 0
        call    std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > std::operator+<char, std::char_traits<char>,
std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)
        mov     rdi, QWORD PTR [rsp+64]
        lea     rax, [rsp+80]
        mov     r12, QWORD PTR [rsp+72]
        cmp     rdi, rax
        je      .L69
        mov     rax, QWORD PTR [rsp+80]
        lea     rsi, [rax+1]
        call    operator delete(void*, unsigned long)
.L69:
        mov     rdi, QWORD PTR [rsp+32]
        cmp     rdi, rbp
        je      .L70
        mov     rax, QWORD PTR [rsp+48]
        lea     rsi, [rax+1]
        call    operator delete(void*, unsigned long)
.L70:
        mov     rdi, QWORD PTR [rsp]
        cmp     rdi, rbx
        je      .L68
        mov     rax, QWORD PTR [rsp+16]
        lea     rsi, [rax+1]
        call    operator delete(void*, unsigned long)
.L68:
        add     rsp, 96
        mov     rax, r12
        pop     rbx
        pop     rbp
        pop     r12
        ret
        mov     rbp, rax
        jmp     .L72

Reply via email to