[flang-commits] [flang] [Flang][Fir] Set default alignment to 64 on inlineAllocation for arrays (PR #208781)
Jason Van Beusekom via flang-commits
flang-commits at lists.llvm.org
Fri Jul 10 10:52:57 PDT 2026
https://github.com/Jason-Van-Beusekom updated https://github.com/llvm/llvm-project/pull/208781
>From 1f7444c91fe6a56e2e0906388294f932f30239bd Mon Sep 17 00:00:00 2001
From: Jason Van Beusekom <jason.van-beusekom at hpe.com>
Date: Fri, 10 Jul 2026 12:07:38 -0500
Subject: [PATCH 1/2] [Flang][Fir] Set default alignment to 64 on
inlineAllocation for arrays
---
.../include/flang/Optimizer/Dialect/FIROps.td | 3 +-
flang/lib/Optimizer/Builder/MutableBox.cpp | 6 +
flang/lib/Optimizer/CodeGen/CodeGen.cpp | 126 ++++++++++++++++++
flang/lib/Optimizer/Dialect/FIROps.cpp | 10 +-
flang/test/Fir/alloc-aligned-device.fir | 13 ++
flang/test/Fir/alloc-aligned-omp.fir | 14 ++
flang/test/Fir/alloc-aligned.fir | 34 +++++
flang/test/Fir/invalid.fir | 8 ++
flang/test/Lower/CUDA/cuda-allocatable.cuf | 2 +-
.../allocatable-and-pointer-status-change.f90 | 4 +-
flang/test/Lower/HLFIR/custom-intrinsic.f90 | 6 +-
.../HLFIR/intrinsic-dynamically-optional.f90 | 2 +-
.../test/Lower/Intrinsics/show_descriptor.f90 | 2 +-
flang/test/Lower/OpenACC/acc-declare.f90 | 2 +-
.../Lower/OpenMP/allocatable-array-bounds.f90 | 2 +-
.../parallel-reduction-allocatable-array.f90 | 2 +-
.../Lower/OpenMP/parallel-reduction-mixed.f90 | 2 +-
...oop-reduction-allocatable-array-minmax.f90 | 6 +-
18 files changed, 225 insertions(+), 19 deletions(-)
create mode 100644 flang/test/Fir/alloc-aligned-device.fir
create mode 100644 flang/test/Fir/alloc-aligned-omp.fir
create mode 100644 flang/test/Fir/alloc-aligned.fir
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index 445132168e42b..8ecdd5ec4ac1c 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -237,7 +237,8 @@ def fir_AllocMemOp : fir_Op<"allocmem", [AttrSizedOperandSegments]> {
OptionalAttr<StrAttr>:$uniq_name,
OptionalAttr<StrAttr>:$bindc_name,
Variadic<AnyIntegerType>:$typeparams,
- Variadic<AnyIntegerType>:$shape
+ Variadic<AnyIntegerType>:$shape,
+ OptionalAttr<I64Attr>:$alignment
);
let results = (outs Res<fir_HeapType, "", [MemAlloc<DefaultResource>]>:$res);
diff --git a/flang/lib/Optimizer/Builder/MutableBox.cpp b/flang/lib/Optimizer/Builder/MutableBox.cpp
index bcec49b3e3c8e..170fecf9bffa4 100644
--- a/flang/lib/Optimizer/Builder/MutableBox.cpp
+++ b/flang/lib/Optimizer/Builder/MutableBox.cpp
@@ -753,6 +753,9 @@ static mlir::Value allocateAndInitNewStorage(fir::FirOpBuilder &builder,
auto lengths = getNewLengths(builder, loc, box, lenParams);
auto newStorage = fir::AllocMemOp::create(builder, loc, box.getBaseTy(),
allocName, lengths, extents);
+
+ if (mlir::isa<fir::SequenceType>(box.getBaseTy()))
+ newStorage.setAlignment(fir::defaultArrayGlobalAlignment);
if (mlir::isa<fir::RecordType>(box.getEleTy())) {
// TODO: skip runtime initialization if this is not required. Currently,
// there is no way to know here if a derived type needs it or not. But the
@@ -776,6 +779,9 @@ void fir::factory::genInlinedAllocation(
safeExtents.push_back(fir::factory::genMaxWithZero(builder, loc, extent));
auto heap = fir::AllocMemOp::create(builder, loc, box.getBaseTy(), allocName,
lengths, safeExtents);
+
+ if (mlir::isa<fir::SequenceType>(box.getBaseTy()))
+ heap.setAlignment(fir::defaultArrayGlobalAlignment);
MutablePropertyWriter{builder, loc, box}.updateMutableBox(
heap, lbounds, safeExtents, lengths);
if (mlir::isa<fir::RecordType>(box.getEleTy())) {
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 74ad23a050fae..da605020f8853 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -1325,6 +1325,70 @@ static mlir::SymbolRefAttr getMalloc(fir::AllocMemOp op,
return getMallocInModule(mod, op, rewriter, indexType);
}
+template <typename ModuleOp>
+static mlir::SymbolRefAttr
+getAlignedAllocInModule(ModuleOp mod, fir::AllocMemOp op,
+ mlir::ConversionPatternRewriter &rewriter,
+ mlir::Type indexType) {
+ static constexpr char alignedAllocName[] = "aligned_alloc";
+ if (auto func =
+ mod.template lookupSymbol<mlir::LLVM::LLVMFuncOp>(alignedAllocName))
+ return mlir::SymbolRefAttr::get(func);
+ if (auto userFunc =
+ mod.template lookupSymbol<mlir::func::FuncOp>(alignedAllocName))
+ return mlir::SymbolRefAttr::get(userFunc);
+
+ mlir::OpBuilder moduleBuilder(mod.getBodyRegion());
+ auto alignedDecl = mlir::LLVM::LLVMFuncOp::create(
+ moduleBuilder, op.getLoc(), alignedAllocName,
+ mlir::LLVM::LLVMFunctionType::get(getLlvmPtrType(op.getContext()),
+ {indexType, indexType},
+ /*isVarArg=*/false));
+ return mlir::SymbolRefAttr::get(alignedDecl);
+}
+
+static mlir::SymbolRefAttr
+getAlignedAlloc(fir::AllocMemOp op, mlir::ConversionPatternRewriter &rewriter,
+ mlir::Type indexType) {
+ if (auto mod = op->getParentOfType<mlir::gpu::GPUModuleOp>())
+ return getAlignedAllocInModule(mod, op, rewriter, indexType);
+ auto mod = op->getParentOfType<mlir::ModuleOp>();
+ return getAlignedAllocInModule(mod, op, rewriter, indexType);
+}
+
+template <typename ModuleOp>
+static mlir::SymbolRefAttr
+getPosixMemalignInModule(ModuleOp mod, fir::AllocMemOp op,
+ mlir::ConversionPatternRewriter &rewriter,
+ mlir::Type indexType) {
+ static constexpr char posixMemalignName[] = "posix_memalign";
+ if (auto func =
+ mod.template lookupSymbol<mlir::LLVM::LLVMFuncOp>(posixMemalignName))
+ return mlir::SymbolRefAttr::get(func);
+ if (auto userFunc =
+ mod.template lookupSymbol<mlir::func::FuncOp>(posixMemalignName))
+ return mlir::SymbolRefAttr::get(userFunc);
+
+ // int posix_memalign(void **memptr, size_t alignment, size_t size);
+ mlir::OpBuilder moduleBuilder(mod.getBodyRegion());
+ auto decl = mlir::LLVM::LLVMFuncOp::create(
+ moduleBuilder, op.getLoc(), posixMemalignName,
+ mlir::LLVM::LLVMFunctionType::get(
+ mlir::IntegerType::get(op.getContext(), 32),
+ {getLlvmPtrType(op.getContext()), indexType, indexType},
+ /*isVarArg=*/false));
+ return mlir::SymbolRefAttr::get(decl);
+}
+
+static mlir::SymbolRefAttr
+getPosixMemalign(fir::AllocMemOp op, mlir::ConversionPatternRewriter &rewriter,
+ mlir::Type indexType) {
+ if (auto mod = op->getParentOfType<mlir::gpu::GPUModuleOp>())
+ return getPosixMemalignInModule(mod, op, rewriter, indexType);
+ auto mod = op->getParentOfType<mlir::ModuleOp>();
+ return getPosixMemalignInModule(mod, op, rewriter, indexType);
+}
+
/// Return value of the stride in bytes between adjacent elements
/// of LLVM type \p llTy. The result is returned as a value of
/// \p idxTy integer type.
@@ -1373,6 +1437,68 @@ struct AllocMemOpConversion : public fir::FIROpConversion<fir::AllocMemOp> {
mlir::IntegerType::get(rewriter.getContext(), mallocTyWidth);
if (mallocTyWidth != ity.getIntOrFloatBitWidth())
size = integerCast(loc, rewriter, mallocTy, size);
+
+ std::optional<uint64_t> alignment = heap.getAlignment();
+ if (alignment && *alignment > 16) {
+ auto mod = heap->getParentOfType<mlir::ModuleOp>();
+ llvm::Triple triple = mod ? fir::getTargetTriple(mod) : llvm::Triple{};
+ bool isGpu = heap->getParentOfType<mlir::gpu::GPUModuleOp>() != nullptr ||
+ triple.isNVPTX() || triple.isAMDGPU() || triple.isSPIRV();
+
+ if (!isGpu && !triple.isOSWindows()) {
+ mlir::Value alignVal = fir::genConstantIndex(
+ loc, mallocTy, rewriter, static_cast<std::int64_t>(*alignment));
+
+ if (triple.isOSDarwin()) {
+ // aligned_alloc requires macOS 10.15+, so use posix_memalign instead
+ mlir::Type ptrTy = ::getLlvmPtrType(heap.getContext());
+ mlir::Value memptr;
+ {
+ mlir::OpBuilder::InsertionGuard guard(rewriter);
+ mlir::Operation *parentOp =
+ rewriter.getInsertionBlock()->getParentOp();
+ mlir::Region *parentRegion =
+ rewriter.getInsertionBlock()->getParent();
+ mlir::Block *insertBlock =
+ getBlockForAllocaInsert(parentOp, parentRegion);
+ rewriter.setInsertionPointToStart(insertBlock);
+ mlir::Value one = fir::genConstantIndex(loc, mallocTy, rewriter, 1);
+ memptr =
+ mlir::LLVM::AllocaOp::create(rewriter, loc, ptrTy, ptrTy, one);
+ }
+ mlir::Value nullPtr =
+ mlir::LLVM::ZeroOp::create(rewriter, loc, ptrTy);
+ mlir::LLVM::StoreOp::create(rewriter, loc, nullPtr, memptr);
+ heap->setAttr("callee", getPosixMemalign(heap, rewriter, mallocTy));
+ mlir::LLVM::CallOp::create(
+ rewriter, loc,
+ mlir::TypeRange{
+ mlir::IntegerType::get(rewriter.getContext(), 32)},
+ mlir::ValueRange{memptr, alignVal, size},
+ addLLVMOpBundleAttrs(rewriter, heap->getAttrs(), 3));
+ mlir::Value newPtr =
+ mlir::LLVM::LoadOp::create(rewriter, loc, ptrTy, memptr);
+ rewriter.replaceOp(heap, newPtr);
+ return mlir::success();
+ }
+
+ mlir::Value alignMinusOne = fir::genConstantIndex(
+ loc, mallocTy, rewriter, static_cast<std::int64_t>(*alignment - 1));
+ mlir::Value sizePlus = mlir::LLVM::AddOp::create(
+ rewriter, loc, mallocTy, size, alignMinusOne);
+ mlir::Value div = mlir::LLVM::UDivOp::create(rewriter, loc, mallocTy,
+ sizePlus, alignVal);
+ mlir::Value roundedSize =
+ mlir::LLVM::MulOp::create(rewriter, loc, mallocTy, div, alignVal);
+ heap->setAttr("callee", getAlignedAlloc(heap, rewriter, mallocTy));
+ rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(
+ heap, ::getLlvmPtrType(heap.getContext()),
+ mlir::ValueRange{alignVal, roundedSize},
+ addLLVMOpBundleAttrs(rewriter, heap->getAttrs(), 2));
+ return mlir::success();
+ }
+ }
+
heap->setAttr("callee", getMalloc(heap, rewriter, mallocTy));
rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(
heap, ::getLlvmPtrType(heap.getContext()), size,
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index fd580f54f762b..34221654cb53a 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -444,7 +444,7 @@ void fir::AllocMemOp::build(mlir::OpBuilder &builder,
llvm::ArrayRef<mlir::NamedAttribute> attributes) {
auto nameAttr = builder.getStringAttr(uniqName);
build(builder, result, wrapAllocMemResultType(inType), inType, nameAttr, {},
- typeparams, shape);
+ typeparams, shape, /*alignment=*/{});
result.addAttributes(attributes);
}
@@ -456,7 +456,7 @@ void fir::AllocMemOp::build(mlir::OpBuilder &builder,
auto nameAttr = builder.getStringAttr(uniqName);
auto bindcAttr = builder.getStringAttr(bindcName);
build(builder, result, wrapAllocMemResultType(inType), inType, nameAttr,
- bindcAttr, typeparams, shape);
+ bindcAttr, typeparams, shape, /*alignment=*/{});
result.addAttributes(attributes);
}
@@ -465,7 +465,7 @@ void fir::AllocMemOp::build(mlir::OpBuilder &builder,
mlir::ValueRange typeparams, mlir::ValueRange shape,
llvm::ArrayRef<mlir::NamedAttribute> attributes) {
build(builder, result, wrapAllocMemResultType(inType), inType, {}, {},
- typeparams, shape);
+ typeparams, shape, /*alignment=*/{});
result.addAttributes(attributes);
}
@@ -489,6 +489,10 @@ llvm::LogicalResult fir::AllocMemOp::verify() {
return emitOpError("must be a !fir.heap type");
if (fir::isa_unknown_size_box(fir::dyn_cast_ptrEleTy(outType)))
return emitOpError("cannot allocate !fir.box of unknown rank or type");
+ if (std::optional<std::int64_t> alignment = getAlignment()) {
+ if (*alignment <= 0 || (*alignment & (*alignment - 1)) != 0)
+ return emitOpError("alignment must be a positive power of two");
+ }
return mlir::success();
}
diff --git a/flang/test/Fir/alloc-aligned-device.fir b/flang/test/Fir/alloc-aligned-device.fir
new file mode 100644
index 0000000000000..c988113b02cf2
--- /dev/null
+++ b/flang/test/Fir/alloc-aligned-device.fir
@@ -0,0 +1,13 @@
+
+// RUN: fir-opt --fir-to-llvm-ir %s | FileCheck %s
+
+gpu.module @cuda_device_mod {
+// CHECK-LABEL: llvm.func @allocmem_array_aligned_device
+// CHECK: llvm.call @malloc(%{{.*}}) {{.*}} : (i64) -> !llvm.ptr
+// CHECK-NOT: @aligned_alloc
+// CHECK-NOT: @posix_memalign
+ func.func @allocmem_array_aligned_device() -> !fir.heap<!fir.array<1000xf32>> {
+ %1 = fir.allocmem !fir.array<1000xf32> {alignment = 64 : i64}
+ return %1 : !fir.heap<!fir.array<1000xf32>>
+ }
+}
diff --git a/flang/test/Fir/alloc-aligned-omp.fir b/flang/test/Fir/alloc-aligned-omp.fir
new file mode 100644
index 0000000000000..f98806a64acc3
--- /dev/null
+++ b/flang/test/Fir/alloc-aligned-omp.fir
@@ -0,0 +1,14 @@
+// RUN: tco --target=aarch64-apple-darwin %s | FileCheck %s
+
+// CHECK-LABEL: define internal void @omp_region_aligned..omp_par(
+// CHECK: %[[MEMPTR:.*]] = alloca ptr, i64 1
+// CHECK: store ptr null, ptr %[[MEMPTR]]
+// CHECK: call i32 @posix_memalign(ptr %[[MEMPTR]], i64 64, i64 4000)
+func.func @omp_region_aligned() {
+ omp.parallel {
+ %1 = fir.allocmem !fir.array<1000xf32> {alignment = 64 : i64}
+ fir.freemem %1 : !fir.heap<!fir.array<1000xf32>>
+ omp.terminator
+ }
+ return
+}
diff --git a/flang/test/Fir/alloc-aligned.fir b/flang/test/Fir/alloc-aligned.fir
new file mode 100644
index 0000000000000..1f9f6d38a8468
--- /dev/null
+++ b/flang/test/Fir/alloc-aligned.fir
@@ -0,0 +1,34 @@
+// RUN: tco --target=x86_64-unknown-linux-gnu %s | FileCheck %s --check-prefixes=CHECK,POSIX
+// RUN: tco --target=aarch64-apple-darwin %s | FileCheck %s --check-prefixes=CHECK,DARWIN
+// RUN: tco --target=nvptx64-nvidia-cuda %s | FileCheck %s --check-prefixes=CHECK,FALLBACK
+// RUN: tco --target=amdgcn-amd-amdhsa %s | FileCheck %s --check-prefixes=CHECK,FALLBACK
+// RUN: tco --target=x86_64-pc-windows-msvc %s | FileCheck %s --check-prefixes=CHECK,FALLBACK
+
+// CHECK-LABEL: define ptr @allocmem_array_aligned(
+// POSIX: call ptr @aligned_alloc(i64 64, i64 4032)
+// DARWIN: %[[MEMPTR:.*]] = alloca ptr, i64 1
+// DARWIN: store ptr null, ptr %[[MEMPTR]]
+// DARWIN: %{{.*}} = call i32 @posix_memalign(ptr %[[MEMPTR]], i64 64, i64 4000)
+// DARWIN: %{{.*}} = load ptr, ptr %[[MEMPTR]]
+// FALLBACK: call ptr @malloc(i64 4000)
+func.func @allocmem_array_aligned() -> !fir.heap<!fir.array<1000xf32>> {
+ %1 = fir.allocmem !fir.array<1000xf32> {alignment = 64 : i64}
+ return %1 : !fir.heap<!fir.array<1000xf32>>
+}
+
+// CHECK-LABEL: define ptr @allocmem_array_dynamic_aligned(
+// DARWIN: %[[MEMPTR:.*]] = alloca ptr, i64 1
+// CHECK: %[[SIZE:.*]] = mul i64 4, %{{.*}}
+// CHECK: %[[NONZERO:.*]] = select i1 %{{.*}}, i64 %[[SIZE]], i64 1
+// POSIX: %[[PLUS:.*]] = add i64 %[[NONZERO]], 63
+// POSIX: %[[DIV:.*]] = udiv i64 %[[PLUS]], 64
+// POSIX: %[[ROUNDED:.*]] = mul i64 %[[DIV]], 64
+// POSIX: call ptr @aligned_alloc(i64 64, i64 %[[ROUNDED]])
+// DARWIN: store ptr null, ptr %[[MEMPTR]]
+// DARWIN: %{{.*}} = call i32 @posix_memalign(ptr %[[MEMPTR]], i64 64, i64 %[[NONZERO]])
+// DARWIN: %{{.*}} = load ptr, ptr %[[MEMPTR]]
+// FALLBACK: call ptr @malloc(i64 %[[NONZERO]])
+func.func @allocmem_array_dynamic_aligned(%n : index) -> !fir.heap<!fir.array<?xf32>> {
+ %1 = fir.allocmem !fir.array<?xf32>, %n {alignment = 64 : i64}
+ return %1 : !fir.heap<!fir.array<?xf32>>
+}
diff --git a/flang/test/Fir/invalid.fir b/flang/test/Fir/invalid.fir
index 5471bcd8acc29..2b63da1b8dd28 100644
--- a/flang/test/Fir/invalid.fir
+++ b/flang/test/Fir/invalid.fir
@@ -1556,3 +1556,11 @@ func.func @logical_or_float(%a: f32, %b: f32) {
%0 = fir.logical_or %a, %b : f32
return
}
+
+// -----
+
+func.func @allocmem_bad_alignment() -> !fir.heap<!fir.array<10xf32>> {
+ // expected-error at +1 {{'fir.allocmem' op alignment must be a positive power of two}}
+ %0 = fir.allocmem !fir.array<10xf32> {alignment = 3 : i64}
+ return %0 : !fir.heap<!fir.array<10xf32>>
+}
diff --git a/flang/test/Lower/CUDA/cuda-allocatable.cuf b/flang/test/Lower/CUDA/cuda-allocatable.cuf
index 5954bd5c2cbf6..a485e8c619349 100644
--- a/flang/test/Lower/CUDA/cuda-allocatable.cuf
+++ b/flang/test/Lower/CUDA/cuda-allocatable.cuf
@@ -184,7 +184,7 @@ end subroutine
! CHECK-LABEL: func.func @_QPsub8() attributes {cuf.proc_attr = #cuf.cuda_proc<global>}
! CHECK: %[[DESC:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub8Ea"}
! CHECK: %[[A:.*]]:2 = hlfir.declare %[[DESC]] {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub8Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
-! CHECK: %[[HEAP:.*]] = fir.allocmem !fir.array<?xf32>, %{{.*}} {fir.must_be_heap = true, uniq_name = "_QFsub8Ea.alloc"}
+! CHECK: %[[HEAP:.*]] = fir.allocmem !fir.array<?xf32>, %{{.*}} {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFsub8Ea.alloc"}
! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[EMBOX:.*]] = fir.embox %[[HEAP]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
! CHECK: fir.store %[[EMBOX]] to %[[A]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
diff --git a/flang/test/Lower/HLFIR/allocatable-and-pointer-status-change.f90 b/flang/test/Lower/HLFIR/allocatable-and-pointer-status-change.f90
index 0c57b201b4646..992c2f53b0687 100644
--- a/flang/test/Lower/HLFIR/allocatable-and-pointer-status-change.f90
+++ b/flang/test/Lower/HLFIR/allocatable-and-pointer-status-change.f90
@@ -20,7 +20,7 @@ subroutine allocation(x)
! CHECK: %[[VAL_12:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_13:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[VAL_12]] : index
! CHECK: %[[VAL_14:.*]] = arith.select %[[VAL_13]], %[[VAL_11]], %[[VAL_12]] : index
-! CHECK: %[[VAL_15:.*]] = fir.allocmem !fir.array<?x!fir.char<1,?>>(%[[VAL_2]] : index), %[[VAL_14]] {fir.must_be_heap = true, uniq_name = "_QFallocationEx.alloc"}
+! CHECK: %[[VAL_15:.*]] = fir.allocmem !fir.array<?x!fir.char<1,?>>(%[[VAL_2]] : index), %[[VAL_14]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFallocationEx.alloc"}
! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_14]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_17:.*]] = fir.embox %[[VAL_15]](%[[VAL_16]]) typeparams %[[VAL_2]] : (!fir.heap<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>
! CHECK: fir.store %[[VAL_17]] to %[[VAL_3]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
@@ -90,7 +90,7 @@ subroutine alloc_comp(x)
! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_10:.*]] = arith.cmpi sgt, %[[VAL_8]], %[[VAL_9]] : index
! CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_10]], %[[VAL_8]], %[[VAL_9]] : index
-! CHECK: %[[VAL_12:.*]] = fir.allocmem !fir.array<?xf32>, %[[VAL_11]] {fir.must_be_heap = true, uniq_name = "_QFalloc_compEa.alloc"}
+! CHECK: %[[VAL_12:.*]] = fir.allocmem !fir.array<?xf32>, %[[VAL_11]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFalloc_compEa.alloc"}
! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_11]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_14:.*]] = fir.embox %[[VAL_12]](%[[VAL_13]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
! CHECK: fir.store %[[VAL_14]] to %[[VAL_6]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
diff --git a/flang/test/Lower/HLFIR/custom-intrinsic.f90 b/flang/test/Lower/HLFIR/custom-intrinsic.f90
index 294077105ed7b..cb894cadd5e26 100644
--- a/flang/test/Lower/HLFIR/custom-intrinsic.f90
+++ b/flang/test/Lower/HLFIR/custom-intrinsic.f90
@@ -705,7 +705,7 @@ subroutine allocatables_test(a, b, c)
! CHECK: %[[VAL_24:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_25:.*]] = arith.cmpi sgt, %[[VAL_17]], %[[VAL_24]] : index
! CHECK: %[[VAL_26:.*]] = arith.select %[[VAL_25]], %[[VAL_17]], %[[VAL_24]] : index
-! CHECK: %[[VAL_27:.*]] = fir.allocmem !fir.array<?x?x?xi32>, %[[VAL_20]], %[[VAL_23]], %[[VAL_26]] {fir.must_be_heap = true, uniq_name = "_QFallocatables_testEa.alloc"}
+! CHECK: %[[VAL_27:.*]] = fir.allocmem !fir.array<?x?x?xi32>, %[[VAL_20]], %[[VAL_23]], %[[VAL_26]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFallocatables_testEa.alloc"}
! CHECK: %[[VAL_28:.*]] = fir.shape %[[VAL_20]], %[[VAL_23]], %[[VAL_26]] : (index, index, index) -> !fir.shape<3>
! CHECK: %[[VAL_29:.*]] = fir.embox %[[VAL_27]](%[[VAL_28]]) : (!fir.heap<!fir.array<?x?x?xi32>>, !fir.shape<3>) -> !fir.box<!fir.heap<!fir.array<?x?x?xi32>>>
! CHECK: fir.store %[[VAL_29]] to %[[VAL_3]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
@@ -724,7 +724,7 @@ subroutine allocatables_test(a, b, c)
! CHECK: %[[VAL_42:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_43:.*]] = arith.cmpi sgt, %[[VAL_35]], %[[VAL_42]] : index
! CHECK: %[[VAL_44:.*]] = arith.select %[[VAL_43]], %[[VAL_35]], %[[VAL_42]] : index
-! CHECK: %[[VAL_45:.*]] = fir.allocmem !fir.array<?x?x?xi32>, %[[VAL_38]], %[[VAL_41]], %[[VAL_44]] {fir.must_be_heap = true, uniq_name = "_QFallocatables_testEb.alloc"}
+! CHECK: %[[VAL_45:.*]] = fir.allocmem !fir.array<?x?x?xi32>, %[[VAL_38]], %[[VAL_41]], %[[VAL_44]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFallocatables_testEb.alloc"}
! CHECK: %[[VAL_46:.*]] = fir.shape %[[VAL_38]], %[[VAL_41]], %[[VAL_44]] : (index, index, index) -> !fir.shape<3>
! CHECK: %[[VAL_47:.*]] = fir.embox %[[VAL_45]](%[[VAL_46]]) : (!fir.heap<!fir.array<?x?x?xi32>>, !fir.shape<3>) -> !fir.box<!fir.heap<!fir.array<?x?x?xi32>>>
! CHECK: fir.store %[[VAL_47]] to %[[VAL_4]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
@@ -743,7 +743,7 @@ subroutine allocatables_test(a, b, c)
! CHECK: %[[VAL_60:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_61:.*]] = arith.cmpi sgt, %[[VAL_53]], %[[VAL_60]] : index
! CHECK: %[[VAL_62:.*]] = arith.select %[[VAL_61]], %[[VAL_53]], %[[VAL_60]] : index
-! CHECK: %[[VAL_63:.*]] = fir.allocmem !fir.array<?x?x?xi32>, %[[VAL_56]], %[[VAL_59]], %[[VAL_62]] {fir.must_be_heap = true, uniq_name = "_QFallocatables_testEc.alloc"}
+! CHECK: %[[VAL_63:.*]] = fir.allocmem !fir.array<?x?x?xi32>, %[[VAL_56]], %[[VAL_59]], %[[VAL_62]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFallocatables_testEc.alloc"}
! CHECK: %[[VAL_64:.*]] = fir.shape %[[VAL_56]], %[[VAL_59]], %[[VAL_62]] : (index, index, index) -> !fir.shape<3>
! CHECK: %[[VAL_65:.*]] = fir.embox %[[VAL_63]](%[[VAL_64]]) : (!fir.heap<!fir.array<?x?x?xi32>>, !fir.shape<3>) -> !fir.box<!fir.heap<!fir.array<?x?x?xi32>>>
! CHECK: fir.store %[[VAL_65]] to %[[VAL_5]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
diff --git a/flang/test/Lower/HLFIR/intrinsic-dynamically-optional.f90 b/flang/test/Lower/HLFIR/intrinsic-dynamically-optional.f90
index 79cc58d940711..ee35a681172a4 100644
--- a/flang/test/Lower/HLFIR/intrinsic-dynamically-optional.f90
+++ b/flang/test/Lower/HLFIR/intrinsic-dynamically-optional.f90
@@ -128,7 +128,7 @@ subroutine test_optional_as_addr
! CHECK: %[[C0_2:.*]] = arith.constant 0 : index
! CHECK: %[[CMPI:.*]] = arith.cmpi sgt, %[[C20]], %[[C0_2]] : index
! CHECK: %[[ALLOC_SZ:.*]] = arith.select %[[CMPI]], %[[C20]], %[[C0_2]] : index
-! CHECK: %[[FROM_ALLOC:.*]] = fir.allocmem !fir.array<?xi32>, %[[ALLOC_SZ]] {fir.must_be_heap = true, uniq_name = "_QFtest_optional_as_addrEfrom.alloc"}
+! CHECK: %[[FROM_ALLOC:.*]] = fir.allocmem !fir.array<?xi32>, %[[ALLOC_SZ]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFtest_optional_as_addrEfrom.alloc"}
! CHECK: %[[FROM_SHAPE:.*]] = fir.shape %[[ALLOC_SZ]] : (index) -> !fir.shape<1>
! CHECK: %[[FROM_BOX:.*]] = fir.embox %[[FROM_ALLOC]](%[[FROM_SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
! CHECK: fir.store %[[FROM_BOX]] to %[[FROM_VAR]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
diff --git a/flang/test/Lower/Intrinsics/show_descriptor.f90 b/flang/test/Lower/Intrinsics/show_descriptor.f90
index e4e61efab11f2..f9daa25f9ffac 100644
--- a/flang/test/Lower/Intrinsics/show_descriptor.f90
+++ b/flang/test/Lower/Intrinsics/show_descriptor.f90
@@ -26,7 +26,7 @@ subroutine test_int
! CHECK: %[[LOAD_0:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_0]] : (i32) -> index
! CHECK: %[[SELECT_0:.*]] = arith.maxsi %[[CONVERT_0]], %[[C0]] : index
-! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[SELECT_0]] {fir.must_be_heap = true, uniq_name = "_QMtest_show_descriptorFtest_intEa.alloc"}
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[SELECT_0]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QMtest_show_descriptorFtest_intEa.alloc"}
call show_descriptor(a)
! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[SELECT_0]] : (index) -> !fir.shape<1>
diff --git a/flang/test/Lower/OpenACC/acc-declare.f90 b/flang/test/Lower/OpenACC/acc-declare.f90
index 3339fa31c3d27..349f5c84d5316 100644
--- a/flang/test/Lower/OpenACC/acc-declare.f90
+++ b/flang/test/Lower/OpenACC/acc-declare.f90
@@ -248,7 +248,7 @@ subroutine acc_declare_allocate()
allocate(a(100))
-! CHECK: %{{.*}} = fir.allocmem !fir.array<?xi32>, %{{.*}} {fir.must_be_heap = true, uniq_name = "_QMacc_declareFacc_declare_allocateEa.alloc"}
+! CHECK: %{{.*}} = fir.allocmem !fir.array<?xi32>, %{{.*}} {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QMacc_declareFacc_declare_allocateEa.alloc"}
! CHECK: fir.store %{{.*}} to %{{.*}} {acc.declare_action = #acc.declare_action<postAlloc = @_QMacc_declareFacc_declare_allocateEa_acc_declare_post_alloc>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
deallocate(a)
diff --git a/flang/test/Lower/OpenMP/allocatable-array-bounds.f90 b/flang/test/Lower/OpenMP/allocatable-array-bounds.f90
index 03e892059bfec..3aca7118ef63a 100644
--- a/flang/test/Lower/OpenMP/allocatable-array-bounds.f90
+++ b/flang/test/Lower/OpenMP/allocatable-array-bounds.f90
@@ -96,7 +96,7 @@ end module assumed_allocatable_array_routines
!HOST-LABEL: func.func @_QPcall_assumed_shape_and_size_array() {
!HOST: %[[ALLOCA:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "arr_read_write", uniq_name = "_QFcall_assumed_shape_and_size_arrayEarr_read_write"}
!HOST: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFcall_assumed_shape_and_size_arrayEarr_read_write"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
-!HOST: %[[ALLOCA_MEM:.*]] = fir.allocmem !fir.array<?xi32>, %{{.*}} {fir.must_be_heap = true, uniq_name = "_QFcall_assumed_shape_and_size_arrayEarr_read_write.alloc"}
+!HOST: %[[ALLOCA_MEM:.*]] = fir.allocmem !fir.array<?xi32>, %{{.*}} {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFcall_assumed_shape_and_size_arrayEarr_read_write.alloc"}
!HOST: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
!HOST: %[[EMBOX:.*]] = fir.embox %[[ALLOCA_MEM]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
!HOST: fir.store %[[EMBOX]] to %[[DECLARE]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
diff --git a/flang/test/Lower/OpenMP/parallel-reduction-allocatable-array.f90 b/flang/test/Lower/OpenMP/parallel-reduction-allocatable-array.f90
index f56875dcb518b..69b8c1cb6abfd 100644
--- a/flang/test/Lower/OpenMP/parallel-reduction-allocatable-array.f90
+++ b/flang/test/Lower/OpenMP/parallel-reduction-allocatable-array.f90
@@ -89,7 +89,7 @@ program reduce
! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_7:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[VAL_6]] : index
! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_5]], %[[VAL_6]] : index
-! CHECK: %[[VAL_9:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_8]] {fir.must_be_heap = true, uniq_name = "_QFEr.alloc"}
+! CHECK: %[[VAL_9:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_8]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFEr.alloc"}
! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_8]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_9]](%[[VAL_10]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
! CHECK: fir.store %[[VAL_11]] to %[[VAL_3]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
diff --git a/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90 b/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90
index 17ee6d0cf6610..0c90ca951ae17 100644
--- a/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90
+++ b/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90
@@ -36,7 +36,7 @@ end subroutine proc
!CHECK: [[MALLOC_BB]]:
!CHECK-NOT: omp.par.{{.*}}:
-!CHECK: call ptr @malloc(i{{(32)|(64)}} 80)
+!CHECK: call ptr @aligned_alloc(i{{(32)|(64)}} 64, i{{(32)|(64)}} 128)
!CHECK: %[[RED_ARR_0:.*]] = getelementptr inbounds [2 x ptr], ptr %red.array, i64 0, i64 0
!CHECK: store ptr %[[F_priv]], ptr %[[RED_ARR_0:.*]]
diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90
index 630bd46863c0e..07b472ed2ee5c 100644
--- a/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90
+++ b/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90
@@ -170,7 +170,7 @@ program reduce15
! CHECK: %[[VAL_12:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_13:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[VAL_12]] : index
! CHECK: %[[VAL_14:.*]] = arith.select %[[VAL_13]], %[[VAL_11]], %[[VAL_12]] : index
-! CHECK: %[[VAL_15:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_14]] {fir.must_be_heap = true, uniq_name = "_QFEarr.alloc"}
+! CHECK: %[[VAL_15:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_14]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFEarr.alloc"}
! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_14]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_17:.*]] = fir.embox %[[VAL_15]](%[[VAL_16]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
! CHECK: fir.store %[[VAL_17]] to %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
@@ -179,7 +179,7 @@ program reduce15
! CHECK: %[[VAL_20:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_21:.*]] = arith.cmpi sgt, %[[VAL_19]], %[[VAL_20]] : index
! CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_21]], %[[VAL_19]], %[[VAL_20]] : index
-! CHECK: %[[VAL_23:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_22]] {fir.must_be_heap = true, uniq_name = "_QFEmaxes.alloc"}
+! CHECK: %[[VAL_23:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_22]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFEmaxes.alloc"}
! CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_22]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_23]](%[[VAL_24]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
! CHECK: fir.store %[[VAL_25]] to %[[VAL_5]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
@@ -188,7 +188,7 @@ program reduce15
! CHECK: %[[VAL_28:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_29:.*]] = arith.cmpi sgt, %[[VAL_27]], %[[VAL_28]] : index
! CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_29]], %[[VAL_27]], %[[VAL_28]] : index
-! CHECK: %[[VAL_31:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_30]] {fir.must_be_heap = true, uniq_name = "_QFEmins.alloc"}
+! CHECK: %[[VAL_31:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_30]] {alignment = 64 : i64, fir.must_be_heap = true, uniq_name = "_QFEmins.alloc"}
! CHECK: %[[VAL_32:.*]] = fir.shape %[[VAL_30]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_33:.*]] = fir.embox %[[VAL_31]](%[[VAL_32]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
! CHECK: fir.store %[[VAL_33]] to %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
>From f0c06c8a50b6d1c08569ae74d0f25644a0124a20 Mon Sep 17 00:00:00 2001
From: Jason Van Beusekom <jason.van-beusekom at hpe.com>
Date: Fri, 10 Jul 2026 12:52:41 -0500
Subject: [PATCH 2/2] windows test fix
---
flang/test/Lower/OpenMP/parallel-reduction-mixed.f90 | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90 b/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90
index 0c90ca951ae17..cf3f73b17060d 100644
--- a/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90
+++ b/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90
@@ -2,7 +2,7 @@
!! to LLVM-IR code.
! RUN: %flang_fc1 -emit-llvm -fopenmp -o - %s 2>&1 \
-! RUN: | FileCheck %s
+! RUN: | FileCheck %s --check-prefixes=CHECK,%if system-windows %{WINDOWS%} %else %{%if system-darwin %{DARWIN%} %else %{POSIX%}%}
subroutine proc
implicit none
@@ -36,7 +36,9 @@ end subroutine proc
!CHECK: [[MALLOC_BB]]:
!CHECK-NOT: omp.par.{{.*}}:
-!CHECK: call ptr @aligned_alloc(i{{(32)|(64)}} 64, i{{(32)|(64)}} 128)
+!POSIX: call ptr @aligned_alloc(i{{(32)|(64)}} 64, i{{(32)|(64)}} 128)
+!WINDOWS: call ptr @malloc(i{{(32)|(64)}} 80)
+!DARWIN: call i32 @posix_memalign(ptr %{{.*}}, i{{(32)|(64)}} 64, i{{(32)|(64)}} 80)
!CHECK: %[[RED_ARR_0:.*]] = getelementptr inbounds [2 x ptr], ptr %red.array, i64 0, i64 0
!CHECK: store ptr %[[F_priv]], ptr %[[RED_ARR_0:.*]]
More information about the flang-commits
mailing list