[flang-commits] [flang] [flang] Fix `getTypeSizeAndAlignment` for packed/tail-padded `RecordType` and `TRANSFER` gate (PR #220377)
via flang-commits
flang-commits at lists.llvm.org
Thu Sep 3 23:02:35 PDT 2026
================
@@ -1661,15 +1661,40 @@ fir::getTypeSizeAndAlignment(mlir::Location loc, mlir::Type ty,
if (auto recTy = mlir::dyn_cast<fir::RecordType>(ty)) {
std::uint64_t size = 0;
unsigned short align = 1;
+ if (recTy.isPacked()) {
+ // LLVM packed structs (<{ ... }>) place fields back-to-back with no
+ // inter-field alignment padding and no tail padding. Each component
+ // still occupies its allocation size (llvm::alignTo(storeSize, ABI
+ // alignment)), because LLVM's packed StructLayout advances by
+ // getTypeAllocSize, not getTypeStoreSize. For example, x86 f80 has
+ // store size 10 bytes but ABI alignment 16 bytes, so its allocation
+ // size is 16 bytes; a packed {f80, i8} therefore occupies 17 bytes,
+ // not 11. The packed struct's own ABI alignment is always 1.
+ for (auto component : recTy.getTypeList()) {
+ auto result =
+ getTypeSizeAndAlignment(loc, component.second, dl, kindMap);
+ if (!result)
+ return result;
+ auto [compSize, compAlign] = *result;
+ size += llvm::alignTo(compSize, compAlign); // allocation size per field
+ }
+ // Packed structs have no tail padding regardless of storeSizeOnly.
+ return std::pair{size, static_cast<unsigned short>(1)};
+ }
for (auto component : recTy.getTypeList()) {
- auto result = getTypeSizeAndAlignment(loc, component.second, dl, kindMap);
+ auto result = getTypeSizeAndAlignment(loc, component.second, dl, kindMap,
+ storeSizeOnly);
if (!result)
return result;
auto [compSize, compAlign] = *result;
size =
llvm::alignTo(size, compAlign) + llvm::alignTo(compSize, compAlign);
align = std::max(align, compAlign);
}
+ // Include tail padding so the size matches the allocation size,
+ // unless the caller only wants the store size (no tail padding).
+ if (!storeSizeOnly)
+ size = llvm::alignTo(size, align);
----------------
MattPD wrote:
Confirmed at `c5025ead076c`: The test passes, and the PR base `9e3a7335e77e` passes both record shapes indirectly.
https://github.com/llvm/llvm-project/pull/220377
More information about the flang-commits
mailing list