[clang] [CIR] Forward caller storage for byref call arguments (PR #216499)

Adam Smith via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 22 14:34:24 PDT 2026


================
@@ -1204,21 +1230,30 @@ CIRABIRewriteContext::rewriteCallSite(mlir::Operation *callOp,
                          dl);
       newArgs.push_back(arg);
     } else if (ac.kind == ArgKind::Indirect) {
-      // byval and byref: allocate a stack slot, copy the value in, and pass
-      // the pointer.  The alloca+store pattern is identical for both; the
-      // attribute distinction (llvm.byval vs llvm.byref) is applied by
-      // updateArgAttrs.  byref does not receive llvm.noalias or llvm.noundef
-      // because it does not assert exclusive ownership of the storage.
-      mlir::Type argTy = arg.getType();
-      auto ptrTy = cir::PointerType::get(argTy);
-      uint64_t align = ac.indirectAlign.value();
-      StringRef slotName = ac.byVal ? "byval" : "byref";
-      auto slot = cir::AllocaOp::create(builder, call.getLoc(), ptrTy,
-                                        builder.getStringAttr(slotName),
-                                        builder.getI64IntegerAttr(align));
+      // byval hands the callee its own copy.  byref must name the caller's
+      // storage instead: CIRGen materializes the argument into a temporary it
+      // destroys after the call and emits the operand's load immediately
+      // before that call, so forwarding the alloca hands the callee the object
+      // the caller destroys, with nothing able to write it in between.
+      if (!ac.byVal) {
+        WholeRecordSource src = getWholeRecordSource(arg);
----------------
adams381 wrote:

Applied.  I took the spelling from your previous comment above.

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


More information about the cfe-commits mailing list