[clang] [libc] [llvm] [clang] Make __builtin_exp and __builtin_expf constexpr. (PR #199808)

via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 12 20:28:43 PDT 2026


lntue wrote:

@hubert-reinterpretcast @jcranmer-intel : I got the following table summarizing Fold/No-Fold behaviors in various situations as follow:

| Precedence & Controlling Rule | `opOK`<br>*(Exact, e.g. `exp(0) = 1`)* | `opInexact`<br>*(Inexact, e.g. `exp(1)`)* | `opUnderflow`<br>*(Range error, e.g. `exp(-88f)`)* | `opOverflow`<br>*(Range error, e.g. `exp(100f)`)* | `opDivByZero`<br>*(e.g. `1.0 / 0.0`, `log(0)`)* | `opInvalidOp`<br>*(e.g. `0.0 / 0.0`, `sqrt(-1)`)* |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: |
| **1. Constant Context (`constexpr`, `static_assert`)**<br>*(All rounding modes: default or `#pragma STDC FENV_ROUND`)* | **Fold** | **Fold**<br>*(allowed by `[library.c]p3`)\** | **No Fold**<br>*(prohibited by `[library.c]p3`)* | **No Fold**<br>*(prohibited by `[library.c]p3`)* | **No Fold**<br>*(prohibited by `[library.c]p3`)* | **No Fold**<br>*(prohibited by `[library.c]p3`)* |
| **2. Global / Static Initializers (C17 ยง7.6.1p2)**<br>*(Evaluated at translation time under default FP settings)* | **Fold** | **Fold**<br>*(bypasses strict FENV)* | Depends on `-fmath-errno`<br>*(No Fold if errno)* | Depends on `-fmath-errno`<br>*(No Fold if errno)* | **Fold** (arithmetic)<br>Depends on `-fmath-errno` (builtins) | **Fold** (arithmetic)<br>Depends on `-fmath-errno` (builtins) |
| **3. Runtime: `#pragma STDC FENV_ACCESS ON`**<br>*(or `-ffp-model=strict`, `-ffp-exception-behavior=strict`)* | **Fold**<br>*(no exceptions raised; exact)* | **No Fold**<br>*(must raise `FE_INEXACT`)* | **No Fold**<br>*(must raise `FE_UNDERFLOW`)* | **No Fold**<br>*(must raise `FE_OVERFLOW`)* | **No Fold**<br>*(must raise `FE_DIVBYZERO`)* | **No Fold**<br>*(must raise `FE_INVALID`)* |
| **4. Runtime: `#pragma STDC FENV_ROUND FE_DYNAMIC`**<br>*(Local block pragma overriding TU defaults)* | **Fold**<br>*(independent of RM)* | **No Fold**<br>*(result depends on dynamic RM)* | **No Fold**<br>*(depends on dynamic RM + errno)* | **No Fold**<br>*(depends on dynamic RM + errno)* | **Fold** (arithmetic)<br>Depends on `-fmath-errno` (builtins) | **Fold** (arithmetic)<br>Depends on `-fmath-errno` (builtins) |
| **5. Runtime: `#pragma STDC FENV_ROUND FE_TONEAREST`**<br>*(Local pragma overriding `-frounding-math`)* | **Fold** | **Fold**<br>*(guaranteed `tonearest`)* | Depends on `-fmath-errno`<br>*(No Fold if errno)* | Depends on `-fmath-errno`<br>*(No Fold if errno)* | **Fold** (arithmetic)<br>Depends on `-fmath-errno` (builtins) | **Fold** (arithmetic)<br>Depends on `-fmath-errno` (builtins) |
| **6. Runtime: `-frounding-math`**<br>*(TU-level dynamic rounding default)* | **Fold**<br>*(independent of RM)* | **No Fold**<br>*(result depends on dynamic RM)* | **No Fold**<br>*(depends on dynamic RM)* | **No Fold**<br>*(depends on dynamic RM)* | **Fold** (arithmetic)<br>Depends on `-fmath-errno` (builtins) | **Fold** (arithmetic)<br>Depends on `-fmath-errno` (builtins) |
| **7. Runtime: `-fmath-errno`**<br>*(TU default on Linux/glibc with default RM)* | **Fold**<br>*(exact; `errno` not set)* | **Fold**<br>*(non-range; `errno` not set)* | **No Fold**<br>*(must write `errno = ERANGE`)* | **No Fold**<br>*(must write `errno = ERANGE`)* | **Fold** (arithmetic)<br>**No Fold** (math builtins: `ERANGE`) | **Fold** (arithmetic)<br>**No Fold** (math builtins: `EDOM`) |
| **8. Runtime: `-fno-math-errno`**<br>*(Default RM, ignore exceptions, ignore errno)* | **Fold** | **Fold** | **Fold**<br>*(folds to denormal or `0.0`)* | **Fold**<br>*(folds to `+inf`)* | **Fold**<br>*(folds to `inf`)* | **Fold**<br>*(folds to `NaN`)* |
| **9. Runtime: `-ffast-math`**<br>*(Unconstrained math optimizations)* | **Fold** | **Fold** | **Fold** | **Fold** | **Fold** | **Fold** |

*\*Note: Directed rounding modes in `constexpr` currently fail evaluation with `note_constexpr_unsupported_rounding` until implemented in `llvm::APFloat::exp`.*

And I tried to add the tests to cover them as much as possible.
Can you take a look to see if I understand them correctly?  Thanks,

https://github.com/llvm/llvm-project/pull/199808


More information about the cfe-commits mailing list