3 ms·
Interesting, this is a case where GCC and Clang are "dumb" and MSVC does a better job. For code #include <cstdlib> #include <cstdint> #include <utility>
by cpgxiii 1y ago
Interesting, this is a case where GCC and Clang are "dumb" and MSVC does a better job. For code
#include <cstdlib>
#include <cstdint>
#include <utility>
std::pair<int64_t, int64_t> LibDivWithRemainder(int64_t numerator, int64_t denominator) {
const auto res = std::div(numerator, denominator);
return std::make_pair(res.quot, res.rem);
}
std::pair<int64_t, int64_t> ManDivWithRemainder(int64_t numerator, int64_t denominator) {
const int64_t quot = numerator / denominator;
const int64_t rem = numerator % denominator;
return std::make_pair(quot, rem);
}
GCC (x86-64 trunk @ -O2) produces
"LibDivWithRemainder(long, long)":
sub rsp, 8
call "ldiv"
add rsp, 8
ret
"ManDivWithRemainder(long, long)":
mov rax, rdi
cqo
idiv rsi
ret
Clang (x86-64 @ -O2) produces
LibDivWithRemainder(long, long):
jmp ldiv@PLT
ManDivWithRemainder(long, long):
mov rax, rdi
mov rcx, rdi
or rcx, rsi
shr rcx, 32
je .LBB1_1
cqo
idiv rsi
ret
.LBB1_1:
xor edx, edx
div esi
ret
while MSVC (x64 @ /O2) produces
mov rax, rdx
cdq
idiv r8
mov QWORD PTR [rcx], rax
mov rax, rcx
mov QWORD PTR [rcx+8], rdx
ret 0
for both