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
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.
mov edi, ediis to zero the top 32 bits ofrdiregister. (ediactually refers to the lower 32 bits ofrdi.)I plan to read more into these and update the answer once I gain a better understanding.