llvm / llvm/llvm-project

Statically known but dynamically selected functions are not inlined

Open
#211,678 0 comments 1 reaction 0 assignees View on GitHub
llvm:optimizations missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

This pattern prevents inlining (https://godbolt.org/z/G5bjTWGYK):

```llvm
define dso_local noundef i32 @foo() local_unnamed_addr {
entry:
ret i32 1
}

define dso_local noundef i32 @bar() local_unnamed_addr {
entry:
ret i32 2
}

define dso_local i32 @test(i32 noundef %b) local_unnamed_addr {
entry:
%tobool.not = icmp eq i32 %b, 0
%cond = select i1 %tobool.not, ptr @bar, ptr @foo
%call = tail call i32 %cond() #2
ret i32 %call
}
```

It does not matter if the function pointer is assigned using control flow + phi instead of select, as long as there is a single call node.

This can be reproduced both in C (https://godbolt.org/z/7d8sr6r4o):

```c
__attribute__((always_inline))
int foo() { return 1; }

__attribute__((always_inline))
int bar() { return 2; }

typedef int (*fptr)();

int test(int b) {
fptr f = b ? foo : bar;
return f();
}
```

and with virtual functions (https://godbolt.org/z/bP8cvTo4W):

```c++
struct A {
virtual int foo() = 0;
};

struct B : public A {
int foo() override { return 1; }
};

struct C : public A {
int foo() override { return 2; }
};

int test(bool pred) {
B b;
C c;
A *a = pred ? static_cast(&b) : static_cast(&c);
return a->foo();
}
```

Contributor guide

Open the contributing guide

Research direction

The LLVM IR, C, and C++ reproductions in the issue, via the linked Compiler Explorer cases, are the starting points. First reproduce the missed inlining, then trace the optimizer's handling of a single indirect call whose target comes from select/phi or virtual dispatch. Done means the shown statically known calls are inlined in generated output while preserving behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, cpp
Domain
compilers, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.