From 9d032d4a4aceeabd7026c6ffe94656cf9eb91813 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 31 Jul 2025 12:29:25 -0500 Subject: [PATCH 1/2] [flang][Evaluate] OperationCode cleanup, fix for Constant Make the OperationCode overloads take the derived operation instead of the Operation base class instance. This makes them usable from visitors of "Expr.u". Also, fix small bug: OperationCode(Constant) shoud be "Constant". --- flang/include/flang/Evaluate/tools.h | 54 +++++++++--------------- flang/lib/Evaluate/tools.cpp | 6 +-- flang/test/Semantics/OpenMP/atomic04.f90 | 2 +- flang/test/Semantics/OpenMP/atomic05.f90 | 2 +- 4 files changed, 25 insertions(+), 39 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index cef57f1851bcc..e2c9878ab19a9 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -1402,10 +1402,8 @@ using OperatorSet = common::EnumSet; std::string ToString(Operator op); -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - switch (op.derived().logicalOperator) { +template Operator OperationCode(const LogicalOperation &op) { + switch (op.logicalOperator) { case common::LogicalOperator::And: return Operator::And; case common::LogicalOperator::Or: @@ -1420,10 +1418,8 @@ Operator OperationCode( return Operator::Unknown; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - switch (op.derived().opr) { +template Operator OperationCode(const Relational &op) { + switch (op.opr) { case common::RelationalOperator::LT: return Operator::Lt; case common::RelationalOperator::LE: @@ -1440,44 +1436,32 @@ Operator OperationCode( return Operator::Unknown; } -template -Operator OperationCode(const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const Add &op) { return Operator::Add; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const Subtract &op) { return Operator::Sub; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const Multiply &op) { return Operator::Mul; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const Divide &op) { return Operator::Div; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const Power &op) { return Operator::Pow; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const RealToIntPower &op) { return Operator::Pow; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template +Operator OperationCode(const Convert &op) { if constexpr (C == T::category) { return Operator::Resize; } else { @@ -1485,25 +1469,27 @@ Operator OperationCode( } } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - if (op.derived().ordering == evaluate::Ordering::Greater) { +template Operator OperationCode(const Extremum &op) { + if (op.ordering == Ordering::Greater) { return Operator::Max; } else { return Operator::Min; } } -template Operator OperationCode(const evaluate::Constant &x) { +template Operator OperationCode(const Constant &x) { return Operator::Constant; } +template Operator OperationCode(const Designator &x) { + return Operator::Identity; +} + template Operator OperationCode(const T &) { return Operator::Unknown; } -Operator OperationCode(const evaluate::ProcedureDesignator &proc); +Operator OperationCode(const ProcedureDesignator &proc); } // namespace operation diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp index 171dd91fa9fd1..90be131651697 100644 --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -1693,17 +1693,17 @@ struct ArgumentExtractor // to int(kind=4) for example. return (*this)(x.template operand<0>()); } else { - return std::make_pair(operation::OperationCode(x), + return std::make_pair(operation::OperationCode(x.derived()), OperationArgs(x, std::index_sequence_for{})); } } template Result operator()(const Designator &x) const { - return {operation::Operator::Identity, {AsSomeExpr(x)}}; + return {operation::OperationCode(x), {AsSomeExpr(x)}}; } template Result operator()(const Constant &x) const { - return {operation::Operator::Identity, {AsSomeExpr(x)}}; + return {operation::OperationCode(x), {AsSomeExpr(x)}}; } template diff --git a/flang/test/Semantics/OpenMP/atomic04.f90 b/flang/test/Semantics/OpenMP/atomic04.f90 index fb87ca5186612..8f8af31245404 100644 --- a/flang/test/Semantics/OpenMP/atomic04.f90 +++ b/flang/test/Semantics/OpenMP/atomic04.f90 @@ -180,7 +180,7 @@ subroutine more_invalid_atomic_update_stmts() x = x !$omp atomic update - !ERROR: The atomic variable x should appear as an argument in the update operation + !ERROR: This is not a valid ATOMIC UPDATE operation x = 1 !$omp atomic update diff --git a/flang/test/Semantics/OpenMP/atomic05.f90 b/flang/test/Semantics/OpenMP/atomic05.f90 index 77ffc6e57f1a3..e0103be4cae4a 100644 --- a/flang/test/Semantics/OpenMP/atomic05.f90 +++ b/flang/test/Semantics/OpenMP/atomic05.f90 @@ -19,7 +19,7 @@ program OmpAtomic x = 2 * 4 !ERROR: At most one clause from the 'memory-order' group is allowed on ATOMIC construct !$omp atomic update release, seq_cst - !ERROR: The atomic variable x should appear as an argument in the update operation + !ERROR: This is not a valid ATOMIC UPDATE operation x = 10 !ERROR: At most one clause from the 'memory-order' group is allowed on ATOMIC construct !$omp atomic capture release, seq_cst From aab7380504be6c39ce4c16d600c1cb5319a5272a Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 31 Jul 2025 13:00:05 -0500 Subject: [PATCH 2/2] Add overload for Relational --- flang/include/flang/Evaluate/tools.h | 2 ++ flang/lib/Evaluate/tools.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index e2c9878ab19a9..212356136d6ee 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -1418,6 +1418,8 @@ template Operator OperationCode(const LogicalOperation &op) { return Operator::Unknown; } +Operator OperationCode(const Relational &op); + template Operator OperationCode(const Relational &op) { switch (op.opr) { case common::RelationalOperator::LT: diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp index 90be131651697..9c059b08dd41c 100644 --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -1793,6 +1793,10 @@ std::string operation::ToString(operation::Operator op) { llvm_unreachable("Unhandler operator"); } +operation::Operator operation::OperationCode(const Relational &op) { + return common::visit([](auto &&s) { return OperationCode(s); }, op.u); +} + operation::Operator operation::OperationCode(const ProcedureDesignator &proc) { Operator code{llvm::StringSwitch(proc.GetName()) .Case("associated", Operator::Associated)