<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/92924>92924</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Large variations in compilation times involving static_assert
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          pkeir
      </td>
    </tr>
</table>

<pre>
    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:

```cpp
static_assert(0==big_calc()); // (1)
```

..or:

```cpp
constexpr int ret = big_calc(); // (2)
static_assert(0==ret);
```

Surprisingly, the first of these (1) runs around 49% slower than the second (2).

```cpp
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 23.10 with an Intel i9-13900K, and Clang 17.0.2. With `n` of `big_calc` set at `(1<<22)` (as above) average compilation times are 7.5 secs. for approach (1); and 5.0 secs. for approach (2).

With `n` of `big_calc` set at `(1<<24)` average compilation times are 29.7 secs. for approach (1); and 19.8 secs. for approach (2).

`$ time clang++-17 -std=c++20 -fconstexpr-steps=$((2**32-1)) double-constant-eval.cpp`

Other approaches (e.g. SFINAE/Concepts class/function templates) are also slow; and have the performance profile of method (1).

GCC behaves similarly (with 43% performance drop).

My suspicion is that 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 performance profile flips: now (1) is quicker than (2).

While such long constexpr calculations are unusual, it would be a pity if third-party benchmarks didn't take such effects into account.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJycVstu6zYQ_Rp6M7AgUfJr4UXi1EXQ1-K26PKCokYSG4pU-bCbfn0xlOzEvo_eFjAS2SLPHJ45M0PhveoM4p6tHtnqaSFi6K3bjy-o3KK2zev-GWwb0MBZmADBQo3go0MIvQggDOBfo0PvlTWgPOBJ6CgCNiACSDuMSiMENSDjBzj39E1ob0H2KF-U6SYYFWB0tokSPYQeCRMlgRAaZvC7Cj0IYOtcWuMDhWTrHNpoZKDAUmiNDb2vVfdRCi3ZOqeIV6BgwWGIzsDf6Cy9eoZBdX0AVKFHB9EjKx9Y_sTyy991Pn3kOE6_-CCCkh-F9-gC49uclU-sfLrG5FvGd_QpH4HxI-NHYHxb0C-3iO_DZJl1_xr5emxQJtBJgJVPcBf4Jiq_Rv0Ca4dh2vQVbh-iG53yynT6lTSj3LTK-QC2pS8eLwcEF40H4Ww0DVQ7xlfgtT2jowSbtNGjtKa5cMv-y4HvDjrt2czMAbQ1HagkSUE0pY1mUiiZwKTHRLQ8sPLA-c3BZ5DWOlpDKhLUAUx6ZPwxfXaXdfAOfn7itO4Or7ZWQ_1-VVKdQihg_GF6WEIxWYYyB_wTUrNn87cXm6ev5OvXXnmqwuAiAp6oans0d3UBypysPqGHwTqk2pFRC6ojn8EziAEiZRx-q6MJEXiZFTmcUwUaeDYBNajdsih3ef4DyStMAwctTAfFJsszPpcrW-eGotn2Pr7HQN0hlehtTtY5ySI8iNqekGQRJ3Siw7mVJJapnZDXEDbZimzls5Q9MY7OCtlfi658TORWWf6FVZ8Y8f8wr2bmX6fKd9nmG7gWu2z7rWQTjSrFAEkJmLy6LDaw9KFh5ZOcfuE5LNtrRS19wNGTHYn6dkJ-YPyh5MuLGxsba43LtEeYsKS2nlFx3vrtl9Q6LyTRE03Mugw-HJ9_fviO8ePBGolj8ETQe8aP154dcBi1COhTmt08F6hpXLToxQlT5xjRtdYNwkikOdHSFLEtDBh621wUvJHm-8MBaiQAD14NSgunX2ll8nFVUn96j9o4O95j_PQKPvpRyXm0pUlFdC6q3I2-Gqlq3gZgOCuJN4jPARqLHrS1L2Cb5g3yzmdXkab692loZZDK-yw8OKRZ2UDr7AACtHAdOpKm1jhkcIhO2einnq0-cbEiI4jmCi5Ss0JhUk_KMEsbkrt2lwKfSc6zg1BG4dIYQLLnFyRxONgTNpfR8bk8tlqRGR_A2PN1mCgPf0YlXy7j47Olmi4TPsp-6v9vE-N9R0vOiib6KHRSI8DZRt3QNUbAqMIrCRR65ZolnegVajSyH4R78dCoxjC-CRDEyxwK2xZl8DSVLAiZWnu2aPZlsyt3YoH7YlOsy7zaVutFv-coNuvVSmBR7cq65ViXm0I2W1GVbbHCeqH2POdVvuJFseJ5tc4KLJqyKrfbbS7EaiVZleMglM60Pg2Zdd1CeR9xv-M7Xi20qFH7dHfj3OAZ0kvGOV3l3J72LOvYeVblWvng31CCChr3P5Jx4CScmtVS5jPta5oXZO6bq8QiOr3vQ0jpmy4enQp9rDNpB8aPFGv-txyd_QNlYPyYGFIjSCf4JwAA__-jAjZz">