llvm / llvm/llvm-project

clang inline func arg eval is too eager

Open
#191,680 1 comment 0 reactions 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

On a call to an inline function, it is better to postpone the argument eval to the real using branch, g++ does it this way, but clang does not:

```c++
#include
#include
__attribute__((pure)) int fake_pure();
inline __attribute__((always_inline)) int foo(int cond, int x) {
if (cond)
return x*2;
else
return 0;
}
int main(int argc, char* argv[]) {
int cond = argc >= 2 && atoi(argv[1]);
return foo(cond, fake_pure());
}
// defined in another file such as fake_pure.cpp
// __attribute__((noinline)) int fake_pure() {
// printf("fake pure\n");
// return 1;
// }
```

In the above code, `fake_pure` is used to trigger argument eval eager(clang) or lazy(g++).
see: https://godbolt.org/z/j7cWEnKdj

This is useful in some other case such as postpone time consuming pointer chasing to the real usage branch:
```c++
#include
#include
struct A {
int x;
A* next;
};
__attribute__((pure)) A* get_a(); // defined in another source file
inline __attribute__((always_inline)) int foo(int cond, int x) {
if (cond)
return x*2;
else
return 0;
}
int main(int argc, char* argv[]) {
int cond = argc >= 2 && atoi(argv[1]);
return foo(cond, get_a()->next->next->next->next->x);
}
```
see: https://godbolt.org/z/668MfsM9n

Contributor guide

Open the contributing guide

Research direction

Reproduce the eager-versus-lazy behavior using the two C++ examples and the linked Compiler Explorer cases, comparing clang with g++. Start by tracing how clang handles argument evaluation when an always_inline function is inlined. Done means unused arguments are not evaluated on branches where the inlined function does not use them, while the shown behavior remains correct.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.