Skip to content

[Flang] Check if two ArrayConstructor's are Equal #121181

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

Merged
merged 11 commits into from
Feb 19, 2025
Merged
40 changes: 39 additions & 1 deletion flang/lib/Lower/Support/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,47 @@ 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) {
return isEqual(x.values(), y.values()) && isEqual(x.lower(), y.lower()) &&
isEqual(x.upper(), y.upper()) && isEqual(x.stride(), y.stride());
}
template <typename A>
static bool isEqual(const Fortran::evaluate::ArrayConstructorValues<A> &x,
const Fortran::evaluate::ArrayConstructorValues<A> &y) {
using Expr = Fortran::evaluate::Expr<A>;
using ImpliedDo = Fortran::evaluate::ImpliedDo<A>;
for (const auto &[xValue, yValue] : llvm::zip(x, y)) {
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 Expr &, const ImpliedDo &) { return false; },
[&](const ImpliedDo &, const Expr &) { return false; },
},
xValue.u, yValue.u);
if (!checkElement) {
return false;
}
}
return true;
}
static bool isEqual(const Fortran::evaluate::SubscriptInteger &x,
const Fortran::evaluate::SubscriptInteger &y) {
return x == y;
}
template <typename A>
static bool isEqual(const Fortran::evaluate::ArrayConstructor<A> &x,
const Fortran::evaluate::ArrayConstructor<A> &y) {
llvm::report_fatal_error("not implemented");
bool checkCharacterType = true;
if constexpr (A::category == Fortran::common::TypeCategory::Character) {
checkCharacterType = isEqual(*x.LEN(), *y.LEN());
}
using Base = Fortran::evaluate::ArrayConstructorValues<A>;
return isEqual((Base)x, (Base)y) &&
(x.GetType() == y.GetType() && checkCharacterType);
}
static bool isEqual(const Fortran::evaluate::ImpliedDoIndex &x,
const Fortran::evaluate::ImpliedDoIndex &y) {
Expand Down
15 changes: 15 additions & 0 deletions flang/test/Lower/OpenMP/atomic-update.f90
Original file line number Diff line number Diff line change
Expand Up @@ -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