[flang-commits] [flang] [flang][OpenMP] Catch assumed-rank/size variables for privatization a… (PR #152764)
via flang-commits
flang-commits at lists.llvm.org
Fri Aug 8 10:17:03 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
@llvm/pr-subscribers-flang-openmp
Author: Tom Eccles (tblah)
<details>
<summary>Changes</summary>
…nd reduction
Fixes #<!-- -->152312
Assumed size is valid for privatization and simple examples generate sensible looking HLFIR.
---
Full diff: https://github.com/llvm/llvm-project/pull/152764.diff
4 Files Affected:
- (modified) flang/lib/Lower/Support/PrivateReductionUtils.cpp (+2)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+19-5)
- (added) flang/test/Lower/OpenMP/Todo/assumed-rank-privatization.f90 (+9)
- (added) flang/test/Semantics/OpenMP/reduction-assumed.f90 (+53)
``````````diff
diff --git a/flang/lib/Lower/Support/PrivateReductionUtils.cpp b/flang/lib/Lower/Support/PrivateReductionUtils.cpp
index fff060b79c9fe..1b09801c607c6 100644
--- a/flang/lib/Lower/Support/PrivateReductionUtils.cpp
+++ b/flang/lib/Lower/Support/PrivateReductionUtils.cpp
@@ -616,6 +616,8 @@ void PopulateInitAndCleanupRegionsHelper::populateByRefInitAndCleanupRegions() {
assert(sym && "Symbol information is required to privatize derived types");
assert(!scalarInitValue && "ScalarInitvalue is unused for privatization");
}
+ if (hlfir::Entity{moldArg}.isAssumedRank())
+ TODO(loc, "Privatization of assumed rank variable");
mlir::Type valTy = fir::unwrapRefType(argType);
if (fir::isa_trivial(valTy)) {
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index cbe6b2c68bf05..bf126bbb0d8c1 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2891,7 +2891,8 @@ static bool CheckSymbolSupportsType(const Scope &scope,
static bool IsReductionAllowedForType(
const parser::OmpReductionIdentifier &ident, const DeclTypeSpec &type,
- const Scope &scope, SemanticsContext &context) {
+ bool cannotBeBuiltinReduction, const Scope &scope,
+ SemanticsContext &context) {
auto isLogical{[](const DeclTypeSpec &type) -> bool {
return type.category() == DeclTypeSpec::Logical;
}};
@@ -2902,6 +2903,10 @@ static bool IsReductionAllowedForType(
auto checkOperator{[&](const parser::DefinedOperator &dOpr) {
if (const auto *intrinsicOp{
std::get_if<parser::DefinedOperator::IntrinsicOperator>(&dOpr.u)}) {
+ if (cannotBeBuiltinReduction) {
+ return false;
+ }
+
// OMP5.2: The type [...] of a list item that appears in a
// reduction clause must be valid for the combiner expression
// See F2023: Table 10.2
@@ -2953,7 +2958,8 @@ static bool IsReductionAllowedForType(
// IAND: arguments must be integers: F2023 16.9.100
// IEOR: arguments must be integers: F2023 16.9.106
// IOR: arguments must be integers: F2023 16.9.111
- if (type.IsNumeric(TypeCategory::Integer)) {
+ if (type.IsNumeric(TypeCategory::Integer) &&
+ !cannotBeBuiltinReduction) {
return true;
}
} else if (realName == "max" || realName == "min") {
@@ -2961,8 +2967,9 @@ static bool IsReductionAllowedForType(
// F2023 16.9.135
// MIN: arguments must be integer, real, or character:
// F2023 16.9.141
- if (type.IsNumeric(TypeCategory::Integer) ||
- type.IsNumeric(TypeCategory::Real) || isCharacter(type)) {
+ if ((type.IsNumeric(TypeCategory::Integer) ||
+ type.IsNumeric(TypeCategory::Real) || isCharacter(type)) &&
+ !cannotBeBuiltinReduction) {
return true;
}
}
@@ -2995,9 +3002,16 @@ void OmpStructureChecker::CheckReductionObjectTypes(
GetSymbolsInObjectList(objects, symbols);
for (auto &[symbol, source] : symbols) {
+ // Built in reductions require types which can be used in their initializer
+ // and combiner expressions. For example, for +:
+ // r = 0; r = r + r2
+ // But it might be valid to use these with DECLARE REDUCTION.
+ // Assumed size is already caught elsewhere.
+ bool cannotBeBuiltinReduction{evaluate::IsAssumedRank(*symbol)};
if (auto *type{symbol->GetType()}) {
const auto &scope{context_.FindScope(symbol->name())};
- if (!IsReductionAllowedForType(ident, *type, scope, context_)) {
+ if (!IsReductionAllowedForType(
+ ident, *type, cannotBeBuiltinReduction, scope, context_)) {
context_.Say(source,
"The type of '%s' is incompatible with the reduction operator."_err_en_US,
symbol->name());
diff --git a/flang/test/Lower/OpenMP/Todo/assumed-rank-privatization.f90 b/flang/test/Lower/OpenMP/Todo/assumed-rank-privatization.f90
new file mode 100644
index 0000000000000..e57833a1013b6
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/assumed-rank-privatization.f90
@@ -0,0 +1,9 @@
+! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: Privatization of assumed rank variable
+subroutine assumedPriv(a)
+ integer :: a(..)
+
+ !$omp parallel private(a)
+ !$omp end parallel
+end
diff --git a/flang/test/Semantics/OpenMP/reduction-assumed.f90 b/flang/test/Semantics/OpenMP/reduction-assumed.f90
new file mode 100644
index 0000000000000..0bc8cd318a74d
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/reduction-assumed.f90
@@ -0,0 +1,53 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+! Types for built in reductions must have types which are valid for the
+! initialization and combiner expressions in the spec. This implies assumed
+! rank and assumed size cannot be used.
+
+subroutine assumedRank1(a)
+ integer :: a(..)
+
+ ! ERROR: The type of 'a' is incompatible with the reduction operator.
+ !$omp parallel reduction(+:a)
+ !$omp end parallel
+end
+
+subroutine assumedRank2(a)
+ integer :: a(..)
+
+ ! ERROR: The type of 'a' is incompatible with the reduction operator.
+ !$omp parallel reduction(min:a)
+ !$omp end parallel
+end
+
+subroutine assumedRank3(a)
+ integer :: a(..)
+
+ ! ERROR: The type of 'a' is incompatible with the reduction operator.
+ !$omp parallel reduction(iand:a)
+ !$omp end parallel
+end
+
+subroutine assumedSize1(a)
+ integer :: a(*)
+
+ ! ERROR: Whole assumed-size array 'a' may not appear here without subscripts
+ !$omp parallel reduction(+:a)
+ !$omp end parallel
+end
+
+subroutine assumedSize2(a)
+ integer :: a(*)
+
+ ! ERROR: Whole assumed-size array 'a' may not appear here without subscripts
+ !$omp parallel reduction(max:a)
+ !$omp end parallel
+end
+
+subroutine assumedSize3(a)
+ integer :: a(*)
+
+ ! ERROR: Whole assumed-size array 'a' may not appear here without subscripts
+ !$omp parallel reduction(ior:a)
+ !$omp end parallel
+end
``````````
</details>
https://github.com/llvm/llvm-project/pull/152764
More information about the flang-commits
mailing list