[llvm-branch-commits] [clang] [CIR] Implement Direct+canFlatten in CallConvLowering (PR #201719)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Jun 12 09:05:27 PDT 2026
================
@@ -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
More information about the llvm-branch-commits
mailing list