[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:33 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>
----------------
MattPD wrote:

At `c5025ead076c`, the new LLVM test fails on all three CI platforms. The emitted function is `@transfer_rec_to_real10_`, not the FIR-level name `@_QPtransfer_rec_to_real10`. With the label corrected locally, the memcpy check still fails because `-O0` emits `ptr %2, ptr %3` without explicit alignment attributes.

Could the test use the external function name and omit alignment attributes from the memcpy check? The `x86_fp80` load later in the test still checks the required 16-byte alignment.


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


More information about the flang-commits mailing list