https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87090
Bug ID: 87090
Summary: Constexpr variables in functions are not optimized
correctly
Product: gcc
Version: 8.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: jeanmichael.celerier at gmail dot com
Target Milestone: ---
Consider the following code :
#include <string_view>
#include <array>
struct Table
{
long long tab[128];
constexpr Table()
: tab {}
{
tab['0'] = 0;
tab['1'] = 1;
tab['2'] = 2;
tab['3'] = 3;
tab['4'] = 4;
tab['5'] = 5;
tab['6'] = 6;
tab['7'] = 7;
tab['8'] = 8;
tab['9'] = 9;
tab['a'] = 10;
tab['A'] = 10;
tab['b'] = 11;
tab['B'] = 11;
tab['c'] = 12;
tab['C'] = 12;
tab['d'] = 13;
tab['D'] = 13;
tab['e'] = 14;
tab['E'] = 14;
tab['f'] = 15;
tab['F'] = 15;
}
constexpr auto operator[](const std::size_t idx) const { return tab[idx];
}
} constexpr t;
constexpr auto conv(std::size_t number)
{
return t[number];
}
std::array<long long, 4> res;
void convert(std::string_view hex)
{
res[0] = (conv(hex[1]));
res[1] = (conv(hex[3]));
res[2] = (conv(hex[5]));
res[3] = (conv(hex[7]));
}
When benchmarking it (calling the `convert("#00ABCDEF")` function a few million
times from another translation unit), I get the following numbers consistently
:
g++-8.2.0 : 8-9 nanoseconds per call
clang++-6.0.1 : 8-10 nanoseconds per call
Now, if I want to put the table inside the conv function to keep it in a small
scope, such as this :
constexpr auto conv(std::size_t number)
{
struct Table
{
long long tab[128];
constexpr Table()
: tab {}
{
tab['0'] = 0;
tab['1'] = 1;
tab['2'] = 2;
tab['3'] = 3;
tab['4'] = 4;
tab['5'] = 5;
tab['6'] = 6;
tab['7'] = 7;
tab['8'] = 8;
tab['9'] = 9;
tab['a'] = 10;
tab['A'] = 10;
tab['b'] = 11;
tab['B'] = 11;
tab['c'] = 12;
tab['C'] = 12;
tab['d'] = 13;
tab['D'] = 13;
tab['e'] = 14;
tab['E'] = 14;
tab['f'] = 15;
tab['F'] = 15;
}
constexpr auto operator[](const std::size_t idx) const { return
tab[idx]; }
} constexpr t;
return t[number];
}
I get the following numbers :
clang++-6.0.1 : 8-10 nanoseconds per call (no changes)
g++-8.2.0 : 120-150 nanoseconds per call, more than ten times slower !
I tested for both compiles at -O2 and -O3 without observable changes.
If I make the "conv" function itself non-constexpr, and mark the table as
static constexpr, I get my performance back - I guess that even while constexpr
the table must be initialized each time ?