Skip to content

Commit 15d8576

Browse files
authored
[Flang][OpenMP] Support lowering of simd reductions (#112194)
This patch enables lowering to MLIR of the reduction clause of `simd` constructs. Lowering from MLIR to LLVM IR remains unimplemented, so at that stage it will result in errors being emitted rather than silently ignoring it as it is currently done. On composite `do simd` constructs, this lowering error will remain untriggered, as the `omp.simd` operation in that case is currently ignored. The MLIR representation, however, will now contain `reduction` information.
1 parent b5cc222 commit 15d8576

File tree

4 files changed

+57
-12
lines changed

4 files changed

+57
-12
lines changed

flang/lib/Lower/OpenMP/OpenMP.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -2070,7 +2070,9 @@ static void genStandaloneSimd(lower::AbstractConverter &converter,
20702070
loopNestClauseOps, iv);
20712071

20722072
EntryBlockArgs simdArgs;
2073-
// TODO: Add private, reduction syms and vars.
2073+
// TODO: Add private syms and vars.
2074+
simdArgs.reduction.syms = simdReductionSyms;
2075+
simdArgs.reduction.vars = simdClauseOps.reductionVars;
20742076
auto simdOp =
20752077
genWrapperOp<mlir::omp::SimdOp>(converter, loc, simdClauseOps, simdArgs);
20762078

@@ -2228,7 +2230,9 @@ static void genCompositeDistributeParallelDoSimd(
22282230
wsloopOp.setComposite(/*val=*/true);
22292231

22302232
EntryBlockArgs simdArgs;
2231-
// TODO: Add private, reduction syms and vars.
2233+
// TODO: Add private syms and vars.
2234+
simdArgs.reduction.syms = simdReductionSyms;
2235+
simdArgs.reduction.vars = simdClauseOps.reductionVars;
22322236
auto simdOp =
22332237
genWrapperOp<mlir::omp::SimdOp>(converter, loc, simdClauseOps, simdArgs);
22342238
simdOp.setComposite(/*val=*/true);
@@ -2285,7 +2289,9 @@ static void genCompositeDistributeSimd(lower::AbstractConverter &converter,
22852289
distributeOp.setComposite(/*val=*/true);
22862290

22872291
EntryBlockArgs simdArgs;
2288-
// TODO: Add private, reduction syms and vars.
2292+
// TODO: Add private syms and vars.
2293+
simdArgs.reduction.syms = simdReductionSyms;
2294+
simdArgs.reduction.vars = simdClauseOps.reductionVars;
22892295
auto simdOp =
22902296
genWrapperOp<mlir::omp::SimdOp>(converter, loc, simdClauseOps, simdArgs);
22912297
simdOp.setComposite(/*val=*/true);
@@ -2342,7 +2348,9 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter,
23422348
wsloopOp.setComposite(/*val=*/true);
23432349

23442350
EntryBlockArgs simdArgs;
2345-
// TODO: Add private, reduction syms and vars.
2351+
// TODO: Add private syms and vars.
2352+
simdArgs.reduction.syms = simdReductionSyms;
2353+
simdArgs.reduction.vars = simdClauseOps.reductionVars;
23462354
auto simdOp =
23472355
genWrapperOp<mlir::omp::SimdOp>(converter, loc, simdClauseOps, simdArgs);
23482356
simdOp.setComposite(/*val=*/true);

flang/test/Lower/OpenMP/simd.f90

+24
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
! RUN: %flang_fc1 -flang-experimental-hlfir -emit-hlfir -fopenmp -fopenmp-version=50 %s -o - | FileCheck %s
55
! RUN: bbc -hlfir -emit-hlfir -fopenmp -fopenmp-version=50 %s -o - | FileCheck %s
66

7+
!CHECK: omp.declare_reduction @[[REDUCER:.*]] : i32
8+
79
!CHECK-LABEL: func @_QPsimd()
810
subroutine simd
911
integer :: i
@@ -273,3 +275,25 @@ subroutine lastprivate_with_simd
273275
sum = i + 1
274276
end do
275277
end subroutine
278+
279+
!CHECK-LABEL: func @_QPsimd_with_reduction_clause()
280+
subroutine simd_with_reduction_clause
281+
integer :: i, x
282+
x = 0
283+
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
284+
! CHECK-NEXT: %[[UB:.*]] = arith.constant 9 : i32
285+
! CHECK-NEXT: %[[STEP:.*]] = arith.constant 1 : i32
286+
! CHECK-NEXT: omp.simd reduction(@[[REDUCER]] %[[X:.*]]#0 -> %[[X_RED:.*]] : !fir.ref<i32>) {
287+
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
288+
!$omp simd reduction(+:x)
289+
do i=1, 9
290+
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X_RED]] {uniq_name = "_QFsimd_with_reduction_clauseEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
291+
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref<i32>
292+
! CHECK: %[[X_LD:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i32>
293+
! CHECK: %[[I_LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref<i32>
294+
! CHECK: %[[SUM:.*]] = arith.addi %[[X_LD]], %[[I_LD]] : i32
295+
! CHECK: hlfir.assign %[[SUM]] to %[[X_DECL]]#0 : i32, !fir.ref<i32>
296+
x = x+i
297+
end do
298+
!$OMP end simd
299+
end subroutine

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -2012,14 +2012,16 @@ void SimdOp::build(OpBuilder &builder, OperationState &state,
20122012
const SimdOperands &clauses) {
20132013
MLIRContext *ctx = builder.getContext();
20142014
// TODO Store clauses in op: linearVars, linearStepVars, privateVars,
2015-
// privateSyms, reductionVars, reductionByref, reductionSyms.
2015+
// privateSyms.
20162016
SimdOp::build(builder, state, clauses.alignedVars,
20172017
makeArrayAttr(ctx, clauses.alignments), clauses.ifExpr,
20182018
/*linear_vars=*/{}, /*linear_step_vars=*/{},
20192019
clauses.nontemporalVars, clauses.order, clauses.orderMod,
20202020
/*private_vars=*/{}, /*private_syms=*/nullptr,
2021-
/*reduction_vars=*/{}, /*reduction_byref=*/nullptr,
2022-
/*reduction_syms=*/nullptr, clauses.safelen, clauses.simdlen);
2021+
clauses.reductionVars,
2022+
makeDenseBoolArrayAttr(ctx, clauses.reductionByref),
2023+
makeArrayAttr(ctx, clauses.reductionSyms), clauses.safelen,
2024+
clauses.simdlen);
20232025
}
20242026

20252027
LogicalResult SimdOp::verify() {

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

+16-5
Original file line numberDiff line numberDiff line change
@@ -1785,18 +1785,29 @@ convertOrderKind(std::optional<omp::ClauseOrderKind> o) {
17851785
llvm_unreachable("Unknown ClauseOrderKind kind");
17861786
}
17871787

1788+
static LogicalResult simdOpSupported(omp::SimdOp op) {
1789+
if (!op.getLinearVars().empty() || !op.getLinearStepVars().empty())
1790+
return op.emitError("linear clause not yet supported");
1791+
1792+
if (!op.getPrivateVars().empty() || op.getPrivateSyms())
1793+
return op.emitError("privatization clauses not yet supported");
1794+
1795+
if (!op.getReductionVars().empty() || op.getReductionByref() ||
1796+
op.getReductionSyms())
1797+
return op.emitError("reduction clause not yet supported");
1798+
1799+
return success();
1800+
}
1801+
17881802
/// Converts an OpenMP simd loop into LLVM IR using OpenMPIRBuilder.
17891803
static LogicalResult
17901804
convertOmpSimd(Operation &opInst, llvm::IRBuilderBase &builder,
17911805
LLVM::ModuleTranslation &moduleTranslation) {
17921806
auto simdOp = cast<omp::SimdOp>(opInst);
17931807
auto loopOp = cast<omp::LoopNestOp>(simdOp.getWrappedLoop());
17941808

1795-
if (!simdOp.getLinearVars().empty() || !simdOp.getLinearStepVars().empty() ||
1796-
!simdOp.getPrivateVars().empty() || simdOp.getPrivateSyms() ||
1797-
!simdOp.getReductionVars().empty() || simdOp.getReductionByref() ||
1798-
simdOp.getReductionSyms())
1799-
return opInst.emitError("unhandled clauses for translation to LLVM IR");
1809+
if (failed(simdOpSupported(simdOp)))
1810+
return failure();
18001811

18011812
llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder);
18021813

0 commit comments

Comments
 (0)