Por que clang produz asm ineficiente com -O0 (para esta soma simples de ponto flutuante
Estou desmontando este código no llvm clang Apple LLVM versão 8.0.0 (clang-800.0.42.1):
int main() {
float a=0.151234;
float b=0.2;
float c=a+b;
printf("%f", c);
}
Compilei sem especificações -O, mas também tentei com -O0 (fornece o mesmo) e -O2 (na verdade calcula o valor e o armazena pré-computado)
A desmontagem resultante é a seguinte (removi as peças que não são relevantes)
-> 0x100000f30 <+0>: pushq %rbp
0x100000f31 <+1>: movq %rsp, %rbp
0x100000f34 <+4>: subq $0x10, %rsp
0x100000f38 <+8>: leaq 0x6d(%rip), %rdi
0x100000f3f <+15>: movss 0x5d(%rip), %xmm0
0x100000f47 <+23>: movss 0x59(%rip), %xmm1
0x100000f4f <+31>: movss %xmm1, -0x4(%rbp)
0x100000f54 <+36>: movss %xmm0, -0x8(%rbp)
0x100000f59 <+41>: movss -0x4(%rbp), %xmm0
0x100000f5e <+46>: addss -0x8(%rbp), %xmm0
0x100000f63 <+51>: movss %xmm0, -0xc(%rbp)
...
Aparentemente, está fazendo o seguinte:
carregando os dois flutuadores nos registradores xmm0 e xmm1 coloque-os na pilhaload um valor (não o que xmm0 tinha anteriormente) da pilha para xmm0 execute a adição. armazene o resultado de volta na pilhAcho ineficiente porque:
Tudo pode ser feito no registro. Não estou usando aeb mais tarde, portanto, poderia pular qualquer operação que envolva a pilhmesmo se quisesse usar a pilha, poderia economizar recarregar xmm0 da pilha se fizesse a operação com uma ordem diferentDado que o compilador está sempre certo, por que ele escolheu essa estratégi