https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91158
--- Comment #3 from Cassio Neri <cassio.neri at gmail dot com> --- Forget my use case and comments on dead code elimination. That was a digression. (My bad.) In general, I don't expect `if` and `if constexpr` to behave the same but I do in this particular case. (I might be wrong.) Finally, since `__builtin_constant_p` is not standard this ticket is a feature request, not a bug report. My reasoning is this: when the compiler sees `static_assert(f1(1));` it enters a "constexpr evaluation mode" (not sure this is the right terminology but you get the point). At this moment, regardless of optimization level the compiler must propagate `1` to `f1` otherwise (generally speaking) it cannot evaluate `f1(1)` and decide whether the `static_assert` passes or not. Therefore, when it enters `f1` and sees `if constexpr (__builtin_constant_p(n))` it is already in "constexpr evaluation mode" (so `constexpr` here is redundant) and it knows `n == 1`. Hence, it should evaluate `__builtin_constant_p(n)` to `1`. To make clear that my point is not that `if` and `if constexpr` should always work the same, please, contrast with this program: int main() { if (f0(1)) puts("if : yes"); else puts("if : no"); if constexpr (f0(1)) puts("if ce: yes"); else puts("if ce: no"); } The output in -O0 mode is `if : no` and `if ce: yes`. Since the first `if` is not `constexpr`, the compiler doesn't need to enter "constexpr evaluation mode" and -O0 is too low for `1` to be propagated to `f0`. The second `if`, on the other hand, is `constexpr`. The compiler enters "constexpr evaluation mode", propagates `1` to `f0` and evaluates `if (__builtin_constant_p(n))` to `1` regardless that this `if` is not `constexpr`. Also, to make clear I'm OK with `if constexpr (__builtin_constant_p(n))` evaluating to `0` even in -O3 level, consider this: int main() { if (f0(1)) puts("if : yes"); else puts("if : no"); } The output is `if : no`. Since the `if` is not `constexpr`, constant propagation is up to the optimizer (QoI issue) and I'm OK if it enters "constexpr evaluation mode" only inside `f1` (when it sees `if constexpr (__builtin_constant_p(n))`) at which point is too late to know the value of `n` and considers `n` as non constant. Finally, I would link to link this issue with bug 70552 comment 5. Martin Sebor, commenting on a patch for another related issue says: "The patch referenced from it sets a precedent for the intrinsic treating constant expressions as constant despite its late evaluation under "normal" circumstances". IIUIC, it says that `__builtin_constant_p(expr)` always evaluates to `1` if expr is a C++ constant expression (e.g. a call to a `constexpr` function). Similarly, I believe that in "constexpr evaluation mode", almost every evaluation of `__builtin_constant_p(expr)` in the taken path should yield `1`. (There are exceptions, notably, when `expr` is a non `constexpr` local variable.)