[flang-commits] [flang] [flang] Fix RecordType sizes, TRANSFER lowering, and BIND(C) ABI on SystemZ/PPC64le (PR #220377)
Daniel Chen via flang-commits
flang-commits at lists.llvm.org
Tue Sep 15 12:46:49 PDT 2026
================
@@ -31,6 +31,61 @@ page](https://llvm.org/releases/).
## Bug Fixes
+- Fixed `fir::getTypeSizeAndAlignment` returning the wrong allocation size for
+ **packed `fir::RecordType`s** (produced by the AIX lowering of `BIND(C)`
+ derived types, or declared directly in textual FIR). Fields in a packed
+ record are placed back-to-back using each component's allocation size
+ (`alignTo(storeSize, ABIalign)`), not its raw store size, and the record's
+ ABI alignment is 1. For example, a packed `{i32, f64}` on x86-64 now
+ correctly reports 12 bytes instead of 16.
+ ([#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:
+ 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`, and `{i16, i8}` (4 bytes) as `i32`, 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 a **`BIND(C)` / `VALUE` argument-passing ABI bug** on PPC64le:
+ derived types were classified using the unpadded store size rather than the
+ allocation size, producing the wrong number of GPR slots. The argument was
+ already passed by value; only the slot count was wrong. For example,
+ `{f128, i8}` (allocation size 32 bytes) is now correctly passed as
+ `[4 x i64]` instead of `[3 x i64]`, 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
----------------
DanielCChen wrote:
Thanks for the quick response and confirmation!
For 1, yes, it is a separate issue to this PR. I am preparing another PR to instead of doing component-by-component assignment, it calls `fir.copy` and figure out the size in `genTypeStrideInBytes`.
For 2, I have a patch to roll back to `getTypeSizeAndAlignment` and remove the new `getTypeStoreSizeAndAlignment`. I am testing it now.
https://github.com/llvm/llvm-project/pull/220377
More information about the flang-commits
mailing list