Why are local function pointer calls not optimized away in C?

Viewed 87

Playing with compiler explorer I found that local function pointer calls were not be optimized away :

static int action1(void) { return 1; }
static int action2(void) { return 2; }
int test(int x) {
   int (*const action)() = x > 5 ? action1 : action2;
   return 1 + action();
}

// yielded :

action1():
       mov     eax, 1
       ret
action2():
       mov     eax, 2
       ret
test(int):
       sub     rsp, 8
       mov     edx, OFFSET FLAT:action2()
       cmp     edi, 5
       mov     eax, OFFSET FLAT:action1()
       cmovle  rax, rdx
       call    rax
       add     rsp, 8
       add     eax, 1
       ret

However:

int test2(void) { return test(6); }

// yields

test2:                                  # @test2
        mov     eax, 2
        ret

Suggesting the results of the action call can be determined at compile time.

The behavior seems to be the same on x86 gcc 10.2 as well as clang 11.0 (-O2).

Q0) Is there some reason that optimizing away the function pointer call can't be done?

Q1) If it can be done is there some reason it's not ?

Q2) And perhaps more importantly, how do I write something like this, but have it inline action1 and action2 :

static int testHelper6(int x, int callback(int)) {
    return 1 + callback(x);
}
int test6(int x) {
    return testHelper6(x, x > 5 ? action1 : action2);
}
0 Answers
Related