On Mon, Jun 30, 2025 at 12:25 PM Andrew Pinski <pins...@gmail.com> wrote:
>
> On Mon, Jun 30, 2025 at 12:01 PM Fractal Fir <fractalfir...@gmail.com> wrote:
> >
> > Thank you so much for the help! It seems like the TREE_ADDRESSABLE bit is 
> > indeed what we have been looking for.
> >
> > In regards to your questions:
> >
> > Sadly, most of this is barely documented if at all. The rust compiler 
> > documentation is... not good.
> >
> > I only know about this because somebody mentioned this in the Rust compiler 
> > chat when I asked about an ABI bug.
> >
> > The only place where this is mentioned at all is the compiler source code, 
> > in: 
> > https://github.com/rust-lang/rust/blob/64033a4ee541c3e9c178fd593e979c74bb798cdc/compiler/rustc_codegen_llvm/src/abi.rs#L464-L468.
>
> So looking it is only set for PassMode::Indirect/on_stack==true which
> should be similar for the TREE_ADDRESSABLE bit being set. If I read
> the code correctly.
>
> But then I read
> https://github.com/rust-lang/rust/blob/c65dccabacdfd6c8a7f7439eba13422fdd89b91e/compiler/rustc_target/src/callconv/mod.rs#L64C1-L73C90
> and that does not correspond at all.

Oh wait I read the code wrong for a second (because there are not
enough comments), on_stack needs to be false for return types.
So yes you need to set TREE_ADDRESSABLE for the return type there.

On the similar subject of arguments with
PassMode::Indirect/on_stack==true, they should be using ARRAY_TYPEs as
mentioned in the comment there and then using VIEW_CONVERT_EXPR back
to the real type.

Thanks,
Andrew


> Since on aarch64 it does not correspond at all to what that comment
> says "a fixed stack offset in accordance to the ABI rather than passed
> using a pointer" that seems x86_64 specific ABI comment rather than
> one based on anything else.
>
> But I think byval is different from TREE_ADDRESSABLE here. Because
> TREE_ADDRESSABLE forces an invisible reference to be passed IIRC but
> it is a bit more complex than that in many cases even.
> And there is no reference to sret in the callconv module at all.
>
> (note the LLVM documentation for these things are at
> https://llvm.org/docs/LangRef.html ).
>
> The more I read this code, the more I hate it. There are not enough
> comments and the comments don't correspond at all to what is actually
> happening.
>
> This is why I mentioned GCC's gimple/generic IR is higher level than
> LLVM's bitcode because there is no "ABI" things like this applied.
> Things are just passed and all.
>
> I get the feeling the RUST ABI was not well thought out either and
> just was using LLVM low level bit code as something which they thought
> would be good instead of thinking high level.
>
>
> >
> > > Why not just change rustc_codegen_gcc code generation to the same as
> > what the target wants for a C like struct always?
> >
> > Even tough the Rust compiler ABI is not *stable*, it is still a real ABI 
> > all backends need to follow. In principle, LLVM, cranelift, and GCC should 
> > agree about the Rust ABI for a given compiler version.
> >
> > The idea is that people should be able to mix & match Rust code compiled 
> > with different compiler backends. We even have an ABI compatibility test 
> > suite: https://github.com/Gankra/abi-cafe.
> >
> > This is something that already runs in CI for each commit(for some backend 
> > combos) and something that we plan to use more extensively.
> >
> >
> > While we could change the Rust ABI to only use `sret` where C would, that 
> > is very unlikely to happen. It is also not my decision to make.
> >
> > The Rust developers want to have freedom in how the ABI is defined, to 
> > continuously improve it in the future.
> >
> > There is also some fear regarding the brittleness of this approach.
> >
> > I believe the `abi-cafe` tool uncovered cases where clang and GCC disagreed 
> > on the C ABI, I think in regards to 128 bit ints on Windows.
>
> Well the biggest issue with GCC for Windows is there is no maintainer
> for the last 10+ years so nothing has been fixed and there are known
> ABI bugs on Windows x86 GCC so any comparison there is not useful for
> the current discussions.
>
> >
> > So, the fear here is that we would accidentally carry some of those bugs 
> > over to Rust.
> >
> > In theory, as long as each backend follows the frontends directions to the 
> > letter, the ABI should always match between the backends.
>
> And looking into the RUST backend code there are 2 parts to it; one
> that is part of LLVM one that is part of rustc. Such a bad design ...
>
> Thanks,
> Andrew Pinski
>
> >
> > That *should*, hopefully, mean we have a matching ABI between all the 
> > backends.
> >
> > Regards,
> >
> > Fractal Fir
> >
> >
> >
> > On Mon, 30 Jun 2025 at 20:32, Andrew Pinski <pins...@gmail.com> wrote:
> >>
> >> On Mon, Jun 30, 2025 at 11:22 AM Andrew Pinski <pins...@gmail.com> wrote:
> >> >
> >> > On Mon, Jun 30, 2025 at 11:10 AM Fractal Fir <fractalfir...@gmail.com> 
> >> > wrote:
> >> > >
> >> > > Hi!
> >> > >
> >> > > I am one of the folk currently working on `rustc_codegen_gcc`, and I 
> >> > > thought that I will provide some more context.
> >> > >
> >> > > > So I looked into this further, it is not rust that specifies sret but
> >> > > rather rust transformation into llvm code generation that does that.
> >> > >
> >> > > > So you need to explain what exactly what you need.
> >> > >
> >> > > The problem here is as follows:
> >> > >
> >> > > The Rust ABI is specified in terms of "PassMode"s. The 
> >> > > `PassMode::Indirect` should *always* correspond to LLVM's `sret` 
> >> > > attribute when applied to a return value.
> >> > >
> >> > > The Rust frontend is free to use `sret` however it pleases. It can 
> >> > > choose to use it in cases where C would not, or not use it where C 
> >> > > would.
> >> > >
> >> > > As an example:
> >> > >
> >> > > ```rust
> >> > > #[repr(C)] // Same layout as in C
> >> > > struct Foo {
> >> > >     a: u128,
> >> > > }
> >> > >
> >> > > #[unsafe(no_mangle)]
> >> > > // Function with the Rust ABI:
> >> > > extern "Rust" fn rust_func() -> Foo {
> >> > >     Foo { a: 1 }
> >> > > }
> >> > > ```
> >> > >
> >> > > This struct will be passed via `sret` by Rust:
> >> > > ```arm
> >> > > rust_func:
> >> > >         mov     w9, #1
> >> > >         stp     x9, xzr, [x8]
> >> > >         ret
> >> > > ```
> >> > >
> >> > > However, GCC(following the C ABI) will pass the struct in a register:
> >> > >
> >> > > ```c
> >> > > struct Foo{
> >> > >     __uint128_t a
> >> > > };
> >> > > struct Foo c_func(){
> >> > >     struct Foo res = {1};
> >> > >     return res;
> >> > > }
> >> > > ```
> >> > >
> >> > > ```arm
> >> > > c_func:
> >> > >         mov     x0, 1
> >> > >         mov     x1, 0
> >> > >         ret
> >> > > ```
> >> > >
> >> > > We need some way to force GCC to pass the return value in `sret`, to 
> >> > > match the Rust ABI. Otherwise, we will get subtle ABI bugs.
> >> >
> >> > So to force GCC to the struct type in memory, you need to have
> >> > TREE_ADDRESSABLE set on the RECORD_TYPE.
> >> > I partly mentioned this but it looks like you missed that part.
> >> >
> >> > So in this case it looks like you need 2 different RECORD_TYPEs, one
> >> > which has TREE_ADDRESSABLE set on it and one without it.
> >> > You can use VIEW_CONVERT_EXPR to "convert" between the 2 as needed.
> >> > You use the one with TREE_ADDRESSABLE not set for the C
> >> > arguments/return types and then use the rest otherwise.
> >> >
> >> > CALL_EXPR_RETURN_SLOT_OPT is a separate (though related) issue.
> >> >
> >> > I hope this helps. And the C++ front-end uses TREE_ADDRESSABLE for
> >> > non-pod (for ABI reasons) in a similar way.
> >>
> >> One more question, where is this documented if at all? Because I
> >> looked into the rust language/compiler specifications and didn't see
> >> it anywhere.
> >> Why not just change rustc_codegen_gcc code generation to the same as
> >> what the target wants for a C like struct always?
> >>
> >> Thanks,
> >> Andrew
> >>
> >>
> >> >
> >> > Thanks,
> >> > Andrew Pinski
> >> >
> >> >
> >> > >
> >> > >
> >> > > We need to do so both on the calle and the caller side. I believe 
> >> > > `CALL_EXPR_RETURN_SLOT_OPT` is applied on the caller side only, which 
> >> > > is insufficient for our purposes.
> >> > >
> >> > > Is there something we could use to achieve this effect?
> >> > >
> >> > > If no, I'd be willing to work on adding such an attribute. Do you have 
> >> > > a rough idea about where I should start?
> >> > >
> >> > > Thank you for taking the time to help us with this issue!
> >> >
> >> > >
> >> > >
> >> > >
> >> > > On Mon, 30 Jun 2025 at 19:31, Antoni Boucher <boua...@zoho.com> wrote:
> >> > >>
> >> > >> Hi.
> >> > >> Let me introduce you Fractal Fir who's a student working on
> >> > >> rustc_codegen_gcc for the Google Summer of Code.
> >> > >> He found some ABI issues (one related to sret) in rustc_codegen_gcc 
> >> > >> and
> >> > >> wanted to join this discussion in order to share more details about 
> >> > >> what
> >> > >> we want to achieve here.
> >> > >> Thanks.
> >> > >>
> >> > >> Le 2025-06-30 à 10 h 51, Andrew Pinski a écrit :
> >> > >> > On Mon, Jun 30, 2025 at 7:25 AM Antoni Boucher <boua...@zoho.com> 
> >> > >> > wrote:
> >> > >> >>
> >> > >> >>
> >> > >> >>
> >> > >> >> Le 2025-06-29 à 19 h 42, Andrew Pinski a écrit :
> >> > >> >>>
> >> > >> >>>
> >> > >> >>> On Sun, Jun 29, 2025, 4:36 PM Antoni Boucher <boua...@zoho.com
> >> > >> >>> <mailto:boua...@zoho.com>> wrote:
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>      Le 2025-06-29 à 10 h 46, Andrew Pinski a écrit :
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       > On Sun, Jun 29, 2025, 7:43 AM Andrew Pinski 
> >> > >> >>> <pins...@gmail.com
> >> > >> >>>      <mailto:pins...@gmail.com>
> >> > >> >>>       > <mailto:pins...@gmail.com <mailto:pins...@gmail.com>>> 
> >> > >> >>> wrote:
> >> > >> >>>       >
> >> > >> >>>       >     On Sun, Jun 29, 2025, 7:36 AM Antoni Boucher via Gcc
> >> > >> >>>       >     <gcc@gcc.gnu.org <mailto:gcc@gcc.gnu.org>
> >> > >> >>>      <mailto:gcc@gcc.gnu.org <mailto:gcc@gcc.gnu.org>>> wrote:
> >> > >> >>>       >
> >> > >> >>>       >         Hi.
> >> > >> >>>       >         Is there a way in GENERIC to specify that a 
> >> > >> >>> parameter will be
> >> > >> >>>       >         passed in
> >> > >> >>>       >         "sret", or is this solely controlled by the hook
> >> > >> >>>      struct_value_rtx?
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       >     It is only controlled by the hook.
> >> > >> >>>       >     What exactly are trying to do?
> >> > >> >>>       >     You could set the return slot optimization bit on the 
> >> > >> >>> call
> >> > >> >>>       >     expression if you want the lhs of a call not to be 
> >> > >> >>> copied and
> >> > >> >>>      just
> >> > >> >>>       >     passed as the address via sret.
> >> > >> >>>
> >> > >> >>>      I'm trying to follow the Rust ABI for rustc_codegen_gcc: 
> >> > >> >>> they manually
> >> > >> >>>      specify whether a param is "sret".
> >> > >> >>>
> >> > >> >>>
> >> > >> >>> Not all ABI/targets have a sret specific register. So this is 
> >> > >> >>> even more
> >> > >> >>> confusing.
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>       >
> >> > >> >>>       >     That is if you have:
> >> > >> >>>       >     StructVar = func(...);
> >> > >> >>>       >
> >> > >> >>>       >     You set the return slot optimization bit on the call 
> >> > >> >>> expr in
> >> > >> >>>      generic
> >> > >> >>>       >     and which will copy that bit to the gimple 
> >> > >> >>> GIMPLE_CALL and then
> >> > >> >>>       >     during expand will again copy it back to the generic
> >> > >> >>>      call_expr and
> >> > >> >>>       >     expand will use the target for the address.
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       > CALL_EXPR_RETURN_SLOT_OPT is the macro.
> >> > >> >>>
> >> > >> >>>      Is this a guaranteed optimization? I'm asking because this 
> >> > >> >>> is for ABI
> >> > >> >>>      correctness and I need a solution that will always work.
> >> > >> >>>      If not, would there be another way to do this?
> >> > >> >>>      Thanks.
> >> > >> >>>
> >> > >> >>>
> >> > >> >>> Yes it is guaranteed that if the return type is returned via 
> >> > >> >>> memory
> >> > >> >>> reference to the other function it will use that memory location.
> >> > >> >>
> >> > >> >> How does this work on the side of the function declaration? Do we 
> >> > >> >> need
> >> > >> >> to set something so that it follows the correct convention?
> >> > >> >
> >> > >> > So there are 2 separate things here.
> >> > >> > First there is an ABI of having struct return in memory.
> >> > >> > Note if TREE_ADDRESSABLE is set on a struct type, then return value 
> >> > >> > is
> >> > >> > always through memory:
> >> > >> > ```
> >> > >> >     In ..._TYPE nodes, it means that objects of this type must be 
> >> > >> > fully
> >> > >> >     addressable.  This means that pieces of this object cannot go 
> >> > >> > into
> >> > >> >     register parameters, for example.  If this a function type, this
> >> > >> >     means that the value must be returned in memory.
> >> > >> > ```
> >> > >> > The ABI part is independent of the CALL_EXPR and dependent on the
> >> > >> > FUNCTION_TYPE that is being used and the target.
> >> > >> >
> >> > >> > Second is specifying if you can reuse the memory of the lhs of a
> >> > >> > modify_expr with a call_expr when the ABI says the memory is return 
> >> > >> > in
> >> > >> > memory.
> >> > >> > This is specified via CALL_EXPR_RETURN_SLOT_OPT on the CALL_EXPR.
> >> > >> >
> >> > >> > I am trying to understand how the rustc front-end sets up this. Does
> >> > >> > it implement the ABI of each target as that is needed for LLVM?
> >> > >> > This is the major difference here as GCC's front-ends normally don't
> >> > >> > care much about the ABI except in specific cases (e.g. returns this
> >> > >> > and a few others). GCC's front-end don't handle the call argument 
> >> > >> > ABI
> >> > >> > at all; rather it is more like you build call_expr which act like
> >> > >> > function calls in C (well with the addition of reference types but
> >> > >> > those are really just pointers at that point). And the middle-end
> >> > >> > (with help from the backend) which implements the full ABI.
> >> > >> >
> >> > >> > The reason why this is done this way is an abstraction layer and
> >> > >> > allows new front-ends for backends that are known to it at the time
> >> > >> > without additional work (e.g. gfortran adding support for riscv or
> >> > >> > aarch64; no changes to  the front-end were made). This seems like 
> >> > >> > the
> >> > >> > opposite of LLVM where there is no tight coupling of the 2 and there
> >> > >> > is no abstraction for most of the ABI call work and each front-end
> >> > >> > needs to implement that again.
> >> > >> >
> >> > >> > Hope this helps explain GCC front-end interactions with the GCC's
> >> > >> > middle-end better.
> >> > >> >
> >> > >> >>
> >> > >> >> Thanks a lot for your help.
> >> > >> >>
> >> > >> >>>
> >> > >> >>> Even for things like a->b = func(...)[RSO].  It is even used by 
> >> > >> >>> the c++
> >> > >> >>> frontend that way.
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       >     Is that what you are looking for?
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       >     Thanks,
> >> > >> >>>       >     Andrew
> >> > >> >>>       >
> >> > >> >>>       >         Thanks.
> >> > >> >>>       >
> >> > >> >>>
> >> > >> >>
> >> > >>
> >
> >
> >
> > On Mon, 30 Jun 2025 at 20:32, Andrew Pinski <pins...@gmail.com> wrote:
> >>
> >> On Mon, Jun 30, 2025 at 11:22 AM Andrew Pinski <pins...@gmail.com> wrote:
> >> >
> >> > On Mon, Jun 30, 2025 at 11:10 AM Fractal Fir <fractalfir...@gmail.com> 
> >> > wrote:
> >> > >
> >> > > Hi!
> >> > >
> >> > > I am one of the folk currently working on `rustc_codegen_gcc`, and I 
> >> > > thought that I will provide some more context.
> >> > >
> >> > > > So I looked into this further, it is not rust that specifies sret but
> >> > > rather rust transformation into llvm code generation that does that.
> >> > >
> >> > > > So you need to explain what exactly what you need.
> >> > >
> >> > > The problem here is as follows:
> >> > >
> >> > > The Rust ABI is specified in terms of "PassMode"s. The 
> >> > > `PassMode::Indirect` should *always* correspond to LLVM's `sret` 
> >> > > attribute when applied to a return value.
> >> > >
> >> > > The Rust frontend is free to use `sret` however it pleases. It can 
> >> > > choose to use it in cases where C would not, or not use it where C 
> >> > > would.
> >> > >
> >> > > As an example:
> >> > >
> >> > > ```rust
> >> > > #[repr(C)] // Same layout as in C
> >> > > struct Foo {
> >> > >     a: u128,
> >> > > }
> >> > >
> >> > > #[unsafe(no_mangle)]
> >> > > // Function with the Rust ABI:
> >> > > extern "Rust" fn rust_func() -> Foo {
> >> > >     Foo { a: 1 }
> >> > > }
> >> > > ```
> >> > >
> >> > > This struct will be passed via `sret` by Rust:
> >> > > ```arm
> >> > > rust_func:
> >> > >         mov     w9, #1
> >> > >         stp     x9, xzr, [x8]
> >> > >         ret
> >> > > ```
> >> > >
> >> > > However, GCC(following the C ABI) will pass the struct in a register:
> >> > >
> >> > > ```c
> >> > > struct Foo{
> >> > >     __uint128_t a
> >> > > };
> >> > > struct Foo c_func(){
> >> > >     struct Foo res = {1};
> >> > >     return res;
> >> > > }
> >> > > ```
> >> > >
> >> > > ```arm
> >> > > c_func:
> >> > >         mov     x0, 1
> >> > >         mov     x1, 0
> >> > >         ret
> >> > > ```
> >> > >
> >> > > We need some way to force GCC to pass the return value in `sret`, to 
> >> > > match the Rust ABI. Otherwise, we will get subtle ABI bugs.
> >> >
> >> > So to force GCC to the struct type in memory, you need to have
> >> > TREE_ADDRESSABLE set on the RECORD_TYPE.
> >> > I partly mentioned this but it looks like you missed that part.
> >> >
> >> > So in this case it looks like you need 2 different RECORD_TYPEs, one
> >> > which has TREE_ADDRESSABLE set on it and one without it.
> >> > You can use VIEW_CONVERT_EXPR to "convert" between the 2 as needed.
> >> > You use the one with TREE_ADDRESSABLE not set for the C
> >> > arguments/return types and then use the rest otherwise.
> >> >
> >> > CALL_EXPR_RETURN_SLOT_OPT is a separate (though related) issue.
> >> >
> >> > I hope this helps. And the C++ front-end uses TREE_ADDRESSABLE for
> >> > non-pod (for ABI reasons) in a similar way.
> >>
> >> One more question, where is this documented if at all? Because I
> >> looked into the rust language/compiler specifications and didn't see
> >> it anywhere.
> >> Why not just change rustc_codegen_gcc code generation to the same as
> >> what the target wants for a C like struct always?
> >>
> >> Thanks,
> >> Andrew
> >>
> >>
> >> >
> >> > Thanks,
> >> > Andrew Pinski
> >> >
> >> >
> >> > >
> >> > >
> >> > > We need to do so both on the calle and the caller side. I believe 
> >> > > `CALL_EXPR_RETURN_SLOT_OPT` is applied on the caller side only, which 
> >> > > is insufficient for our purposes.
> >> > >
> >> > > Is there something we could use to achieve this effect?
> >> > >
> >> > > If no, I'd be willing to work on adding such an attribute. Do you have 
> >> > > a rough idea about where I should start?
> >> > >
> >> > > Thank you for taking the time to help us with this issue!
> >> >
> >> > >
> >> > >
> >> > >
> >> > > On Mon, 30 Jun 2025 at 19:31, Antoni Boucher <boua...@zoho.com> wrote:
> >> > >>
> >> > >> Hi.
> >> > >> Let me introduce you Fractal Fir who's a student working on
> >> > >> rustc_codegen_gcc for the Google Summer of Code.
> >> > >> He found some ABI issues (one related to sret) in rustc_codegen_gcc 
> >> > >> and
> >> > >> wanted to join this discussion in order to share more details about 
> >> > >> what
> >> > >> we want to achieve here.
> >> > >> Thanks.
> >> > >>
> >> > >> Le 2025-06-30 à 10 h 51, Andrew Pinski a écrit :
> >> > >> > On Mon, Jun 30, 2025 at 7:25 AM Antoni Boucher <boua...@zoho.com> 
> >> > >> > wrote:
> >> > >> >>
> >> > >> >>
> >> > >> >>
> >> > >> >> Le 2025-06-29 à 19 h 42, Andrew Pinski a écrit :
> >> > >> >>>
> >> > >> >>>
> >> > >> >>> On Sun, Jun 29, 2025, 4:36 PM Antoni Boucher <boua...@zoho.com
> >> > >> >>> <mailto:boua...@zoho.com>> wrote:
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>      Le 2025-06-29 à 10 h 46, Andrew Pinski a écrit :
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       > On Sun, Jun 29, 2025, 7:43 AM Andrew Pinski 
> >> > >> >>> <pins...@gmail.com
> >> > >> >>>      <mailto:pins...@gmail.com>
> >> > >> >>>       > <mailto:pins...@gmail.com <mailto:pins...@gmail.com>>> 
> >> > >> >>> wrote:
> >> > >> >>>       >
> >> > >> >>>       >     On Sun, Jun 29, 2025, 7:36 AM Antoni Boucher via Gcc
> >> > >> >>>       >     <gcc@gcc.gnu.org <mailto:gcc@gcc.gnu.org>
> >> > >> >>>      <mailto:gcc@gcc.gnu.org <mailto:gcc@gcc.gnu.org>>> wrote:
> >> > >> >>>       >
> >> > >> >>>       >         Hi.
> >> > >> >>>       >         Is there a way in GENERIC to specify that a 
> >> > >> >>> parameter will be
> >> > >> >>>       >         passed in
> >> > >> >>>       >         "sret", or is this solely controlled by the hook
> >> > >> >>>      struct_value_rtx?
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       >     It is only controlled by the hook.
> >> > >> >>>       >     What exactly are trying to do?
> >> > >> >>>       >     You could set the return slot optimization bit on the 
> >> > >> >>> call
> >> > >> >>>       >     expression if you want the lhs of a call not to be 
> >> > >> >>> copied and
> >> > >> >>>      just
> >> > >> >>>       >     passed as the address via sret.
> >> > >> >>>
> >> > >> >>>      I'm trying to follow the Rust ABI for rustc_codegen_gcc: 
> >> > >> >>> they manually
> >> > >> >>>      specify whether a param is "sret".
> >> > >> >>>
> >> > >> >>>
> >> > >> >>> Not all ABI/targets have a sret specific register. So this is 
> >> > >> >>> even more
> >> > >> >>> confusing.
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>       >
> >> > >> >>>       >     That is if you have:
> >> > >> >>>       >     StructVar = func(...);
> >> > >> >>>       >
> >> > >> >>>       >     You set the return slot optimization bit on the call 
> >> > >> >>> expr in
> >> > >> >>>      generic
> >> > >> >>>       >     and which will copy that bit to the gimple 
> >> > >> >>> GIMPLE_CALL and then
> >> > >> >>>       >     during expand will again copy it back to the generic
> >> > >> >>>      call_expr and
> >> > >> >>>       >     expand will use the target for the address.
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       > CALL_EXPR_RETURN_SLOT_OPT is the macro.
> >> > >> >>>
> >> > >> >>>      Is this a guaranteed optimization? I'm asking because this 
> >> > >> >>> is for ABI
> >> > >> >>>      correctness and I need a solution that will always work.
> >> > >> >>>      If not, would there be another way to do this?
> >> > >> >>>      Thanks.
> >> > >> >>>
> >> > >> >>>
> >> > >> >>> Yes it is guaranteed that if the return type is returned via 
> >> > >> >>> memory
> >> > >> >>> reference to the other function it will use that memory location.
> >> > >> >>
> >> > >> >> How does this work on the side of the function declaration? Do we 
> >> > >> >> need
> >> > >> >> to set something so that it follows the correct convention?
> >> > >> >
> >> > >> > So there are 2 separate things here.
> >> > >> > First there is an ABI of having struct return in memory.
> >> > >> > Note if TREE_ADDRESSABLE is set on a struct type, then return value 
> >> > >> > is
> >> > >> > always through memory:
> >> > >> > ```
> >> > >> >     In ..._TYPE nodes, it means that objects of this type must be 
> >> > >> > fully
> >> > >> >     addressable.  This means that pieces of this object cannot go 
> >> > >> > into
> >> > >> >     register parameters, for example.  If this a function type, this
> >> > >> >     means that the value must be returned in memory.
> >> > >> > ```
> >> > >> > The ABI part is independent of the CALL_EXPR and dependent on the
> >> > >> > FUNCTION_TYPE that is being used and the target.
> >> > >> >
> >> > >> > Second is specifying if you can reuse the memory of the lhs of a
> >> > >> > modify_expr with a call_expr when the ABI says the memory is return 
> >> > >> > in
> >> > >> > memory.
> >> > >> > This is specified via CALL_EXPR_RETURN_SLOT_OPT on the CALL_EXPR.
> >> > >> >
> >> > >> > I am trying to understand how the rustc front-end sets up this. Does
> >> > >> > it implement the ABI of each target as that is needed for LLVM?
> >> > >> > This is the major difference here as GCC's front-ends normally don't
> >> > >> > care much about the ABI except in specific cases (e.g. returns this
> >> > >> > and a few others). GCC's front-end don't handle the call argument 
> >> > >> > ABI
> >> > >> > at all; rather it is more like you build call_expr which act like
> >> > >> > function calls in C (well with the addition of reference types but
> >> > >> > those are really just pointers at that point). And the middle-end
> >> > >> > (with help from the backend) which implements the full ABI.
> >> > >> >
> >> > >> > The reason why this is done this way is an abstraction layer and
> >> > >> > allows new front-ends for backends that are known to it at the time
> >> > >> > without additional work (e.g. gfortran adding support for riscv or
> >> > >> > aarch64; no changes to  the front-end were made). This seems like 
> >> > >> > the
> >> > >> > opposite of LLVM where there is no tight coupling of the 2 and there
> >> > >> > is no abstraction for most of the ABI call work and each front-end
> >> > >> > needs to implement that again.
> >> > >> >
> >> > >> > Hope this helps explain GCC front-end interactions with the GCC's
> >> > >> > middle-end better.
> >> > >> >
> >> > >> >>
> >> > >> >> Thanks a lot for your help.
> >> > >> >>
> >> > >> >>>
> >> > >> >>> Even for things like a->b = func(...)[RSO].  It is even used by 
> >> > >> >>> the c++
> >> > >> >>> frontend that way.
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       >     Is that what you are looking for?
> >> > >> >>>       >
> >> > >> >>>       >
> >> > >> >>>       >     Thanks,
> >> > >> >>>       >     Andrew
> >> > >> >>>       >
> >> > >> >>>       >         Thanks.
> >> > >> >>>       >
> >> > >> >>>
> >> > >> >>
> >> > >>

Reply via email to