-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[flang][OpenMP] Catch assumed-rank/size variables for privatization a… #152764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…nd reduction Fixes llvm#152312 Assumed size is valid for privatization and simple examples generate sensible looking HLFIR.
@llvm/pr-subscribers-flang-semantics @llvm/pr-subscribers-flang-openmp Author: Tom Eccles (tblah) Changes…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:
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
|
@llvm/pr-subscribers-flang-fir-hlfir Author: Tom Eccles (tblah) Changes…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:
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
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…nd reduction
Fixes #152312
Assumed size is valid for privatization and simple examples generate sensible looking HLFIR.