[flang-commits] [flang] [Flang] Check if two ArrayConstructor's are Equal (PR #121181)
via flang-commits
flang-commits at lists.llvm.org
Thu Dec 26 22:10:50 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Thirumalai Shaktivel (Thirumalai-Shaktivel)
<details>
<summary>Changes</summary>
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
Fixes: https://github.com/llvm/llvm-project/issues/104526
---
Full diff: https://github.com/llvm/llvm-project/pull/121181.diff
2 Files Affected:
- (modified) flang/include/flang/Lower/Support/Utils.h (+44-1)
- (modified) flang/test/Lower/OpenMP/atomic-update.f90 (+15)
``````````diff
diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h
index 1cc74521e22d88..b2f3673f9164cb 100644
--- a/flang/include/flang/Lower/Support/Utils.h
+++ b/flang/include/flang/Lower/Support/Utils.h
@@ -545,9 +545,52 @@ class IsEqualEvaluateExpr {
return isEqual(x.proc(), y.proc()) && isEqual(x.arguments(), y.arguments());
}
template <typename A>
+ static bool isEqual(const Fortran::evaluate::ImpliedDo<A> &x,
+ const Fortran::evaluate::ImpliedDo<A> &y) {
+ using Expr = Fortran::evaluate::Expr<A>;
+ 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 <typename A>
static bool isEqual(const Fortran::evaluate::ArrayConstructor<A> &x,
const Fortran::evaluate::ArrayConstructor<A> &y) {
- llvm::report_fatal_error("not implemented");
+ for (const auto &[xValue, yValue] : llvm::zip(x, y)) {
+ using Expr = Fortran::evaluate::Expr<A>;
+ using ImpliedDo = Fortran::evaluate::ImpliedDo<A>;
+ 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) {
diff --git a/flang/test/Lower/OpenMP/atomic-update.f90 b/flang/test/Lower/OpenMP/atomic-update.f90
index 16dae9d5f301c1..7d04745015faab 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<?xi32> {
+!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<i32> {
+!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
``````````
</details>
https://github.com/llvm/llvm-project/pull/121181
More information about the flang-commits
mailing list