[flang-commits] [flang] [flang][acc] fix allocatable logical reduction (PR #177177)
via flang-commits
flang-commits at lists.llvm.org
Wed Jan 21 06:28:20 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: None (jeanPerier)
<details>
<summary>Changes</summary>
The value types were not properly unwrapped from the variable type in `getReductionInitValue`, which caused issues with logical reductions on allocatables or pointers.
---
Full diff: https://github.com/llvm/llvm-project/pull/177177.diff
2 Files Affected:
- (modified) flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp (+3-15)
- (modified) flang/test/Lower/OpenACC/acc-reduction.f90 (+44)
``````````diff
diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp
index 322577f8014fc..5199271da3a2a 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp
@@ -330,8 +330,9 @@ static R getReductionInitValue(mlir::acc::ReductionOperator op, mlir::Type ty) {
/// Return a constant with the initial value for the reduction operator and
/// type combination.
static mlir::Value getReductionInitValue(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Type ty,
+ mlir::Location loc, mlir::Type varType,
mlir::acc::ReductionOperator op) {
+ mlir::Type ty = fir::getFortranElementType(varType);
if (op == mlir::acc::ReductionOperator::AccLand ||
op == mlir::acc::ReductionOperator::AccLor ||
op == mlir::acc::ReductionOperator::AccEqv ||
@@ -369,19 +370,6 @@ static mlir::Value getReductionInitValue(fir::FirOpBuilder &builder,
return fir::factory::Complex{builder, loc}.createComplex(cmplxTy, realInit,
imagInit);
}
-
- if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(ty))
- return getReductionInitValue(builder, loc, seqTy.getEleTy(), op);
-
- if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(ty))
- return getReductionInitValue(builder, loc, boxTy.getEleTy(), op);
-
- if (auto heapTy = mlir::dyn_cast<fir::HeapType>(ty))
- return getReductionInitValue(builder, loc, heapTy.getEleTy(), op);
-
- if (auto ptrTy = mlir::dyn_cast<fir::PointerType>(ty))
- return getReductionInitValue(builder, loc, ptrTy.getEleTy(), op);
-
llvm::report_fatal_error("Unsupported OpenACC reduction type");
}
@@ -491,7 +479,7 @@ static RecipeOp genRecipeOp(
mlir::Value initValue;
if constexpr (std::is_same_v<RecipeOp, mlir::acc::ReductionRecipeOp>) {
assert(op != mlir::acc::ReductionOperator::AccNone);
- initValue = getReductionInitValue(builder, loc, fir::unwrapRefType(ty), op);
+ initValue = getReductionInitValue(builder, loc, ty, op);
}
// Since we reuse the same recipe for all variables of the same type - we
diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90
index 1981b01aa45d1..339a4e3435c0d 100644
--- a/flang/test/Lower/OpenACC/acc-reduction.f90
+++ b/flang/test/Lower/OpenACC/acc-reduction.f90
@@ -2,6 +2,41 @@
! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
+! CHECK-LABEL: acc.reduction.recipe @reduction_lor_ref_box_heap_l32 : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>> reduction_operator <lor> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>):
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant false
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<!fir.logical<4>>>) -> !fir.heap<!fir.logical<4>>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.logical<4> {bindc_name = "acc.reduction.init", uniq_name = ""}
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCMEM_0]] temporary_lhs : i1, !fir.heap<!fir.logical<4>>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap<!fir.logical<4>>) -> !fir.box<!fir.heap<!fir.logical<4>>>
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<!fir.logical<4>>>
+! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
+
+! CHECK-LABEL: } combiner {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>):
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<!fir.logical<4>>>) -> !fir.heap<!fir.logical<4>>
+! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
+! CHECK: %[[BOX_ADDR_1:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.heap<!fir.logical<4>>>) -> !fir.heap<!fir.logical<4>>
+! CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.heap<!fir.logical<4>>
+! CHECK: %[[LOAD_3:.*]] = fir.load %[[BOX_ADDR_1]] : !fir.heap<!fir.logical<4>>
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_3]] : (!fir.logical<4>) -> i1
+! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[LOAD_2]] : (!fir.logical<4>) -> i1
+! CHECK: %[[ORI_0:.*]] = arith.ori %[[CONVERT_0]], %[[CONVERT_1]] : i1
+! CHECK: %[[CONVERT_2:.*]] = fir.convert %[[ORI_0]] : (i1) -> !fir.logical<4>
+! CHECK: hlfir.assign %[[CONVERT_2]] to %[[BOX_ADDR_1]] : !fir.logical<4>, !fir.heap<!fir.logical<4>>
+! CHECK: acc.yield %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
+
+! CHECK-LABEL: } destroy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>):
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<!fir.logical<4>>>) -> !fir.heap<!fir.logical<4>>
+! CHECK: fir.freemem %[[BOX_ADDR_0]] : !fir.heap<!fir.logical<4>>
+! CHECK: acc.terminator
+! CHECK: }
+
! CHECK-LABEL: acc.reduction.recipe @reduction_max_box_UxUxf32 : !fir.box<!fir.array<?x?xf32>> reduction_operator <max> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?x?xf32>>):
! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1.401300e-45 : f32
@@ -1840,3 +1875,12 @@ subroutine acc_reduction_max_dynamic_extent_max(a, n)
! CHECK: %[[DECL_A:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFacc_reduction_max_dynamic_extent_maxEa"} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>, !fir.dscope) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
! CHECK: %[[RED:.*]] = acc.reduction var(%[[DECL_A]]#0 : !fir.box<!fir.array<?x?xf32>>) recipe(@reduction_max_box_UxUxf32) -> !fir.box<!fir.array<?x?xf32>> {name = "a"}
! CHECK: acc.parallel reduction(%[[RED]] : !fir.box<!fir.array<?x?xf32>>)
+
+subroutine acc_reduction_logical_allocatable(l)
+ logical, allocatable :: l
+ !$acc parallel reduction(.or.:l)
+ !$acc end parallel
+end subroutine
+! CHECK-LABEL: func.func @_QPacc_reduction_logical_allocatable(
+! CHECK: %[[REDUCTION_0:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>) recipe(@reduction_lor_ref_box_heap_l32) -> !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>> {name = "l"}
+! CHECK: acc.parallel reduction(%[[REDUCTION_0]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>)
``````````
</details>
https://github.com/llvm/llvm-project/pull/177177
More information about the flang-commits
mailing list