================
@@ -912,7 +1032,33 @@ CIRABIRewriteContext::rewriteCallSite(mlir::Operation 
*callOp,
     if (ac.kind == ArgKind::Ignore)
       continue;
     mlir::Value arg = argOperands[idx];
-    if (ac.kind == ArgKind::Expand) {
+    if (auto flatTy = getFlattenedCoercedType(ac)) {
+      // Direct + canFlatten: pass one scalar call argument per field of the
+      // ABI-coerced struct.  When the original and coerced types differ in
+      // layout, coerce through a memory slot and read each field with
+      // cir.get_member + cir.load from that slot, rather than loading the
+      // whole coerced struct and extracting members from the value.  When the
+      // types are already identical there is no backing slot (arg is a plain
+      // struct value), so extract each field directly from the value.
+      if (arg.getType() != flatTy) {
+        SmallPtrSet<mlir::Operation *, 4> coercionOps;
+        mlir::Value coercedPtr =
+            emitCoercionToMemory(builder, call.getLoc(), flatTy, arg,
+                                 enclosingFunc, dl, coercionOps);
+        for (auto [f, fieldTy] : llvm::enumerate(flatTy.getMembers())) {
+          mlir::Type fieldPtrTy = cir::PointerType::get(fieldTy);
+          auto fieldPtr =
+              cir::GetMemberOp::create(builder, call.getLoc(), fieldPtrTy,
+                                       coercedPtr, /*name=*/"", /*index=*/f);
+          newArgs.push_back(cir::LoadOp::create(builder, call.getLoc(), 
fieldTy,
+                                                fieldPtr.getResult()));
+        }
+      } else {
+        for (unsigned f = 0; f < flatTy.getNumElements(); ++f)
----------------
adams381 wrote:

When the operand is a plain (non-volatile, non-atomic) load from an alloca, 
each field is now read with `cir.get_member` + `cir.load`, and the whole-struct 
load is dropped once nothing else uses it -- so those args lower to gep+load, 
no `extractvalue`. I factored that into `emitStructFieldArgs`, shared with the 
Expand path. `cir.extract_member` stays as the fallback when the operand isn't 
such a load (a constant, a call result, or a volatile/atomic load).

https://github.com/llvm/llvm-project/pull/201719
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to