================
@@ -792,7 +893,21 @@ LogicalResult CIRABIRewriteContext::rewriteCallSite(
if (ac.kind == ArgKind::Ignore)
continue;
Value arg = argOperands[idx];
- if (ac.kind == ArgKind::Expand) {
+ if (auto flatTy = getFlattenedCoercedType(ac)) {
+ // Direct + canFlatten: coerce the struct to the ABI-coerced struct type
+ // and then extract each field as a separate call argument. The coercion
+ // is a memory round-trip when the original and coerced types differ in
+ // layout; when they are the same CIR type the coercion is skipped.
+ Value coerced = arg;
+ if (arg.getType() != flatTy)
+ coerced = emitCoercion(builder, call.getLoc(), flatTy, arg,
+ enclosingFunc, dl);
+ for (unsigned f = 0; f < flatTy.getNumElements(); ++f) {
+ Value field =
+ cir::ExtractMemberOp::create(builder, call.getLoc(), coerced, f);
----------------
adams381 wrote:
Reworked the call site. When the operand needs coercion it now goes through a
coerce slot and reads each field with `cir.get_member` + `cir.load` from that
slot, instead of loading the whole coerced struct and extracting from the
value. The shared memory half is factored into `emitCoercionToMemory`, which
returns the destination-typed pointer to the slot. The no-coercion case (the
operand already has the coerced type) keeps `cir.extract_member`, since that
value has no backing alloca to take member pointers from.
https://github.com/llvm/llvm-project/pull/201719
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits