Skip to content

Commit f70343d

Browse files
committed
[flang] Fix combined folding of FINDLOC/MAXLOC/MINLOC
The tests for folding these intrinsics neglected to name the logical scalars with a leading "test_", so test failures caused by recent work to implement a combined constant folding facility for these intrinsics wasn't catching some bugs. This patch fixes the tests and the bugs. Differential Revision: https://reviews.llvm.org/D112741
1 parent a905c54 commit f70343d

File tree

3 files changed

+84
-71
lines changed

3 files changed

+84
-71
lines changed

flang/lib/Evaluate/fold-integer.cpp

+27-14
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,7 @@ template <WhichLocation WHICH> class LocationHelper {
256256
}
257257
if (dim) { // DIM=
258258
if (*dim < 1 || *dim > array->Rank()) {
259-
context_.messages().Say(
260-
"FINDLOC(DIM=%d) is out of range"_err_en_US, *dim);
259+
context_.messages().Say("DIM=%d is out of range"_err_en_US, *dim);
261260
return std::nullopt;
262261
}
263262
int zbDim{*dim - 1};
@@ -267,22 +266,27 @@ template <WhichLocation WHICH> class LocationHelper {
267266
ConstantSubscript dimLength{array->shape()[zbDim]};
268267
ConstantSubscript n{GetSize(resultShape)};
269268
for (ConstantSubscript j{0}; j < n; ++j) {
270-
ConstantSubscript hit{array->lbounds()[zbDim] - 1};
271-
value.reset();
269+
ConstantSubscript hit{0};
270+
if constexpr (WHICH == WhichLocation::Maxloc ||
271+
WHICH == WhichLocation::Minloc) {
272+
value.reset();
273+
}
272274
for (ConstantSubscript k{0}; k < dimLength;
273275
++k, ++at[zbDim], mask && ++maskAt[zbDim]) {
274276
if ((!mask || mask->At(maskAt).IsTrue()) &&
275277
IsHit(array->At(at), value, relation)) {
276278
hit = at[zbDim];
277-
if (!back) {
278-
break;
279+
if constexpr (WHICH == WhichLocation::Findloc) {
280+
if (!back) {
281+
break;
282+
}
279283
}
280284
}
281285
}
282286
resultIndices.emplace_back(hit);
283-
at[zbDim] = array->lbounds()[zbDim] + dimLength - 1;
287+
at[zbDim] = dimLength;
284288
array->IncrementSubscripts(at);
285-
at[zbDim] = array->lbounds()[zbDim];
289+
at[zbDim] = 1;
286290
if (mask) {
287291
maskAt[zbDim] = mask->lbounds()[zbDim] + dimLength - 1;
288292
mask->IncrementSubscripts(maskAt);
@@ -298,8 +302,10 @@ template <WhichLocation WHICH> class LocationHelper {
298302
if ((!mask || mask->At(maskAt).IsTrue()) &&
299303
IsHit(array->At(at), value, relation)) {
300304
resultIndices = at;
301-
if (!back) {
302-
break;
305+
if constexpr (WHICH == WhichLocation::Findloc) {
306+
if (!back) {
307+
break;
308+
}
303309
}
304310
}
305311
}
@@ -318,6 +324,7 @@ template <WhichLocation WHICH> class LocationHelper {
318324
std::optional<Constant<T>> &value,
319325
[[maybe_unused]] RelationalOperator relation) const {
320326
std::optional<Expr<LogicalResult>> cmp;
327+
bool result{true};
321328
if (value) {
322329
if constexpr (T::category == TypeCategory::Logical) {
323330
// array(at) .EQV. value?
@@ -332,11 +339,17 @@ template <WhichLocation WHICH> class LocationHelper {
332339
Expr<T>{Constant<T>{*value}}));
333340
}
334341
Expr<LogicalResult> folded{Fold(context_, std::move(*cmp))};
335-
return GetScalarConstantValue<LogicalResult>(folded).value().IsTrue();
336-
} else { // first unmasked element seen for MAXLOC/MINLOC
337-
value.emplace(std::move(element));
338-
return true;
342+
result = GetScalarConstantValue<LogicalResult>(folded).value().IsTrue();
343+
} else {
344+
// first unmasked element for MAXLOC/MINLOC - always take it
345+
}
346+
if constexpr (WHICH == WhichLocation::Maxloc ||
347+
WHICH == WhichLocation::Minloc) {
348+
if (result) {
349+
value.emplace(std::move(element));
350+
}
339351
}
352+
return result;
340353
}
341354

342355
static constexpr int dimArg{WHICH == WhichLocation::Findloc ? 2 : 1};

flang/test/Evaluate/fold-findloc.f90

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
! RUN: %python %S/test_folding.py %s %flang_fc1
2+
! Tests folding of FINDLOC, MAXLOC, & MINLOC
3+
module m1
4+
integer, parameter :: ia1(2:6) = [1, 2, 3, 2, 1]
5+
integer, parameter :: ia2(2:3,2:4) = reshape([1, 2, 3, 3, 2, 1], shape(ia2))
6+
7+
logical, parameter :: test_fi1a = all(findloc(ia1, 1) == 1)
8+
logical, parameter :: test_fi1ar = rank(findloc(ia1, 1)) == 1
9+
logical, parameter :: test_fi1ak = kind(findloc(ia1, 1, kind=2)) == 2
10+
logical, parameter :: test_fi1ad = findloc(ia1, 1, dim=1) == 1
11+
logical, parameter :: test_fi1adr = rank(findloc(ia1, 1, dim=1)) == 0
12+
logical, parameter :: test_fi1b = all(findloc(ia1, 1, back=.true.) == 5)
13+
logical, parameter :: test_fi1c = all(findloc(ia1, 2, mask=[.false., .false., .true., .true., .true.]) == 4)
14+
15+
logical, parameter :: test_fi2a = all(findloc(ia2, 1) == [1, 1])
16+
logical, parameter :: test_fi2ar = rank(findloc(ia2, 1)) == 1
17+
logical, parameter :: test_fi2b = all(findloc(ia2, 1, back=.true.) == [2, 3])
18+
logical, parameter :: test_fi2c = all(findloc(ia2, 2, mask=reshape([.false., .false., .true., .true., .true., .false.], shape(ia2))) == [1, 3])
19+
logical, parameter :: test_fi2d = all(findloc(ia2, 1, dim=1) == [1, 0, 2])
20+
logical, parameter :: test_fi2e = all(findloc(ia2, 1, dim=2) == [1, 3])
21+
22+
logical, parameter :: test_xi1a = all(maxloc(ia1) == 3)
23+
logical, parameter :: test_xi1ar = rank(maxloc(ia1)) == 1
24+
logical, parameter :: test_xi1ak = kind(maxloc(ia1, kind=2)) == 2
25+
logical, parameter :: test_xi1ad = maxloc(ia1, dim=1) == 3
26+
logical, parameter :: test_xi1adr = rank(maxloc(ia1, dim=1)) == 0
27+
logical, parameter :: test_xi1b = all(maxloc(ia1, back=.true.) == 3)
28+
logical, parameter :: test_xi1c = all(maxloc(ia1, mask=[.false., .true., .false., .true., .true.]) == 2)
29+
logical, parameter :: test_xi1d = all(maxloc(ia1, mask=[.false., .true., .false., .true., .true.], back=.true.) == 4)
30+
31+
logical, parameter :: test_xi2a = all(maxloc(ia2) == [1, 2])
32+
logical, parameter :: test_xi2ar = rank(maxloc(ia2)) == 1
33+
logical, parameter :: test_xi2b = all(maxloc(ia2, back=.true.) == [2, 2])
34+
logical, parameter :: test_xi2c = all(maxloc(ia2, mask=reshape([.false., .true., .true., .true., .true., .true.], shape(ia2))) == [1, 2])
35+
logical, parameter :: test_xi2d = all(maxloc(ia2, mask=reshape([.false., .true., .true., .true., .true., .true.], shape(ia2)), back=.true.) == [2, 2])
36+
logical, parameter :: test_xi2e = all(maxloc(ia2, dim=1) == [2, 1, 1])
37+
logical, parameter :: test_xi2f = all(maxloc(ia2, dim=1, back=.true.) == [2, 2, 1])
38+
logical, parameter :: test_xi2g = all(maxloc(ia2, dim=2) == [2, 2])
39+
40+
logical, parameter :: test_ni1a = all(minloc(ia1) == 1)
41+
logical, parameter :: test_ni1ar = rank(minloc(ia1)) == 1
42+
logical, parameter :: test_ni1ak = kind(minloc(ia1, kind=2)) == 2
43+
logical, parameter :: test_ni1ad = minloc(ia1, dim=1) == 1
44+
logical, parameter :: test_ni1adr = rank(minloc(ia1, dim=1)) == 0
45+
logical, parameter :: test_ni1b = all(minloc(ia1, back=.true.) == 5)
46+
logical, parameter :: test_ni1c = all(minloc(ia1, mask=[.false., .true., .true., .true., .false.]) == 2)
47+
logical, parameter :: test_ni1d = all(minloc(ia1, mask=[.false., .true., .true., .true., .false.], back=.true.) == 4)
48+
49+
logical, parameter :: test_ni2a = all(minloc(ia2) == [1, 1])
50+
logical, parameter :: test_ni2ar = rank(minloc(ia2)) == 1
51+
logical, parameter :: test_ni2b = all(minloc(ia2, back=.true.) == [2, 3])
52+
logical, parameter :: test_ni2c = all(minloc(ia2, mask=reshape([.false., .true., .true., .false., .true., .false.], shape(ia2))) == [2, 1])
53+
logical, parameter :: test_ni2d = all(minloc(ia2, mask=reshape([.false., .true., .true., .false., .true., .false.], shape(ia2)), back=.true.) == [1, 3])
54+
logical, parameter :: test_ni2e = all(minloc(ia2, dim=1) == [1, 1, 2])
55+
logical, parameter :: test_ni2f = all(minloc(ia2, dim=1, back=.true.) == [1, 2, 2])
56+
logical, parameter :: test_ni2g = all(minloc(ia2, dim=2) == [1, 3])
57+
end module

flang/test/Evaluate/folding30.f90

-57
This file was deleted.

0 commit comments

Comments
 (0)