[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:10 PDT 2026
================
@@ -102,4 +102,67 @@ module attributes { dlti.dl_spec = #dlti.dl_spec< i1 = dense<8> : vector<2xi64>,
// CHECK: %[[C:.*]] = arith.constant 16 : index
// CHECK: return %[[C]]
// CHECK-NOT: fir.box_elesize
+
+ // Fold: packed derived type -- fir.type<tp<{i:i32,d:f64}>>.
+ // This is the exact example from MattPD's review: on x86-64
+ // (f64 ABI align=8B) the non-packed size is 16B and the packed
+ // size is 12B (i32 allocSize=4B + f64 allocSize=alignTo(8,8)=8B,
+ // no inter-field gap, no tail padding).
+ // The element distance must be 12, not 16.
+ func.func @fold_packed_record(%arg0: !fir.box<!fir.type<tp<{i:i32,d:f64}>>>) -> index {
+ %0 = fir.box_elesize %arg0 : (!fir.box<!fir.type<tp<{i:i32,d:f64}>>>) -> index
+ return %0 : index
+ }
+ // CHECK-LABEL: func.func @fold_packed_record(
+ // CHECK: %[[C:.*]] = arith.constant 12 : index
+ // CHECK: return %[[C]]
+ // CHECK-NOT: fir.box_elesize
+
+ // Fold: packed derived type with a wider alignment gap.
+ // On x86-64: i32 store=4B, complex<f64> store=16B.
+ // Non-packed: alignTo(4,4)=4 + alignTo(4,8)+alignTo(16,8)=24, tail=24 -> 24B.
+ // Packed: 4 + 16 = 20B, align=1.
+ // The element distance must be 20, not 24.
+ func.func @fold_packed_record2(%arg0: !fir.box<!fir.type<tp2<{i:i32,z:complex<f64>}>>>) -> index {
+ %0 = fir.box_elesize %arg0 : (!fir.box<!fir.type<tp2<{i:i32,z:complex<f64>}>>>) -> index
+ return %0 : index
+ }
+ // CHECK-LABEL: func.func @fold_packed_record2(
+ // CHECK: %[[C:.*]] = arith.constant 20 : index
+ // CHECK: return %[[C]]
+ // CHECK-NOT: fir.box_elesize
+
+ // Fold: tail-padded record type -- fir.type<tpad{a:i32,b:i8}>.
+ // The field loop gives size=5, align=4; getTypeSizeAndAlignment returns
+ // {8, 4} (alignTo(5,4)=8). FoldBoxEleSize also rounded 5 to 8 before
+ // this fix, so both revisions fold to 8. This check verifies that the
+ // correct 8-byte element stride is produced; the distinction between
+ // allocation size and raw store size is covered by
+ // flang/test/Fir/CUDA/cuda-constructor-2.f90 and
+ // flang/test/Fir/CUDA/cuda-shared-offset.mlir.
+ // Use a distinct type name (tpad) to avoid redefining the packed type (tp)
+ // used above.
+ func.func @fold_tail_padded_record(%arg0: !fir.box<!fir.array<?x!fir.type<tpad{a:i32,b:i8}>>>) -> index {
+ %0 = fir.box_elesize %arg0 : (!fir.box<!fir.array<?x!fir.type<tpad{a:i32,b:i8}>>>) -> index
+ return %0 : index
+ }
+ // CHECK-LABEL: func.func @fold_tail_padded_record(
+ // CHECK: %[[C:.*]] = arith.constant 8 : index
+ // CHECK: return %[[C]]
+ // CHECK-NOT: fir.box_elesize
+
+ // Fold: packed derived type with f80 component.
+ // f80 on x86-64: store size = 10B, ABI alignment = 16B,
+ // allocation size = alignTo(10, 16) = 16B.
+ // i8: store size = 1B, ABI alignment = 1B, allocation size = 1B.
+ // Packed size = 16 + 1 = 17B (not 10 + 1 = 11B).
+ // This case distinguishes allocation-size from store-size in the packed path.
+ func.func @fold_packed_f80_i8(%arg0: !fir.box<!fir.type<tp3<{x:f80,b:i8}>>>) -> index {
+ %0 = fir.box_elesize %arg0 : (!fir.box<!fir.type<tp3<{x:f80,b:i8}>>>) -> index
+ return %0 : index
+ }
+ // CHECK-LABEL: func.func @fold_packed_f80_i8(
+ // CHECK: %[[C:.*]] = arith.constant 17 : index
----------------
MattPD wrote:
I am flagging a separate FIR-to-LLVM heap-allocation gap so it is tracked. At `de5ef3bc48d6`, `fir.allocmem !fir.type<tp3<{x:f80,b:i8}>>` lowers to `malloc(11)`, although LLVM places `b` at byte 16. Could the PR link an issue that tracks the allocation gap?
https://github.com/llvm/llvm-project/pull/220377
More information about the flang-commits
mailing list