[clang] [CIR] Emit classic's attributes for a non-byval indirect argument (PR #222445)

Adam Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 10 13:02:34 PDT 2026


================
@@ -63,6 +64,19 @@ class CIRABIRewriteContext : public mlir::abi::ABIRewriteContext {
 private:
   mlir::ModuleOp module;
   const mlir::DataLayout &dl;
+
+  /// Each block argument rewriteFunctionDefinition has rewritten into a
+  /// non-byval indirect parameter, mapped to the alignment its classification
+  /// states, so rewriteCallSite can forward such a parameter rather than copy
+  /// it.  Recorded where the classification says so rather than read back
+  /// from an emitted attribute, which would tie the pass to whichever
+  /// attribute is unique to this case today.
+  ///
+  /// Sound for one run over one module only.  A recorded argument is retyped
+  /// but never erased, so the keys stay valid, but a value freed with one
+  /// module can be recycled by the next, and a stale hit would forward the
+  /// caller's object where a copy is required.  Do not promote to pass state.
+  llvm::DenseMap<mlir::BlockArgument, uint64_t> nonByvalParams;
----------------
adams381 wrote:

Per-function on its own would not have worked, since the driver rewrites F and then every call to F, so when a call inside G is rewritten the current function is F while the question is about G's parameters.

However, the map is only there because `insertArgCoercion` replaces the CIRGen spill alloca with the incoming pointer and erases it as soon as it rewrites the signature, which leaves the call site holding a block argument with no defining operation to inspect.  Deferring the replacement and erase to the end of the pass keeps the alloca in place while call sites are rewritten, so `getUnderlyingAlloca` answers every case and both the map and its block-argument arm go away.

https://github.com/llvm/llvm-project/pull/222445


More information about the cfe-commits mailing list