<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/154702>154702</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Clang should inline pointers-to-members more aggresively with ranges
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          NamorNiradnug
      </td>
    </tr>
</table>

<pre>
    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
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzMVk1z4ygQ_TXoQtmFkfXhgw62Em_tZU657CmFBJKZQrQDyNnsr98CEdnr2NnszhwmpZRkeK_pppvXMGtlr4WoULZD2UPCRncAU31jA5hv0jCuxz5pgL9VNWgruTDYHQTuQCl4lbrH4k82HJVA6RaRLcrJ9LSI7vxDttaZsXV4D4BR4QcwxrgBUHgQ8IrSMGQd9wbS7Um0DgxKa49A6aNH2gmEiof4QbaBv2MG0bIFbd0NA3sAlD4imuPOm6Cb9-WNcKPRZ4Zhuhd2-mb67Rk6RMvop_8L9PNPVNQXq0nxGqmdVE54hxDNw9p-MIRIN1-gO8O07cAMVxaayXlv4R71O0iNaH2xyIySXGgn3ZsPvXiICG9u3tGLnE1bWyume8xBWI1o4bDUSmoRko5yEjcoJ5hpjlumFJYeY51gHEM3wX1dSHdVEswOiGynpN1OF72IjykFLftHKtNHHJKNaB5C2F5GPDbY2KM3sSYX4wOcwvvlFQzHR2cwynbGHjGiO1yi7MEzDJdfpazyyPnyInQdGYvVFeUmPKURflmCSrDw9o7SOsDlBP-sirOQ8JlrZ-5l-OdFQjLfz-ZNu8_Pk-XnTk8DcBQm5MjX7Aal9U2ar89nX6_3AHPtf4qaDtinECO6D_P_q8K8cNTTTswnEdFtHL-jVveMRynz1q-NXdmbj-vNQQ8un0L153dpT8RL3RTFObeM81gEH4-IEe6jCuxGh1nnhMHtgek-CP1JaAxa-FPucdcylxMM5nomyFdOsAPMsGJDw5mHeBXICe6Fs1Fg-N0G8q71v0fcryj5oXfi2TU2OohuRC_eXegAlrHvYS-_P6s3_IuFixbx33rDefu3ysIPpGAqtF-98X6ex8UsEPPMVWrjbeXrqf25vfu3uo7HyX5s2B0Y7CXeT8RLm11GHvAGlG_Y-ODcMfhG94ju-2liCaZHdP-X_89fXsrijyee8Crlm3TDElGtiiwr8nyzIcmh6hgjpUjLNl-tWJ43rOBZLtqCFGLNmmKdyIoSmpGSrsiGpCuyzJrVmuZ03ZYkpZyUaE3EwKRaKnUa_NqJtHYU1SpbF4QmijVC2XBhpbT11xVEfddMTOUJi2bsLVoTJa2zZxNOOiWq6XZjDzAq_n61OYLUThi7cLAYxNAIY_EARmDW90ZYeRLqDb9Kd8BTxSajUdXVPkl3GJtlCwOie79kfC2OBr6L1iG6DyFYRPcxilNF_w4AAP__oYhOqw">