Почему g cc производит эту странную сборку против clang? - PullRequest
2 голосов
/ 16 февраля 2020

Я пытался выяснить разницу между g cc и clang и как они справляются std::vector. Может кто-нибудь с большим знанием объяснить, почему g cc и clang производят такой разный выход?

g cc 9.2: https://godbolt.org/z/AFN46d clang 9.0: https://godbolt.org/z/kEkpWE

Программа:

#include <vector>

int foo(int a) {
    auto vec = std::vector<int>{};
    vec.push_back(1);
    vec.push_back(2);
    return vec[1] * a;
}
int main () {
    return foo(5) + foo(4);
}

clang производит довольно понятную сборку. Тем не менее, g cc производит такие странные вещи:

void std::vector<int, std::allocator<int> >::_M_realloc_insert<int>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int&&):
        movabs  rcx, 2305843009213693951
        push    r15
        push    r14
        push    r13
        push    r12
        push    rbp
        push    rbx
        sub     rsp, 24
        mov     r12, QWORD PTR [rdi+8]
        mov     r8, QWORD PTR [rdi]
        mov     rax, r12
        sub     rax, r8
        sar     rax, 2
        cmp     rax, rcx
        je      .L16
        mov     r15, rdx
        mov     rdx, rsi
        mov     rbp, rdi
        mov     r13, rsi
        sub     rdx, r8
        test    rax, rax
        je      .L11
        movabs  r14, 9223372036854775804
        lea     rsi, [rax+rax]
        cmp     rax, rsi
        jbe     .L17

Откуда берутся эти маги c числа?

1 Ответ

2 голосов
/ 16 февраля 2020

G CC пытается быть в безопасности и испускает некоторые дополнительные проверки. Первая константа, которую вы видите, это просто

__gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(int)

и представляет собой максимально возможный размер вектора целых чисел на x86-64.

Вторая константа выглядит просто

__gnu_cxx::__numeric_traits<ptrdiff_t>::__max

округлено до деления на sizeof(int).

В общем, эти вещи происходят из различных max_size() методов в libstdc ++. Вполне возможно, что clang способен доказать, что некоторые проверки не нужны.

...