================
@@ -5255,6 +5255,33 @@ void CodeGenFunction::EmitCallArg(CallArgList &args,
const Expr *E,
}
}
+ // Under musttail, hand a trivially-copyable record source's LValue to
+ // EmitCall rather than materializing an agg.tmp. EmitCall's Indirect path
+ // routes it via the matching incoming parameter, which survives the tail
+ // call. Limited to params and locals: globals and captures don't have the
+ // dangle issue and the existing path may be more efficient for them.
+ if (HasAggregateEvalKind && MustTailCall && type->isRecordType() &&
----------------
xroche wrote:
Nope, it isn't musttail-specific.
The C path right above (the `CK_LValueToRValue` case) already forwards
unconditionally, so the `MustTailCall` gate was the only thing keeping the C++
trivial copy/move case from doing the same. Dropped the gate and the storage
restriction: a trivial copy/move ctor whose source is a variable now forwards
the source LValue for any call, and `EmitCall` makes the real copy at the
byval/Indirect boundary. The source is kept to a direct variable reference for
now; broader lvalues (`*p`, member access) stay on the existing path and can
follow up.
Forwarding skips the copy, so it has to exclude the types whose by-value copy
is not a plain memcpy in `EmitAggregateCopy`, or the special copy gets dropped.
Excluded: a stripped derived-to-base cast (same-type guard, would slice),
`hlsl_constant` sources (as the C path does), CUDA
`device_builtin_surface`/`texture` types (lowered to a handle), and, under ObjC
GC, records with an object member (need the `objc_memmove_collectable` write
barrier). ARC/`__ptrauth`/PFP/inalloca are already excluded because they are
not trivially copyable.
https://github.com/llvm/llvm-project/pull/199351
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits