LINUX.ORG.RU

Почему компилятор тупит?

 , ,


0

4
#include <string.h>

int main(void)
{
    return strlen("123");
}

-O0
main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $3, %eax
        popq    %rbp
        ret

-O3
main:
        movl    $3, %eax
        ret

https://godbolt.org/g/qFO05n

#include <string.h>

int main(void) 
{  
   char ar[] = {"123"};
  
   return strlen(ar);
}

-O0
main:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $16, %rsp
        movq    %fs:40, %rax
        movq    %rax, -8(%rbp)
        xorl    %eax, %eax
        movl    $3355185, -16(%rbp)
        leaq    -16(%rbp), %rax
        movq    %rax, %rdi
        call    strlen
        movq    -8(%rbp), %rdx
        xorq    %fs:40, %rdx
        je      .L3
        call    __stack_chk_fail
.L3:
        leave
        ret

-O3
main:
        subq    $24, %rsp
        movq    %fs:40, %rax
        movq    %rax, 8(%rsp)
        xorl    %eax, %eax
        movl    $3355185, (%rsp)
        movq    %rsp, %rsi
        movq    %rsp, %rax
.L2:
        movl    (%rax), %ecx
        addq    $4, %rax
        leal    -16843009(%rcx), %edx
        notl    %ecx
        andl    %ecx, %edx
        andl    $-2139062144, %edx
        je      .L2
        movl    %edx, %ecx
        shrl    $16, %ecx
        testl   $32896, %edx
        cmove   %ecx, %edx
        leaq    2(%rax), %rcx
        cmove   %rcx, %rax
        addb    %dl, %dl
        sbbq    $3, %rax
        subq    %rsi, %rax
        movq    8(%rsp), %rdi
        xorq    %fs:40, %rdi
        jne     .L9
        addq    $24, %rsp
        ret
.L9:
        call    __stack_chk_fail

https://godbolt.org/g/WoC3bn

Понятно что в случае 2 на -О3 он догадался заинлайнить функцию. Но почему, видя, что массив нигде не используется он не сделал movl 3 как в случае 1?

Более того, стоит поменять количество символов на 2 - код сокращается на треть.

Но почему, видя, что массив нигде не используется он не сделал movl 3 как в случае 1?

Если выбрать gcc-4.9.0 и выше, то остается 2 инструкции. Если очень интересно посмотреть, где появилась разница - можно посмотреть в -fdump-tree-all / -fdump-rtl-all.

Можно забисектить до исправляющего коммита :)

sf ★★ ()