https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91158

            Bug ID: 91158
           Summary: "if (__builtin_constant_p(n))" versus "if constexpr
                    (__builtin_constant_p(n))"
           Product: gcc
           Version: 9.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: cassio.neri at gmail dot com
  Target Milestone: ---

Consider:

constexpr bool f0(int n) {
    if (__builtin_constant_p(n))
        return true;
    return false;
    // Alternatively:
    // return __builtin_constant_p(n) ? true : false;
    // return __builtin_constant_p(n);
}
constexpr bool f1(int n) {
    if constexpr (__builtin_constant_p(n))
        return true;
    return false;
}
static_assert( f0(1));
static_assert( f1(1)); // gcc 9.1 fails

I would expect both static_asserts to pass, that is, I would expect no
difference in behaviour between f0 and f1. (FWIW, for gcc 9.1, -O0, -O1, -O2
and -O3 all behave the same.)

This might be an issue with different moments where 'if constexpr' and
__builtin_constant_p are evaluated. (Similarly to bug 19449 comment 2.) In any
case, I find f1 very misleading. My real use case is like

if (__builtin_constant_p(n))
    // efficient code
else
    // less efficient code

However, branching at runtime is unacceptable and, if the compiler does not
know the value of n it's preferable to drop the 'if-else' altogether and live
with the less efficient code. Willing to avoid branching at runtime is a big
hint for using 'if constexpr' but, as things stand, this implies *never* using
the more efficient code.

Although a regular 'if' does what I want, I don't get the assurance that 'if
contexpr' provides about no branching at runtime. Instead, I need to rely on
the optimizer rather than on the semantics of C++.

See also bug 54021.

Reply via email to