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

--- Comment #4 from Jan Hubicka <hubicka at ucw dot cz> ---
And to answer the question about why GCC produces more code, it is
actually speculative devirtualization of the call.  GCC determines
the most likely target and inlines it.

foo_virtual(Aint*):

        # this tests whether the dynamic type uses
        # Aint::operator+=

        mov     rax, QWORD PTR [rdi]
        mov     rax, QWORD PTR [rax]
        cmp     rax, OFFSET FLAT:Aint::operator+=(A const&)
        jne     .L19

        # if so, this is inlined copy of operator +=

        push    rbx
        xor     ecx, ecx
        mov     edx, OFFSET FLAT:typeinfo for Aint
        mov     esi, OFFSET FLAT:typeinfo for A
        mov     rbx, rdi
        call    __dynamic_cast
        test    rax, rax
        je      .L20
        mov     eax, DWORD PTR [rax+8]
        add     DWORD PTR [rbx+8], eax
        pop     rbx
        ret

        # this is the fallback code in case devirtualizaiton
        # failed.

.L19:
        mov     rsi, rdi
        jmp     rax

-fno-devirtualize-speculatively will lead to same code as Clang does.
Honza

Reply via email to