[flang-commits] [flang] [llvm] [mlir] [flang][OpenMP] Lower target in_reduction (PR #199967)
Sairudra More via flang-commits
flang-commits at lists.llvm.org
Mon Jul 13 07:51:25 PDT 2026
================
@@ -8493,6 +8530,59 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder,
bool isOffloadEntry =
isTargetDevice || !ompBuilder->Config.TargetTriples.empty();
+ // Resolve in_reduction clauses on omp.target for the host. From the target
+ // device's perspective an in_reduction list item behaves as a regular
+ // map(tofrom) variable, so no special handling is needed there; only the
+ // host redirects the mapped value to the per-task reduction-private storage
+ // returned by __kmpc_task_reduction_get_th_data (emitted inside the
+ // to-be-outlined target task body). This applies to both offloading and
+ // non-offloading host modules.
+ //
+ // The target body has no dedicated in_reduction block argument: each
+ // in_reduction variable is accessed through its map_entries block argument.
+ // So each in_reduction variable must also be captured by a matching
+ // map_entries entry (guaranteed by the verifier); without one the outlined
+ // body would reference a value defined in the host function. Record, for each
+ // in_reduction variable, the position of that map entry so the corresponding
+ // map block argument can be redirected inside the body. The in_reduction
+ // operand itself is used as the `orig` argument of the runtime lookup.
+ SmallVector<llvm::Value *> inRedOrigPtrs;
+ SmallVector<unsigned> inRedMapArgIdx;
+ if (!targetOp.getInReductionVars().empty() && !isTargetDevice) {
+ inRedOrigPtrs.reserve(targetOp.getInReductionVars().size());
+ inRedMapArgIdx.reserve(targetOp.getInReductionVars().size());
+ for (Value v : targetOp.getInReductionVars()) {
+ // Select the map_entries entry that captures this in_reduction operand,
+ // using the same predicate as omp::TargetOp::verify(): exact same value,
+ // or another result of the same defining op. The verifier guarantees at
+ // least one match exists; more than one matching entry is a lowering
+ // ambiguity (the redirect cannot pick which map argument to rebind).
+ std::optional<unsigned> matchIdx;
+ for (auto [idx, mapV] : llvm::enumerate(targetOp.getMapVars())) {
+ auto mapInfo = mapV.getDefiningOp<omp::MapInfoOp>();
+ if (!mapInfo || !targetInReductionCapturedBy(v, mapInfo.getVarPtr()))
+ continue;
----------------
Saieiei wrote:
Done!
https://github.com/llvm/llvm-project/pull/199967
More information about the flang-commits
mailing list