[flang-commits] [flang] [flang][OpenMP] Diagnose privatized array section reductions (PR #215997)

Tom Eccles via flang-commits flang-commits at lists.llvm.org
Thu Aug 13 02:56:56 PDT 2026


https://github.com/tblah created https://github.com/llvm/llvm-project/pull/215997

Contiguous array sections can hit the same task and taskloop base-symbol rebinding problem as array elements. Diagnose these cases until reduction object identity is preserved through region binding.

Check only symbols that become delayed-private block arguments so eager taskloop privatization remains supported. Cover task and taskloop section diagnostics.

This issue was previously reported here:
https://github.com/llvm/llvm-project/pull/215617#discussion_r3766204295

Assisted-by: Codex

>From f98b50693c3c70f8576961fefcfc3878d436456d Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Wed, 12 Aug 2026 15:27:01 +0100
Subject: [PATCH] [flang][OpenMP] Diagnose privatized array section reductions

Contiguous array sections can hit the same task and taskloop
base-symbol rebinding problem as array elements. Diagnose these
cases until reduction object identity is preserved through region
binding.

Check only symbols that become delayed-private block arguments so
eager taskloop privatization remains supported. Cover task and
taskloop section diagnostics.

This issue was previously reported here:
https://github.com/llvm/llvm-project/pull/215617#discussion_r3766204295

Assisted-by: Codex
---
 flang/lib/Lower/OpenMP/OpenMP.cpp             | 35 ++++++------
 ...ction-array-element-task-privatization.f90 | 53 ++++++++++++++++---
 2 files changed, 64 insertions(+), 24 deletions(-)

diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 52edfdfdd738f..cec5d8ed24899 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -155,9 +155,9 @@ makeObjects(llvm::ArrayRef<const semantics::Symbol *> syms) {
   return objects;
 }
 
-static bool hasPrivatizedArrayElementReduction(
+static bool hasPrivatizedArrayReductionObject(
     llvm::ArrayRef<Object> reductionObjects,
-    const llvm::SetVector<const semantics::Symbol *> &privatizedSymbols) {
+    llvm::ArrayRef<const semantics::Symbol *> privatizedSymbols) {
   for (const Object &object : reductionObjects) {
     if (!object.sym() || !object.ref())
       continue;
@@ -166,10 +166,7 @@ static bool hasPrivatizedArrayElementReduction(
     if (!dataRef)
       continue;
     const auto *arrayRef = std::get_if<evaluate::ArrayRef>(&dataRef->u);
-    if (!arrayRef ||
-        llvm::any_of(arrayRef->subscript(), [](const auto &subscript) {
-          return std::holds_alternative<evaluate::Triplet>(subscript.u);
-        }))
+    if (!arrayRef)
       continue;
 
     const semantics::Symbol &ultimate = object.sym()->GetUltimate();
@@ -4299,10 +4296,10 @@ genTaskOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
                            /*useDelayedPrivatization=*/true, symTable);
   dsp.processStep1(&clauseOps);
 
-  if (hasPrivatizedArrayElementReduction(inReductionObjects,
-                                         dsp.getAllSymbolsToPrivatize()))
-    TODO(loc, "TASK construct with IN_REDUCTION of an array element whose "
-              "base array is privatized");
+  if (hasPrivatizedArrayReductionObject(inReductionObjects,
+                                        dsp.getDelayedPrivSymbols()))
+    TODO(loc, "TASK construct with IN_REDUCTION of an array element or section "
+              "whose base array is privatized");
 
   ObjectEntryBlockArgs taskArgs;
   taskArgs.priv.objects = makeObjects(dsp.getDelayedPrivSymbols());
@@ -4922,14 +4919,16 @@ static mlir::omp::TaskloopContextOp genStandaloneTaskloop(
                            enableDelayedPrivatization, symTable);
   dsp.processStep1(&taskloopClauseOps);
 
-  if (hasPrivatizedArrayElementReduction(inReductionObjects,
-                                         dsp.getAllSymbolsToPrivatize()))
-    TODO(loc, "TASKLOOP construct with IN_REDUCTION of an array element whose "
-              "base array is privatized");
-  if (hasPrivatizedArrayElementReduction(reductionObjects,
-                                         dsp.getAllSymbolsToPrivatize()))
-    TODO(loc, "TASKLOOP construct with REDUCTION of an array element whose "
-              "base array is privatized");
+  if (hasPrivatizedArrayReductionObject(inReductionObjects,
+                                        dsp.getDelayedPrivSymbols()))
+    TODO(loc,
+         "TASKLOOP construct with IN_REDUCTION of an array element or section "
+         "whose base array is privatized");
+  if (hasPrivatizedArrayReductionObject(reductionObjects,
+                                        dsp.getDelayedPrivSymbols()))
+    TODO(loc,
+         "TASKLOOP construct with REDUCTION of an array element or section "
+         "whose base array is privatized");
 
   mlir::omp::LoopNestOperands loopNestClauseOps;
   llvm::SmallVector<const semantics::Symbol *> iv;
diff --git a/flang/test/Lower/OpenMP/Todo/reduction-array-element-task-privatization.f90 b/flang/test/Lower/OpenMP/Todo/reduction-array-element-task-privatization.f90
index 770f309d1d160..bdce803fed4d5 100644
--- a/flang/test/Lower/OpenMP/Todo/reduction-array-element-task-privatization.f90
+++ b/flang/test/Lower/OpenMP/Todo/reduction-array-element-task-privatization.f90
@@ -5,14 +5,27 @@
 ! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %t/taskloop-in.f90 2>&1 | FileCheck %s --check-prefix=TASKLOOP-IN
 ! RUN: %not_todo_cmd bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %t/taskloop-reduction.f90 2>&1 | FileCheck %s --check-prefix=TASKLOOP-REDUCTION
 ! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %t/taskloop-reduction.f90 2>&1 | FileCheck %s --check-prefix=TASKLOOP-REDUCTION
+! RUN: %not_todo_cmd bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %t/task-section.f90 2>&1 | FileCheck %s --check-prefix=TASK-SECTION
+! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %t/task-section.f90 2>&1 | FileCheck %s --check-prefix=TASK-SECTION
+! RUN: %not_todo_cmd bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %t/taskloop-in-section.f90 2>&1 | FileCheck %s --check-prefix=TASKLOOP-IN-SECTION
+! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %t/taskloop-in-section.f90 2>&1 | FileCheck %s --check-prefix=TASKLOOP-IN-SECTION
+! RUN: %not_todo_cmd bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %t/taskloop-reduction-section.f90 2>&1 | FileCheck %s --check-prefix=TASKLOOP-REDUCTION-SECTION
+! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %t/taskloop-reduction-section.f90 2>&1 | FileCheck %s --check-prefix=TASKLOOP-REDUCTION-SECTION
+! RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 --enable-delayed-privatization=false -o %t/eager-in-bbc.mlir %t/taskloop-in.f90
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -mmlir --enable-delayed-privatization=false -o %t/eager-in-fc1.mlir %t/taskloop-in.f90
+! RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 --enable-delayed-privatization=false -o %t/eager-section-bbc.mlir %t/taskloop-reduction-section.f90
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -mmlir --enable-delayed-privatization=false -o %t/eager-section-fc1.mlir %t/taskloop-reduction-section.f90
 
-! An array element in a task reduction and the implicitly firstprivate base
-! array are represented by separate block arguments. Reject these constructs
-! until lowering can bind references to the correct argument.
+! An array element or section in a task reduction and the implicitly
+! firstprivate base array are represented by separate block arguments. Reject
+! these constructs until lowering can bind references to the correct argument.
 
-! TASK: not yet implemented: TASK construct with IN_REDUCTION of an array element whose base array is privatized
-! TASKLOOP-IN: not yet implemented: TASKLOOP construct with IN_REDUCTION of an array element whose base array is privatized
-! TASKLOOP-REDUCTION: not yet implemented: TASKLOOP construct with REDUCTION of an array element whose base array is privatized
+! TASK: not yet implemented: TASK construct with IN_REDUCTION of an array element or section whose base array is privatized
+! TASKLOOP-IN: not yet implemented: TASKLOOP construct with IN_REDUCTION of an array element or section whose base array is privatized
+! TASKLOOP-REDUCTION: not yet implemented: TASKLOOP construct with REDUCTION of an array element or section whose base array is privatized
+! TASK-SECTION: not yet implemented: TASK construct with IN_REDUCTION of an array element or section whose base array is privatized
+! TASKLOOP-IN-SECTION: not yet implemented: TASKLOOP construct with IN_REDUCTION of an array element or section whose base array is privatized
+! TASKLOOP-REDUCTION-SECTION: not yet implemented: TASKLOOP construct with REDUCTION of an array element or section whose base array is privatized
 
 !--- task.f90
 subroutine task_reduction_element(a)
@@ -24,6 +37,34 @@ subroutine task_reduction_element(a)
   !$omp end taskgroup
 end subroutine
 
+!--- task-section.f90
+subroutine task_reduction_section(a)
+  integer :: a(4)
+  !$omp taskgroup task_reduction(+: a(2:3))
+  !$omp task in_reduction(+: a(2:3))
+  a(2:3) = a(2:3) + 1
+  !$omp end task
+  !$omp end taskgroup
+end subroutine
+
+!--- taskloop-in-section.f90
+subroutine taskloop_in_reduction_section(a, n)
+  integer :: a(4), n
+  !$omp taskloop in_reduction(+: a(2:3))
+  do i = 1, n
+    a(2:3) = a(2:3) + i
+  end do
+end subroutine
+
+!--- taskloop-reduction-section.f90
+subroutine taskloop_reduction_section(a, n)
+  integer :: a(4), n
+  !$omp taskloop reduction(+: a(2:3))
+  do i = 1, n
+    a(2:3) = a(2:3) + i
+  end do
+end subroutine
+
 !--- taskloop-in.f90
 subroutine taskloop_in_reduction_element(a, n)
   integer :: a(4), n



More information about the flang-commits mailing list