https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82280
Bug ID: 82280 Summary: Missed optimization opportunity constexpr/inline data copy not elided Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: matt at godbolt dot org Target Milestone: --- Consider the C++ code: ``` #include <array> #include <algorithm> constexpr auto get_tokens() { return std::array<char, 53>{"This is my string of possible tokens to match."}; } struct S { #ifndef LOCAL static constexpr auto m_tokens = get_tokens(); #endif constexpr bool has_token(const char c) const { #ifdef LOCAL const constexpr auto m_tokens = get_tokens(); #endif for (const auto val : m_tokens) { if (val == c) { return true; } } return false; } }; int main(const int argc, const char *[]) { constexpr S s; return s.has_token(char(argc)); } ``` Compiled with `-O3 -std=c++1z`, the `m_tokens` is a struct-level static constexpr data member. Adding `-DLOCAL` makes it a const constexpr local variable within the `has_token` routine. When compiled with local, the result of the `get_tokens()` call is copied to stack, and is used from there. The copy introduces 10 instructions. Given that the source is immutable, the copy can be elided and the original data referred to instead. See, for example: https://godbolt.org/g/ZVZMi6 Clang avoids the copy (see https://godbolt.org/g/j5P8Uv - NB this is clang 5.0 with `-O2` to prevent some of its other optimizations from confusing the issue further).