Skip to content

Commit 160da73

Browse files
[Flang] Check if two ArrayConstructor's are Equal (llvm#121181)
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: llvm#104526
1 parent c442b39 commit 160da73

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

flang/lib/Lower/Support/Utils.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,9 +478,47 @@ class IsEqualEvaluateExpr {
478478
return isEqual(x.proc(), y.proc()) && isEqual(x.arguments(), y.arguments());
479479
}
480480
template <typename A>
481+
static bool isEqual(const Fortran::evaluate::ImpliedDo<A> &x,
482+
const Fortran::evaluate::ImpliedDo<A> &y) {
483+
return isEqual(x.values(), y.values()) && isEqual(x.lower(), y.lower()) &&
484+
isEqual(x.upper(), y.upper()) && isEqual(x.stride(), y.stride());
485+
}
486+
template <typename A>
487+
static bool isEqual(const Fortran::evaluate::ArrayConstructorValues<A> &x,
488+
const Fortran::evaluate::ArrayConstructorValues<A> &y) {
489+
using Expr = Fortran::evaluate::Expr<A>;
490+
using ImpliedDo = Fortran::evaluate::ImpliedDo<A>;
491+
for (const auto &[xValue, yValue] : llvm::zip(x, y)) {
492+
bool checkElement = Fortran::common::visit(
493+
common::visitors{
494+
[&](const Expr &v, const Expr &w) { return isEqual(v, w); },
495+
[&](const ImpliedDo &v, const ImpliedDo &w) {
496+
return isEqual(v, w);
497+
},
498+
[&](const Expr &, const ImpliedDo &) { return false; },
499+
[&](const ImpliedDo &, const Expr &) { return false; },
500+
},
501+
xValue.u, yValue.u);
502+
if (!checkElement) {
503+
return false;
504+
}
505+
}
506+
return true;
507+
}
508+
static bool isEqual(const Fortran::evaluate::SubscriptInteger &x,
509+
const Fortran::evaluate::SubscriptInteger &y) {
510+
return x == y;
511+
}
512+
template <typename A>
481513
static bool isEqual(const Fortran::evaluate::ArrayConstructor<A> &x,
482514
const Fortran::evaluate::ArrayConstructor<A> &y) {
483-
llvm::report_fatal_error("not implemented");
515+
bool checkCharacterType = true;
516+
if constexpr (A::category == Fortran::common::TypeCategory::Character) {
517+
checkCharacterType = isEqual(*x.LEN(), *y.LEN());
518+
}
519+
using Base = Fortran::evaluate::ArrayConstructorValues<A>;
520+
return isEqual((Base)x, (Base)y) &&
521+
(x.GetType() == y.GetType() && checkCharacterType);
484522
}
485523
static bool isEqual(const Fortran::evaluate::ImpliedDoIndex &x,
486524
const Fortran::evaluate::ImpliedDoIndex &y) {

flang/test/Lower/OpenMP/atomic-update.f90

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,19 @@ program OmpAtomicUpdate
185185
!$omp atomic update
186186
w = max(w,x,y,z)
187187

188+
!CHECK: %[[IMP_DO:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
189+
!CHECK: ^bb0(%{{.*}}: index):
190+
! [...]
191+
!CHECK: %[[ADD_I1:.*]] = arith.addi {{.*}} : i32
192+
!CHECK: hlfir.yield_element %[[ADD_I1]] : i32
193+
!CHECK: }
194+
! [...]
195+
!CHECK: %[[SUM:.*]] = hlfir.sum %[[IMP_DO]]
196+
!CHECK: omp.atomic.update %[[VAL_X_DECLARE]]#1 : !fir.ref<i32> {
197+
!CHECK: ^bb0(%[[ARG0:.*]]: i32):
198+
!CHECK: %[[ADD_I2:.*]] = arith.addi %[[ARG0]], %[[SUM]] : i32
199+
!CHECK: omp.yield(%[[ADD_I2]] : i32)
200+
!CHECK: }
201+
!$omp atomic update
202+
x = x + sum([ (y+2, y=1, z) ])
188203
end program OmpAtomicUpdate

0 commit comments

Comments
 (0)