Issue |
154702
|
Summary |
Clang should inline pointers-to-members more aggresively with ranges
|
Labels |
clang
|
Assignees |
|
Reporter |
NamorNiradnug
|
Consider the following example:
```c++
struct Foo {
bool meow;
std::vector<bool> boos;
};
bool Bar(const std::vector<Foo>& foos) {
return std::ranges::any_of(
foos
| std::views::filter(&Foo::meow)
| std::views::transform(&Foo::boos)
| std::views::join,
std::identity{}
);
}
```
Clang doesn't inline the `any_of` and call it instead of inlining it:
```asm
Bar(std::vector<Foo, std::allocator<Foo>> const&):
sub rsp, 40
mov qword ptr [rsp + 8], rdi
mov qword ptr [rsp + 16], 0
mov qword ptr [rsp + 24], -1
mov qword ptr [rsp + 32], 8
lea rdi, [rip + std::ranges::any_of]
lea rsi, [rsp + 8]
call bool std::ranges::__any_of_fn::operator()<std::ranges::join_view<std::ranges::transform_view<std::ranges::filter_view<std::ranges::ref_view<std::vector<Foo, std::allocator<Foo>> const>, bool Foo::*>, std::vector<bool, std::allocator<bool>> Foo::*>>, std::identity, std::identity>(T&&, std::identity, T0) const
add rsp, 40
ret
```
But after changing even one of `&Foo::meow` or `&Foo::boos` to a lambda `Bar` gets inlined:
```c++
bool BarInlined(const std::vector<Foo>& foos) {
return std::ranges::any_of(
foos
| std::views::filter([] (const auto& foo) { return foo.meow; })
| std::views::transform(&Foo::boos)
| std::views::join,
std::identity{}
);
}
bool BarAlsoInlined(const std::vector<Foo>& foos) {
return std::ranges::any_of(
foos
| std::views::filter(&Foo::meow)
| std::views::transform([] (const auto& foo) -> const auto& { return foo.boos; })
| std::views::join,
std::identity{}
);
}
```
GCC inlines the `any_of` for all the examples.
Godbolt: https://godbolt.org/z/z6qq87YTd
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs