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. > >> > >> >>> > > >> > >> >>> > >> > >> >> > >> > >>