[flang-commits] [flang] [flang] Fix RecordType sizes, TRANSFER lowering, and BIND(C) ABI on SystemZ/PPC64le (PR #220377)
via flang-commits
flang-commits at lists.llvm.org
Fri Sep 4 23:33:11 PDT 2026
================
@@ -31,6 +31,48 @@ page](https://llvm.org/releases/).
## Bug Fixes
+- Fixed `fir::getTypeSizeAndAlignment` returning the wrong allocation size for
+ **packed derived types** (`SEQUENCE` types compiled with `PACK` / LLVM
+ packed-struct layout). Fields in a packed struct are placed back-to-back
+ using each component's allocation size (`alignTo(storeSize, ABIalign)`), not
+ its raw store size, and the struct ABI alignment is 1. For example, a packed
+ `{f80, i8}` on x86-64 now correctly reports 17 bytes instead of 11.
+ ([#220377](https://github.com/llvm/llvm-project/pull/220377))
+
+- Fixed `fir::getTypeSizeAndAlignment` omitting **tail padding** from unpacked
+ derived types. The returned size is now rounded up to the record's own ABI
+ alignment, matching the allocation extent used by array element strides, CUDA
+ shared-memory layout, and stack/heap allocation placement. For example,
+ `{i32, i8}` (store size 5 bytes, align 4) now correctly reports 8 bytes
+ instead of 5.
+ ([#220377](https://github.com/llvm/llvm-project/pull/220377))
+
+- Fixed a **`BIND(C)` / `VALUE` argument-passing ABI bug** on SystemZ and
+ PPC64le: derived types whose allocation size fits in a GPR were incorrectly
+ passed indirectly (by reference) instead of as an integer register value,
+ because `getTypeSizeAndAlignment` was returning the unpadded store size
+ rather than the allocation size. For example, `{i32, i8}` (allocation size
+ 8 bytes) is now correctly passed as `i64` on SystemZ, and `{f128, i8}`
+ (allocation size 32 bytes) as `[4 x i64]` on PPC64le, matching the C ABI.
+ Fortran programs with `BIND(C)` `VALUE` derived-type arguments of these
+ shapes that interoperate with C were already producing incorrect results;
+ programs compiled entirely in Fortran that relied on the old (incorrect)
+ convention must be recompiled.
+ ([#220377](https://github.com/llvm/llvm-project/pull/220377))
+
+- Fixed the `TRANSFER` intrinsic inline path to compare **stored-representation
+ widths** (excluding outer tail padding) rather than allocation sizes when
+ deciding whether to inline a load instead of calling the runtime. This
+ prevents reading uninitialized tail-padding bytes into the result (wrong
----------------
MattPD wrote:
`transfer_rec_to_int8` still passes an eight-byte source descriptor to the runtime. `TransferImpl` copies `min(8, 8)` bytes, so it copies all eight bytes. In a test that initializes every source byte, binaries built from `de5ef3bc48d6` and from its parent commit both preserve all eight bytes, including the three tail-padding bytes.
Could the release note, PR description, and commit message describe the change in `TRANSFER` lowering without claiming that the runtime no longer reads tail-padding bytes?
https://github.com/llvm/llvm-project/pull/220377
More information about the flang-commits
mailing list