[clang] [CIR] Preserve padding bytes across a byval argument (PR #224672)
Adam Smith via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 20 21:48:41 PDT 2026
================
@@ -797,14 +806,44 @@ void insertArgCoercion(
if (destAlloca)
pendingParamSlots.emplace_back(destAlloca, blockArg);
} else {
- // byval: load the incoming pointer so the body sees a T value (and
- // any CIRGen param-slot store becomes a local copy of that value).
+ // With byval the callee works on its own copy. A record's padding
+ // bytes can hold another union member's live data, so its spill slot
+ // is filled by a byte copy of the incoming object. A _BitInt keeps
+ // its load and spill store, which are its conversion between value
+ // and in-memory form.
+ cir::StoreOp paramStore;
+ if (mlir::isa<cir::RecordType>(blockArg.getType()))
+ paramStore = maybeFindParamSpill(blockArg);
+
+ // Erasing the spill before the block argument is retyped keeps the
----------------
adams381 wrote:
Four shapes reach the byval arm on x86_64: a record classified MEMORY, a `_BitInt` wider than 128 bits, an oversized vector, and `_Complex long double`. The `_BitInt` and the vector store their whole slot, and the complex skips only x87 padding that nothing can alias. Only in a record can the bytes a store skips be another union member's value.
https://github.com/llvm/llvm-project/pull/224672
More information about the cfe-commits
mailing list