Skip to content

[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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions flang/lib/Lower/Support/PrivateReductionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
24 changes: 19 additions & 5 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}};
Expand All @@ -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
Expand Down Expand Up @@ -2953,16 +2958,18 @@ 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") {
// MAX: arguments must be integer, real, or character:
// 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;
}
}
Expand Down Expand Up @@ -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());
Expand Down
9 changes: 9 additions & 0 deletions flang/test/Lower/OpenMP/Todo/assumed-rank-privatization.f90
Original file line number Diff line number Diff line change
@@ -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
53 changes: 53 additions & 0 deletions flang/test/Semantics/OpenMP/reduction-assumed.f90
Original file line number Diff line number Diff line change
@@ -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