5

I'm expecting std::pair and std::tuple have the similar behavior. But it turns out that std::tuple generates worse asm code then std::pair.

https://gcc.godbolt.org/z/Ri4M8z - gcc 10.0.0 nightly build, -O3 -std=c++17
compiling for the x86-64 System V ABI

#include <utility>

std::pair<long, long> test_pair() {
    return { 1, 2 };
}
# returned in RDX:RAX
test_pair():
        mov     eax, 1
        mov     edx, 2
        ret

#include <tuple>
std::tuple<long, long> test_tuple() {
    return { 1, 2 };
}
# returned via hidden pointer, not packed into registers
test_tuple():
        mov     QWORD PTR [rdi], 2
        mov     QWORD PTR [rdi+8], 1
        mov     rax, rdi
        ret

Those two functions both return two values. test_pair uses registers to store values which is expected; but test_tuple stores values on stack, which seems unoptimise. Why these two functions behave differently?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Carter Li
  • 149
  • 12
  • in which program did you test that? – OznOg Jun 09 '19 at 16:22
  • 4
    One of them is trivially copyable, the other isn't, leading to special treatment in the ABI. :( The compiler doesn't have a choice here (other than modifying the C++ ABI). Normally this goes away with inlining, but it will apply any time you return a tuple or pair. – Peter Cordes Jun 09 '19 at 16:28
  • std::optional is more strange. https://gcc.godbolt.org/z/LQBYw2 gcc 9.1 tries to save stack frame which is unnecessary in my opinion. gcc 7.4 won't do it either. Is it a bug? – Carter Li Jun 09 '19 at 16:29
  • @JesperJuhl > make sure to build with your compilers optimizer enabled Of course. See my attached link – Carter Li Jun 09 '19 at 16:31
  • [GCC/Clang x86_64 C++ ABI mismatch when returning a tuple?](https://stackoverflow.com/q/37457443/995714) – phuclv Jun 24 '19 at 15:57

0 Answers0