Generated assembly code for returning std::optional<uint32_t>

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Under -O3 -std=c++17, the assembly code generated by gcc 11.2 for some
std::optional C++ code seems less optimal than I expect; it is writing the
content of optional<uint64_t> return values to both the stack and to the
RAX register. What am I missing? I was under the impression that return
values are put in RAX if they can fit. Why does gcc have to write the
return value to both the stack and RAX instead of just one of them? Can the
writing to the stack be avoided?

foo() & bar() return optional<uint32_t> and demonstrate this problem. baz()
returns int32_t and does not have the problem. bun(), which calls foo() and
bar(), accesses the optional<uint32_t> return value through RAX and not
through the stack, so it is evident that the stack value is redundant.

https://godbolt.org/z/Ef14n8EcM

C++ code:
#include <cstdint>
#include <optional>

using namespace std;

optional<uint32_t> foo() {
return 111;
}

optional<uint32_t> bar() {
return nullopt;
}

uint32_t baz() {
return 111;
}

bool bun(bool x) {
auto f = x ? foo : bar;
return f().has_value();
}

Generated assembly code:
foo():
mov DWORD PTR [rsp-8], 111
mov BYTE PTR [rsp-4], 1
mov rax, QWORD PTR [rsp-8]
ret
bar():
mov BYTE PTR [rsp-4], 0
mov rax, QWORD PTR [rsp-8]
ret
baz():
mov eax, 111
ret
bun(bool):
sub rsp, 24
mov edx, OFFSET FLAT:bar()
test dil, dil
mov eax, OFFSET FLAT:foo()
cmove rax, rdx
call rax
add rsp, 24
shr rax, 32
ret



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux