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).

Reply via email to