https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123214
Marco Ribeiro <speaktomarco at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |speaktomarco at gmail dot com
--- Comment #3 from Marco Ribeiro <speaktomarco at gmail dot com> ---
I bumped into the same (or just similar) issue today, and found out that it
gets worse when the local is const.
Same function, only the constness of std::optional differs (compiled under
-O3):
https://godbolt.org/z/Wv9KrK6cb
For the non-const case, gcc keeps the optional in registers, but in the const
case, it stores the optional on the stack and, instead of optimizing the branch
on the flag, it branches once, copies the optional to another stack slot, and
then branches again on the copied flag.
It looks worse in C++26 mode too: the same function goes from 29 instructions
at '-std=c++23' to 35 at '-std=c++26', on the same compiler
(see tab "C++23 vs C++26"). Maybe it is related to the libstdc++ 'optional<T&>'
changes (P2988R12).
clang generates the same code for both, so the const does not look semantically
relevant (see tab "gcc vs clang").
Found while optimizing a hot function with a cheap callee, where it cost
1.5x ~ 4.5x.
I can open a separate issue (with the reduced testcases) if the C++26 or
const part is considered a different bug.