Why does GCC use "mov edi, edi" for this unsigned integer to double conversion but not for signed?

310 Views Asked by At

When compile(x86-64 gcc 11.2 with -O2) the code below:


double foo(unsigned int x) {
    return x/2.5;
}

double zoo(int x) {
    return x/2.5;
}

int main(){
    return 0;
}

I got the assembly like this:

foo(unsigned int):
        mov     edi, edi
        pxor    xmm0, xmm0
        cvtsi2sd        xmm0, rdi
        divsd   xmm0, QWORD PTR .LC0[rip]
        ret
zoo(int):
        pxor    xmm0, xmm0
        cvtsi2sd        xmm0, edi
        divsd   xmm0, QWORD PTR .LC0[rip]
        ret
main:
        xor     eax, eax
        ret
.LC0:
        .long   0
        .long   1074003968

Why does GCC insert mov edi, edi for the function doing floating-point division on an unsigned int but not for the signed one?

CodeLink: https://gcc.godbolt.org/z/f1hKGrW6T

1

There are 1 best solutions below

1
Niket On

I am not well-versed in this field, but this interesting question urged me to google around and it is such a fascinating spiral. Let me share my findings.

  • The purpose of mov edi, edi is to zero the top 32 bits of rdi register. (edi actually refers to the lower 32 bits of rdi.)
  • Why it happens: 32-bit operands generate a 32-bit result, zero-extended to a 64-bit result in the destination general-purpose register. (http://x86asm.net/articles/x86-64-tour-of-intel-manuals/)
  • Why was this behaviour introduced: to avoid partial register stall

Partial register stall is a problem that occurs when we write to part of a 32-bit register and later read from the whole register or a bigger part of it.
They cause performance penalty (Why doesn't GCC use partial registers?)

  • Why is this relevant to our question? I do not 100% understand the reason but here is what I found:

Since an n-bit bitstring can be interpreted semantically both as an unsigned as well as signed integer, we use sign extension to make things clear. (https://cs.stackexchange.com/questions/81320/signed-and-unsigned-loads-in-a-32-bit-registers)

I plan to read more into these and update the answer once I gain a better understanding.