Curious missed optimization of recursive constexpr function by Clang

Viewed 93

Today I wanted to test, how Clang would transform a recursive power of two function and noticed that even with known exponent, the recursion is not optimized away even when using constexpr.

#include <array>
constexpr unsigned int pow2_recursive(unsigned int exp) {
    if(exp == 0) return 1;
    return 2 * pow2_recursive(exp-1);
}

unsigned int pow2_5() {
    return pow2_recursive(5);
}

pow2_5 is compiled as a call to pow2_recursive.

pow2_5():                             # @pow2_5()
        mov     edi, 5
        jmp     pow2_recursive(unsigned int)     # TAILCALL

However, when I use the result in a context that requires it to be known at compile time, it will correctly compute the result at compile time.

unsigned int pow2_5_arr() {
    std::array<int, pow2_recursive(5)> a;
    return a.size();
}

is compiled to

pow2_5_arr():                        # @pow2_5_arr()
        mov     eax, 32
        ret

Here is the link to the full example in Godbolt: https://godbolt.org/z/fcKef1

So, am I missing something here? Is there something that can change the result at runtime and a reason, that pow2_5 cannot be optimized in the same way as pow2_5_arr?

0 Answers
Related