[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