[flang-commits] [flang] [flang] Fix `getTypeSizeAndAlignment` for packed/tail-padded `RecordType` and `TRANSFER` gate (PR #220377)

Daniel Chen via flang-commits flang-commits at lists.llvm.org
Thu Sep 3 05:48:36 PDT 2026


================
@@ -0,0 +1,67 @@
+! RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -emit-hlfir %s -o - | FileCheck %s
+! REQUIRES: x86-registered-target
+
+! Regression test for https://github.com/llvm/llvm-project/pull/220377
+!
+! The TRANSFER inline gate compares store sizes, not allocation sizes.
+! Tail padding must not be included in the comparison.
+!
+! Types declared at module scope so that bare %flang_fc1 does not abort when
+! TRANSFER falls through to the runtime path (pre-existing defect: runtime
+! TRANSFER of a subroutine-local derived type aborts under bare %flang_fc1).
+
+! Shape 1: tail-padded record whose store size matches real(10).
+!   t1 fields: integer(8) [8B, align 8] + integer(2) [2B, align 2]
+!   Store size = 10B; allocation size = alignTo(10, 8) = 16B.
+!   real(10) = f80 on x86-64: store size = 10B.
+!   10 == 10 on store size -> must INLINE (fir.load), not call _FortranATransfer.
+!   Without the storeSizeOnly fix the allocation size (16) != 10 and this
+!   would wrongly fall through to the runtime path.
+module m1
+  type :: t1
+    integer(8) :: a
+    integer(2) :: b
+  end type
+end module
+
+! Shape 2: tail-padded record whose allocation size matches integer(8) but
+!   whose store size does not.
+!   t2 fields: integer(4) [4B, align 4] + integer(1) [1B, align 1]
+!   Store size = 5B; allocation size = alignTo(5, 4) = 8B.
+!   integer(8) store size = 8B.
+!   Without the storeSizeOnly fix: 8 == 8 on allocation size -> would inline,
+!   but that reads 3 bytes of uninitialized tail padding into the result.
+!   With the fix: 5 != 8 on store size -> correctly stays on RUNTIME path.
+module m2
+  type :: t2
+    integer(4) :: a
+    integer(1) :: b
+  end type
+end module
+
+subroutine transfer_rec_to_real10(out)
+  ! CHECK-LABEL: func @_QPtransfer_rec_to_real10(
+  ! CHECK-NOT:     fir.call @_FortranATransfer
+  ! CHECK:         fir.convert {{.*}} : (!fir.ref<!fir.type<{{.*}}>>) -> !fir.ref<f80>
+  ! CHECK:         fir.load {{.*}} : !fir.ref<f80>
----------------
DanielCChen wrote:

The FIR-to-LLVM lowering aborts on this source due to a missing type descriptor (pre-existing issue, also noted in your other comment). Reaching LLVM IR requires `-mmlir --ignore-missing-type-desc`, which is a debug flag that substitutes null for missing descriptors — not appropriate for a regression test. The path selection (inline vs. runtime) is decided at the HLFIR stage, so seems stopping there is sufficient to verify both the `storeSizeOnly` gate and the alignment fix.

https://github.com/llvm/llvm-project/pull/220377


More information about the flang-commits mailing list