https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99091
Bug ID: 99091 Summary: constexpr variable evaluated at runtime Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: barry.revzin at gmail dot com Target Milestone: --- Consider the following (link to compiler explorer: https://godbolt.org/z/jWsxsK) #include <array> static constexpr auto doy = []{ std::array<int, 13> month_offset{}; for (int m=1; m<=12;++m) { month_offset[m] = (153*(m > 2 ? m-3 : m+9) + 2)/5; } return month_offset; }(); auto foo(int m) -> int { #ifdef LOCAL constexpr auto doy = []{ std::array<int, 13> month_offset{}; for (int m=1; m<=12;++m) { month_offset[m] = (153*(m > 2 ? m-3 : m+9) + 2)/5; } return month_offset; }(); #endif return doy[m]; } This is a fragment of code that does some calculation to figure out the date, which isn't super important. If LOCAL is not defined (i.e. we declare the array as a namespace-scope constexpr), the -O3 codegen of 'foo' is: foo(int): movsx rdi, edi mov eax, DWORD PTR doy[0+rdi*4] ret However, if we want to move the declaration of doy to be more local to the calculation and compile with -DLOCAL, the codegen instead is (on -O3): foo(int): pxor xmm0, xmm0 mov rax, QWORD PTR .LC0[rip] movsx rdi, edi mov DWORD PTR [rsp-24], 275 movaps XMMWORD PTR [rsp-72], xmm0 movdqa xmm0, XMMWORD PTR .LC1[rip] mov QWORD PTR [rsp-68], rax movaps XMMWORD PTR [rsp-56], xmm0 movdqa xmm0, XMMWORD PTR .LC2[rip] movaps XMMWORD PTR [rsp-40], xmm0 mov eax, DWORD PTR [rsp-72+rdi*4] ret This can be alleviated by marked the local variable doy as being static constexpr. Except that this prevents 'foo' from being a constexpr function (can't have static variables). This just seems like bad codegen, I'm not sure there's any reason that the compiler needs to do work here. It would be nice if the codegen with a local constexpr variable were the same as if it were a non-local constexpr variable.