[llvm-branch-commits] [flang] [flang][OpenMP] Improve diagnosing invalid operators in DECLARE_REDUCTION (PR #232353)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Oct 15 07:49:10 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Krzysztof Parzyszek (kparzysz)
<details>
<summary>Changes</summary>
Move the check out of the common MakeNameFromOperator function and
into OmpStructureChecker. Remove the no longer needed SemanticsContext
parameter in MakeNameFromOperator.
This will allow reusing at least some parts of the the name-mangling
code in DECLARE_INDUCTION.
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
---
Full diff: https://github.com/llvm/llvm-project/pull/232353.diff
13 Files Affected:
- (modified) flang/include/flang/Semantics/tools.h (+1-2)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+1-2)
- (modified) flang/lib/Lower/Support/ReductionProcessor.cpp (+1-1)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+44-19)
- (modified) flang/lib/Semantics/check-omp-structure.h (+2)
- (modified) flang/lib/Semantics/resolve-names.cpp (+1-2)
- (modified) flang/lib/Semantics/tools.cpp (+3-5)
- (modified) flang/test/Semantics/OpenMP/declare-reduction-bad-operator.f90 (+2-2)
- (modified) flang/test/Semantics/OpenMP/in-reduction.f90 (+1-1)
- (modified) flang/test/Semantics/OpenMP/reduction-subtract.f90 (+2-1)
- (modified) flang/test/Semantics/OpenMP/reduction01.f90 (+1-1)
- (modified) flang/test/Semantics/OpenMP/reduction14.f90 (+2-1)
- (modified) flang/test/Semantics/OpenMP/task-reduction.f90 (+1-1)
``````````diff
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index bd2cb0780de9b..eb8bc762aa1a0 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -791,8 +791,7 @@ bool HadUseError(SemanticsContext &, SourceName at, const Symbol *);
bool AreSameModuleSymbol(const Symbol &, const Symbol &);
parser::CharBlock MakeNameFromOperator(
- const parser::DefinedOperator::IntrinsicOperator &op,
- SemanticsContext &context);
+ const parser::DefinedOperator::IntrinsicOperator &op);
parser::CharBlock MangleSpecialFunctions(parser::CharBlock name);
std::string MangleDefinedOperator(parser::CharBlock name);
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 7aa11e3bc776a..4769b098a064d 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -6678,8 +6678,7 @@ static void genOpenMPDeclareReductionImpl(
parser::CharBlock mangledOpName =
semantics::MakeNameFromOperator(
ReductionProcessor::toParserIntrinsicOperator(
- intrOp),
- semaCtx);
+ intrOp));
redSymPtr = semantics::omp::FindUserReductionSymbol(
converter.getCurrentScope(), mangledOpName);
}
diff --git a/flang/lib/Lower/Support/ReductionProcessor.cpp b/flang/lib/Lower/Support/ReductionProcessor.cpp
index 55f24c937d8b5..0655bff1e7604 100644
--- a/flang/lib/Lower/Support/ReductionProcessor.cpp
+++ b/flang/lib/Lower/Support/ReductionProcessor.cpp
@@ -1206,7 +1206,7 @@ bool ReductionProcessor::processReductionArguments(
const semantics::DeclTypeSpec *opVarType =
reductionSymbols[idx]->GetUltimate().GetType();
parser::CharBlock mangledOpName = semantics::MakeNameFromOperator(
- toParserIntrinsicOperator(intrinsicOp), *semaCtx);
+ toParserIntrinsicOperator(intrinsicOp));
if (const semantics::Symbol *userSym =
semantics::omp::FindUserReductionSymbol(
converter.getCurrentScope(), mangledOpName, opVarType)) {
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 7376a05d5c2ae..1041ab778192c 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2756,17 +2756,32 @@ void OmpStructureChecker::Enter(const parser::OmpDeclareMapperDirective &x) {
}
void OmpStructureChecker::Enter(const parser::OmpDeclareReductionDirective &x) {
+ llvm::omp::Version version{context_.langOptions().getOpenMPVersion()};
+ std::string dirName{
+ GetUpperName(llvm::omp::Directive::OMPD_declare_reduction, version)};
+
const parser::OmpArgumentList &args{x.v.Arguments()};
if (args.v.size() != 1) {
context_.Say(args.source,
- "DECLARE_REDUCTION directive should have a single argument"_err_en_US);
+ "%s directive should have a single argument"_err_en_US, dirName);
return;
}
const parser::OmpArgument &arg{args.v.front()};
- if (!std::holds_alternative<parser::OmpReductionSpecifier>(arg.u)) {
+ if (auto *spec{std::get_if<parser::OmpReductionSpecifier>(&arg.u)}) {
+ auto &ident{std::get<parser::OmpReductionIdentifier>(spec->t)};
+ using IntrinsicOperator = parser::DefinedOperator::IntrinsicOperator;
+ if (auto *intOp{parser::Unwrap<IntrinsicOperator>(ident)}) {
+ if (!CheckReductionIntrinsicOperator(*intOp, arg.source)) {
+ context_.Say(arg.source,
+ "Invalid reduction intrinsic operator in %s directive"_err_en_US,
+ dirName);
+ }
+ }
+ } else {
context_.Say(arg.source,
- "The argument to the DECLARE_REDUCTION directive should be a reduction-specifier"_err_en_US);
+ "The argument to the %s directive should be a reduction-specifier"_err_en_US,
+ dirName);
}
}
@@ -4161,6 +4176,25 @@ void OmpStructureChecker::Enter(const parser::OmpClause::TaskReduction &x) {
CheckReductionObjects(objects, llvm::omp::Clause::OMPC_task_reduction);
}
+bool OmpStructureChecker::CheckReductionIntrinsicOperator(
+ parser::DefinedOperator::IntrinsicOperator op, parser::CharBlock source) {
+ switch (op) {
+ case parser::DefinedOperator::IntrinsicOperator::Add:
+ case parser::DefinedOperator::IntrinsicOperator::Multiply:
+ case parser::DefinedOperator::IntrinsicOperator::AND:
+ case parser::DefinedOperator::IntrinsicOperator::OR:
+ case parser::DefinedOperator::IntrinsicOperator::EQV:
+ case parser::DefinedOperator::IntrinsicOperator::NEQV:
+ return true;
+ case parser::DefinedOperator::IntrinsicOperator::Subtract:
+ context_.Say(source,
+ "The minus reduction operator is deprecated since OpenMP 5.2"_err_en_US);
+ return false;
+ default:
+ return false;
+ }
+}
+
bool OmpStructureChecker::CheckReductionOperator(
const parser::OmpReductionIdentifier &ident, parser::CharBlock source,
llvm::omp::Clause clauseId) {
@@ -4169,22 +4203,13 @@ bool OmpStructureChecker::CheckReductionOperator(
auto visitOperator{[&](const parser::DefinedOperator &dOpr) {
if (const auto *intrinsicOp{
std::get_if<parser::DefinedOperator::IntrinsicOperator>(&dOpr.u)}) {
- switch (*intrinsicOp) {
- case parser::DefinedOperator::IntrinsicOperator::Add:
- case parser::DefinedOperator::IntrinsicOperator::Multiply:
- case parser::DefinedOperator::IntrinsicOperator::AND:
- case parser::DefinedOperator::IntrinsicOperator::OR:
- case parser::DefinedOperator::IntrinsicOperator::EQV:
- case parser::DefinedOperator::IntrinsicOperator::NEQV:
- return true;
- case parser::DefinedOperator::IntrinsicOperator::Subtract:
- context_.Say(GetContext().clauseSource,
- "The minus reduction operator is deprecated since OpenMP 5.2 and is not supported in the REDUCTION clause."_err_en_US,
- ContextDirectiveAsFortran());
+ if (!CheckReductionIntrinsicOperator(*intrinsicOp, source)) {
+ context_.Say(source,
+ "Invalid reduction operator in %s clause"_err_en_US,
+ GetUpperName(clauseId, version));
return false;
- default:
- break;
}
+ return true;
}
// User-defined operators are OK if there has been a declared reduction
// for that. We mangle those names to store the user details.
@@ -4304,7 +4329,7 @@ static std::optional<parser::CharBlock> MangledReductionIdentifier(
if (const auto *intrinsicOp{
std::get_if<parser::DefinedOperator::IntrinsicOperator>(
&dOpr.u)}) {
- return MakeNameFromOperator(*intrinsicOp, context);
+ return MakeNameFromOperator(*intrinsicOp);
}
if (const auto *definedOp{
std::get_if<parser::DefinedOpName>(&dOpr.u)};
@@ -4389,7 +4414,7 @@ static bool IsReductionAllowedForType(
DIE("This should have been caught in CheckIntrinsicOperator");
return false;
}
- parser::CharBlock name{MakeNameFromOperator(*intrinsicOp, context)};
+ parser::CharBlock name{MakeNameFromOperator(*intrinsicOp)};
return CheckSymbolSupportsType(scope, name, type);
} else if (const auto *definedOp{
std::get_if<parser::DefinedOpName>(&dOpr.u)}) {
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 530ad90abcefc..3965201271419 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -487,6 +487,8 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
const parser::CharBlock &source, llvm::omp::Directive type);
void CheckReductionObjects(
const parser::OmpObjectList &objects, llvm::omp::Clause clauseId);
+ bool CheckReductionIntrinsicOperator(
+ parser::DefinedOperator::IntrinsicOperator op, parser::CharBlock source);
bool CheckReductionOperator(const parser::OmpReductionIdentifier &ident,
parser::CharBlock source, llvm::omp::Clause clauseId);
void CheckReductionObjectTypes(const parser::OmpObjectList &objects,
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f67f567578e90..562d290240b77 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2181,8 +2181,7 @@ void OmpVisitor::ProcessReductionSpecifier(
mangledName = context().SaveTempName(MangleDefinedOperator(name->source));
} else {
mangledName = MakeNameFromOperator(
- std::get<parser::DefinedOperator::IntrinsicOperator>(defOp.u),
- context());
+ std::get<parser::DefinedOperator::IntrinsicOperator>(defOp.u));
}
}
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index ce5c72a481c78..32aa55c5bd73a 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -1995,8 +1995,7 @@ bool AreSameModuleSymbol(const Symbol &symbol, const Symbol &other) {
}
parser::CharBlock MakeNameFromOperator(
- const parser::DefinedOperator::IntrinsicOperator &op,
- SemanticsContext &context) {
+ const parser::DefinedOperator::IntrinsicOperator &op) {
switch (op) {
case parser::DefinedOperator::IntrinsicOperator::Multiply:
return parser::CharBlock{"op.*", 4};
@@ -2015,7 +2014,6 @@ parser::CharBlock MakeNameFromOperator(
return parser::CharBlock{"op.NEQV", 7};
default:
- context.Say("Unsupported operator in DECLARE REDUCTION"_err_en_US);
return parser::CharBlock{"op.?", 4};
}
}
@@ -2031,8 +2029,8 @@ parser::CharBlock MangleSpecialFunctions(parser::CharBlock name) {
}
std::string MangleDefinedOperator(parser::CharBlock name) {
- CHECK(name[0] == '.' && name[name.size() - 1] == '.');
- return "op" + name.ToString();
+ CHECK(name.starts_with('.') && name.ends_with('.'));
+ return "op" + name.str();
}
std::string GetReductionFortranId(parser::CharBlock mangledName) {
diff --git a/flang/test/Semantics/OpenMP/declare-reduction-bad-operator.f90 b/flang/test/Semantics/OpenMP/declare-reduction-bad-operator.f90
index 1d1d2903a2780..ce93b640f237b 100644
--- a/flang/test/Semantics/OpenMP/declare-reduction-bad-operator.f90
+++ b/flang/test/Semantics/OpenMP/declare-reduction-bad-operator.f90
@@ -1,6 +1,6 @@
-! RUN: not %flang_fc1 -fdebug-dump-symbols -fopenmp -fopenmp-version=50 %s 2>&1 | FileCheck %s
+!RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50
function func(n)
+!ERROR: Invalid reduction intrinsic operator in DECLARE REDUCTION directive
!$omp declare reduction(/:integer:omp_out=omp_out+omp_in)
-!CHECK: error: Unsupported operator in DECLARE REDUCTION
end function func
diff --git a/flang/test/Semantics/OpenMP/in-reduction.f90 b/flang/test/Semantics/OpenMP/in-reduction.f90
index 0472774704334..54d11028f8e45 100644
--- a/flang/test/Semantics/OpenMP/in-reduction.f90
+++ b/flang/test/Semantics/OpenMP/in-reduction.f90
@@ -9,7 +9,7 @@ subroutine f00
subroutine f01
real :: x
-!ERROR: Invalid reduction operator in IN_REDUCTION clause.
+!ERROR: Invalid reduction operator in IN_REDUCTION clause
!$omp target in_reduction(.not.: x)
!$omp end target
end
diff --git a/flang/test/Semantics/OpenMP/reduction-subtract.f90 b/flang/test/Semantics/OpenMP/reduction-subtract.f90
index d4034743a14dc..fc0dd98da32d9 100644
--- a/flang/test/Semantics/OpenMP/reduction-subtract.f90
+++ b/flang/test/Semantics/OpenMP/reduction-subtract.f90
@@ -4,7 +4,8 @@
subroutine reduction_subtract
integer :: x
- !ERROR: The minus reduction operator is deprecated since OpenMP 5.2 and is not supported in the REDUCTION clause.
+ !ERROR: Invalid reduction operator in REDUCTION clause
+ !ERROR: The minus reduction operator is deprecated since OpenMP 5.2
!$omp do reduction(-:x)
do i=1, 100
x = x - i
diff --git a/flang/test/Semantics/OpenMP/reduction01.f90 b/flang/test/Semantics/OpenMP/reduction01.f90
index 0e1a8a571c584..d08b55c4b9214 100644
--- a/flang/test/Semantics/OpenMP/reduction01.f90
+++ b/flang/test/Semantics/OpenMP/reduction01.f90
@@ -5,7 +5,7 @@ program omp_reduction
integer :: i
integer :: k = 10
- !ERROR: Invalid reduction operator in REDUCTION clause.
+ !ERROR: Invalid reduction operator in REDUCTION clause
!$omp parallel do reduction(**:k)
do i = 1, 10
k = k ** 1
diff --git a/flang/test/Semantics/OpenMP/reduction14.f90 b/flang/test/Semantics/OpenMP/reduction14.f90
index 7d3f8d468f765..966c0610c8e92 100644
--- a/flang/test/Semantics/OpenMP/reduction14.f90
+++ b/flang/test/Semantics/OpenMP/reduction14.f90
@@ -23,7 +23,8 @@ program omp_reduction
!$omp end parallel
! - is deprecated for all types
- ! ERROR: The minus reduction operator is deprecated since OpenMP 5.2 and is not supported in the REDUCTION clause.
+ ! ERROR: Invalid reduction operator in REDUCTION clause
+ ! ERROR: The minus reduction operator is deprecated since OpenMP 5.2
!$omp parallel reduction(-:i,r,c,z,l)
!$omp end parallel
diff --git a/flang/test/Semantics/OpenMP/task-reduction.f90 b/flang/test/Semantics/OpenMP/task-reduction.f90
index 7e43332d53fe1..efbfa6ba199f5 100644
--- a/flang/test/Semantics/OpenMP/task-reduction.f90
+++ b/flang/test/Semantics/OpenMP/task-reduction.f90
@@ -9,7 +9,7 @@ subroutine f00
subroutine f01
real :: x
-!ERROR: Invalid reduction operator in TASK_REDUCTION clause.
+!ERROR: Invalid reduction operator in TASK_REDUCTION clause
!$omp taskgroup task_reduction(.not.: x)
!$omp end taskgroup
end
``````````
</details>
https://github.com/llvm/llvm-project/pull/232353
More information about the llvm-branch-commits
mailing list