[CIR] Lower sret returns in CallConvLowering (#201716) Functions that return an aggregate by value classify their return as ArgKind::Indirect, but CallConvLowering reached an errorNYI for that case, so the whole CallConv pass refused to lower any struct-returning function. rewriteFunctionDefinition now recognizes an Indirect return: the wire return type becomes void, a hidden sret pointer is prepended as block argument 0, and every cir.return is routed through that pointer. Rather than storing the loaded return value through the sret pointer (a byte-copy that breaks non-trivially-copyable types -- libstdc++'s SSO std::string keeps a _M_p pointer into its own _M_local_buf, so a byte-copy leaves the destination aliasing the source's dying stack storage), insertSRetStores rewires the __retval alloca to the sret pointer so construction flows directly into the caller's slot, matching classic CodeGen's "construct into %agg.result" pattern. CIRGen emits one cir.load __retval / cir.return pair per return statement, all reading the single __retval alloca, so the alloca is rewired once and every return is collapsed to a bare return. That cir.return (cir.load <alloca>) shape is treated as an invariant and asserted with cast<> rather than guarded by a fallback. The sret parameter carries sret(T) align A writable dead_on_unwind, plus noalias on definitions. rewriteCallSite prepends the return slot, makes the call return void, and reads the result back. When the result has a single store-into-dest use whose destination dominates the call, it reuses that destination as the sret slot and drops the redundant store, so the callee writes straight into the local with no copy; otherwise it allocates a fresh slot and loads the value out. The slot's per-argument attributes go through the same updateArgAttrs path as the non-sret case, so sret composes with Extend (signext/zeroext) and Ignore arguments. byval indirect arguments and Expand are still errorNYI. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
Welcome to the LLVM project!
This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.
The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.
C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.
Other components include: the libc++ C++ standard library, the LLD linker, and more.
Consult the Getting Started with LLVM page for information on building and running LLVM.
For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.
Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.
The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.