https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115639
Bug ID: 115639 Summary: Large variations in compilation times involving static_assert Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: pkeir at outlook dot com Target Milestone: --- I often want to be sure that an expression is evaluated at compile time, while also checking that it produces the expected value. With a `constexpr` function called `big_calc`, expected to return zero, I might either use: static_assert(0==big_calc()); // (1) ...or: constexpr int ret = big_calc(); // (2) static_assert(0==ret); Surprisingly, the first of these (1) takes around 76% longer than the second (2) to compile. constexpr int big_calc() { long i = 1, count = 0, n = (1<<22); for (; i < n; i++) count = count + i; bool b = count == (i * (i - 1)) / 2; return 0; } This is true even when `big_calc` involves more calculations. I am using Ubuntu 24.04 with an Intel i9-13900K, and g++ (GCC) 15.0.0 20240623 (experimental). With `n` of `big_calc` set at `(1<<22)` (as above) average compilation times are 6.5 secs. for approach (1); and 3.7 secs. for approach (2). With `n` of `big_calc` set at `(1<<24)` average compilation times are 28.3 secs. for approach (1); and 16.2 secs. for approach (2). time /opt/gcc-latest/bin/g++ -std=c++20 performance-bug-double-constant-eval.cpp -fconstexpr-ops-limit=$((2**31-1)) -fconstexpr-loop-limit=$((2**31-1)) Other approaches to invoke `big_calc` (e.g. SFINAE/Concepts class/function templates) are also slow; and have the performance profile of method (1). Perhaps the constant expression is being evaluated twice. It does look odd that the `big_calc` function returns zero. This was reduced from a larger problem. Curiously, if `big_calc` instead returns a boolean (i.e. `b`), and the `0==` part of each constant expression is removed, the issue disappears. This is reminiscent of a recently resolved Clang issue (https://github.com/llvm/llvm-project/issues/92924), though with 2 notable differences: firstly, with GCC the problem only arises when the `big_calc` function is actually invoked; and secondly, the `-Wno-invalid-constexpr` flag makes no difference to the performance with GCC.