From 63e1034d4e996849e4a297bce8b409cec18c31aa Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Fri, 27 Dec 2024 05:21:24 +0000 Subject: [PATCH 1/8] [Flang] Check if two ArrayConstructor's are Equal This also includes comparing the two ImpliedDo Details: - For ArrayConstructor, check if x and y have the same elements and type - For ImpliedDo, check if x and y have the same lower, upper, stride and values --- flang/include/flang/Lower/Support/Utils.h | 44 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h index 1cc74521e22d8..5eb39a08898f1 100644 --- a/flang/include/flang/Lower/Support/Utils.h +++ b/flang/include/flang/Lower/Support/Utils.h @@ -545,9 +545,51 @@ class IsEqualEvaluateExpr { return isEqual(x.proc(), y.proc()) && isEqual(x.arguments(), y.arguments()); } template + static bool isEqual(const Fortran::evaluate::ImpliedDo &x, + const Fortran::evaluate::ImpliedDo &y) { + using Expr = Fortran::evaluate::Expr; + for (const auto &[xValue, yValue] : llvm::zip(x.values(), y.values())) { + bool checkValue = Fortran::common::visit( + common::visitors{ + [&](const Expr &v, const Expr &w) { return isEqual(v, w); }, + [&](const auto &, const auto &) { + llvm::report_fatal_error("isEqual is not handled yet for " + "the element type in ImpliedDo"); + return false; + }, + }, + xValue.u, yValue.u); + if (!checkValue) { + return false; + } + } + return isEqual(x.lower(), y.lower()) && isEqual(x.upper(), y.upper()) && + isEqual(x.stride(), y.stride()); + } + template static bool isEqual(const Fortran::evaluate::ArrayConstructor &x, const Fortran::evaluate::ArrayConstructor &y) { - llvm::report_fatal_error("not implemented"); + for (const auto &[xValue, yValue] : llvm::zip(x, y)) { + using Expr = Fortran::evaluate::Expr; + using ImpliedDo = Fortran::evaluate::ImpliedDo; + bool checkElement = Fortran::common::visit( + common::visitors{ + [&](const Expr &v, const Expr &w) { return isEqual(v, w); }, + [&](const ImpliedDo &v, const ImpliedDo &w) { + return isEqual(v, w); + }, + [&](const auto &, const auto &) { + llvm::report_fatal_error("isEqual is not handled yet for " + "the element type in ImpliedDo"); + return false; + }, + }, + xValue.u, yValue.u); + if (!checkElement) { + return false; + } + } + return x.GetType() == y.GetType(); } static bool isEqual(const Fortran::evaluate::ImpliedDoIndex &x, const Fortran::evaluate::ImpliedDoIndex &y) { From 06b6e83462c2db0a0b89f0effd13297372cd8e50 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Fri, 27 Dec 2024 05:58:14 +0000 Subject: [PATCH 2/8] [Test] Add a test --- flang/test/Lower/OpenMP/atomic-update.f90 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/flang/test/Lower/OpenMP/atomic-update.f90 b/flang/test/Lower/OpenMP/atomic-update.f90 index 16dae9d5f301c..7d04745015faa 100644 --- a/flang/test/Lower/OpenMP/atomic-update.f90 +++ b/flang/test/Lower/OpenMP/atomic-update.f90 @@ -185,4 +185,19 @@ program OmpAtomicUpdate !$omp atomic update w = max(w,x,y,z) +!CHECK: %[[IMP_DO:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr { +!CHECK: ^bb0(%{{.*}}: index): +! [...] +!CHECK: %[[ADD_I1:.*]] = arith.addi {{.*}} : i32 +!CHECK: hlfir.yield_element %[[ADD_I1]] : i32 +!CHECK: } +! [...] +!CHECK: %[[SUM:.*]] = hlfir.sum %[[IMP_DO]] +!CHECK: omp.atomic.update %[[VAL_X_DECLARE]]#1 : !fir.ref { +!CHECK: ^bb0(%[[ARG0:.*]]: i32): +!CHECK: %[[ADD_I2:.*]] = arith.addi %[[ARG0]], %[[SUM]] : i32 +!CHECK: omp.yield(%[[ADD_I2]] : i32) +!CHECK: } + !$omp atomic update + x = x + sum([ (y+2, y=1, z) ]) end program OmpAtomicUpdate From 0b5e7a876eb74a562c99f8dbea882606a8eeba4c Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Thu, 16 Jan 2025 10:10:23 +0000 Subject: [PATCH 3/8] [Flang] Add isEqual visitor for ArrayConstructorValue --- flang/include/flang/Lower/Support/Utils.h | 42 ++++++++--------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h index 5eb39a08898f1..742db701dacfb 100644 --- a/flang/include/flang/Lower/Support/Utils.h +++ b/flang/include/flang/Lower/Support/Utils.h @@ -547,49 +547,35 @@ class IsEqualEvaluateExpr { template static bool isEqual(const Fortran::evaluate::ImpliedDo &x, const Fortran::evaluate::ImpliedDo &y) { - using Expr = Fortran::evaluate::Expr; - for (const auto &[xValue, yValue] : llvm::zip(x.values(), y.values())) { - bool checkValue = Fortran::common::visit( - common::visitors{ - [&](const Expr &v, const Expr &w) { return isEqual(v, w); }, - [&](const auto &, const auto &) { - llvm::report_fatal_error("isEqual is not handled yet for " - "the element type in ImpliedDo"); - return false; - }, - }, - xValue.u, yValue.u); - if (!checkValue) { - return false; - } - } - return isEqual(x.lower(), y.lower()) && isEqual(x.upper(), y.upper()) && - isEqual(x.stride(), y.stride()); + return isEqual(x.values(), y.values()) && isEqual(x.lower(), y.lower()) && + isEqual(x.upper(), y.upper()) && isEqual(x.stride(), y.stride()); } template - static bool isEqual(const Fortran::evaluate::ArrayConstructor &x, - const Fortran::evaluate::ArrayConstructor &y) { + static bool isEqual(const Fortran::evaluate::ArrayConstructorValue &x, + const Fortran::evaluate::ArrayConstructorValue &y) { + using Expr = Fortran::evaluate::Expr; + using ImpliedDo = Fortran::evaluate::ImpliedDo; for (const auto &[xValue, yValue] : llvm::zip(x, y)) { - using Expr = Fortran::evaluate::Expr; - using ImpliedDo = Fortran::evaluate::ImpliedDo; bool checkElement = Fortran::common::visit( common::visitors{ [&](const Expr &v, const Expr &w) { return isEqual(v, w); }, [&](const ImpliedDo &v, const ImpliedDo &w) { return isEqual(v, w); }, - [&](const auto &, const auto &) { - llvm::report_fatal_error("isEqual is not handled yet for " - "the element type in ImpliedDo"); - return false; - }, + [&](const Expr &, const ImpliedDo &) { return false; }, + [&](const ImpliedDo &, const Expr &) { return false; }, }, xValue.u, yValue.u); if (!checkElement) { return false; } } - return x.GetType() == y.GetType(); + return true; + } + template + static bool isEqual(const Fortran::evaluate::ArrayConstructor &x, + const Fortran::evaluate::ArrayConstructor &y) { + return isEqual(x, y) && x.GetType() == y.GetType(); } static bool isEqual(const Fortran::evaluate::ImpliedDoIndex &x, const Fortran::evaluate::ImpliedDoIndex &y) { From 47acfec912ec16ae588241ae88cd179eeff740ae Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Thu, 16 Jan 2025 10:14:34 +0000 Subject: [PATCH 4/8] [Flang] Add check for CharacterType for ArrayConstructor --- flang/include/flang/Lower/Support/Utils.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h index 742db701dacfb..b3dfe74fc6573 100644 --- a/flang/include/flang/Lower/Support/Utils.h +++ b/flang/include/flang/Lower/Support/Utils.h @@ -575,7 +575,11 @@ class IsEqualEvaluateExpr { template static bool isEqual(const Fortran::evaluate::ArrayConstructor &x, const Fortran::evaluate::ArrayConstructor &y) { - return isEqual(x, y) && x.GetType() == y.GetType(); + bool checkCharacterType = true; + if constexpr (A::category == Fortran::common::TypeCategory::Character) { + checkCharacterType = x.LEN() == y.LEN(); + } + return isEqual(x, y) && x.GetType() == y.GetType() && checkCharacterType; } static bool isEqual(const Fortran::evaluate::ImpliedDoIndex &x, const Fortran::evaluate::ImpliedDoIndex &y) { From 8d7305b3b73d36131d4434030c97e9a0b27f3233 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Tue, 21 Jan 2025 07:33:08 +0000 Subject: [PATCH 5/8] Fix type conflicts --- flang/include/flang/Lower/Support/Utils.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h index b3dfe74fc6573..7159f049a08a2 100644 --- a/flang/include/flang/Lower/Support/Utils.h +++ b/flang/include/flang/Lower/Support/Utils.h @@ -551,8 +551,8 @@ class IsEqualEvaluateExpr { isEqual(x.upper(), y.upper()) && isEqual(x.stride(), y.stride()); } template - static bool isEqual(const Fortran::evaluate::ArrayConstructorValue &x, - const Fortran::evaluate::ArrayConstructorValue &y) { + static bool isEqual(const Fortran::evaluate::ArrayConstructorValues &x, + const Fortran::evaluate::ArrayConstructorValues &y) { using Expr = Fortran::evaluate::Expr; using ImpliedDo = Fortran::evaluate::ImpliedDo; for (const auto &[xValue, yValue] : llvm::zip(x, y)) { @@ -579,7 +579,9 @@ class IsEqualEvaluateExpr { if constexpr (A::category == Fortran::common::TypeCategory::Character) { checkCharacterType = x.LEN() == y.LEN(); } - return isEqual(x, y) && x.GetType() == y.GetType() && checkCharacterType; + using Base = Fortran::evaluate::ArrayConstructorValues; + return isEqual((Base) x, (Base) y) && + (x.GetType() == y.GetType() && checkCharacterType); } static bool isEqual(const Fortran::evaluate::ImpliedDoIndex &x, const Fortran::evaluate::ImpliedDoIndex &y) { From 595c4f64512df0555ebb0360ddd6ba40323487f2 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Tue, 21 Jan 2025 08:09:30 +0000 Subject: [PATCH 6/8] Fix clang format --- flang/include/flang/Lower/Support/Utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h index 7159f049a08a2..7dc380c40c012 100644 --- a/flang/include/flang/Lower/Support/Utils.h +++ b/flang/include/flang/Lower/Support/Utils.h @@ -580,7 +580,7 @@ class IsEqualEvaluateExpr { checkCharacterType = x.LEN() == y.LEN(); } using Base = Fortran::evaluate::ArrayConstructorValues; - return isEqual((Base) x, (Base) y) && + return isEqual((Base)x, (Base)y) && (x.GetType() == y.GetType() && checkCharacterType); } static bool isEqual(const Fortran::evaluate::ImpliedDoIndex &x, From 6442b335c2a5d2560b3a67aed6d87e36eeea88e5 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Mon, 27 Jan 2025 08:42:15 +0000 Subject: [PATCH 7/8] [Flang] Move the check inside `isEqual` --- flang/include/flang/Lower/Support/Utils.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h index 7dc380c40c012..f50288ff4d7cf 100644 --- a/flang/include/flang/Lower/Support/Utils.h +++ b/flang/include/flang/Lower/Support/Utils.h @@ -572,12 +572,16 @@ class IsEqualEvaluateExpr { } return true; } + static bool isEqual(const Fortran::evaluate::SubscriptInteger &x, + const Fortran::evaluate::SubscriptInteger &y) { + return x == y; + } template static bool isEqual(const Fortran::evaluate::ArrayConstructor &x, const Fortran::evaluate::ArrayConstructor &y) { bool checkCharacterType = true; if constexpr (A::category == Fortran::common::TypeCategory::Character) { - checkCharacterType = x.LEN() == y.LEN(); + checkCharacterType = isEqual(*x.LEN(), *y.LEN()); } using Base = Fortran::evaluate::ArrayConstructorValues; return isEqual((Base)x, (Base)y) && From 5eae75268fec4a2530311248396d301235a950bb Mon Sep 17 00:00:00 2001 From: Thirumalai Shaktivel <74826228+Thirumalai-Shaktivel@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:01:14 +0530 Subject: [PATCH 8/8] Fix clang-format --- flang/include/flang/Lower/Support/Utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h index f50288ff4d7cf..561aae04e8e99 100644 --- a/flang/include/flang/Lower/Support/Utils.h +++ b/flang/include/flang/Lower/Support/Utils.h @@ -574,7 +574,7 @@ class IsEqualEvaluateExpr { } static bool isEqual(const Fortran::evaluate::SubscriptInteger &x, const Fortran::evaluate::SubscriptInteger &y) { - return x == y; + return x == y; } template static bool isEqual(const Fortran::evaluate::ArrayConstructor &x,