[flang-commits] [flang] [flang][runtime] Fix empty FINDLOC() results (PR #75251)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Dec 12 15:01:54 PST 2023


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/75251

When FINDLOC() can't find its target value among the unmasked array elements, it must return a zero result.  Its implementation doesn't sufficiently distinguish a zero result from a hit in an array with lower bound(s) less than one.  Fix by adding a flag to distinguish the case with no hits from cases with hits.

Fixes llvm-test-suite/Fortran/gfortran/regression/findloc_6.f90.

>From 051b2139f85de695cfd45f2c4b21136770e4d8f8 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Tue, 12 Dec 2023 14:58:06 -0800
Subject: [PATCH] [flang][runtime] Fix empty FINDLOC() results

When FINDLOC() can't find its target value among the unmasked
array elements, it must return a zero result.  Its implementation
doesn't sufficiently distinguish a zero result from a hit
in an array with lower bound(s) less than one.  Fix by adding
a flag to distinguish the case with no hits from cases with
hits.

Fixes llvm-test-suite/Fortran/gfortran/regression/findloc_6.f90.
---
 flang/runtime/findloc.cpp | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/flang/runtime/findloc.cpp b/flang/runtime/findloc.cpp
index 339e0c75f05fe1..6b60e523d2a47e 100644
--- a/flang/runtime/findloc.cpp
+++ b/flang/runtime/findloc.cpp
@@ -84,27 +84,27 @@ template <typename EQUALITY> class LocationAccumulator {
 public:
   LocationAccumulator(
       const Descriptor &array, const Descriptor &target, bool back)
-      : array_{array}, target_{target}, back_{back} {
-    Reinitialize();
-  }
-  void Reinitialize() {
-    // per standard: result indices are all zero if no data
-    for (int j{0}; j < rank_; ++j) {
-      location_[j] = 0;
-    }
-  }
+      : array_{array}, target_{target}, back_{back} {}
+  void Reinitialize() { gotAnything_ = false; }
   template <typename A> void GetResult(A *p, int zeroBasedDim = -1) {
     if (zeroBasedDim >= 0) {
-      *p = location_[zeroBasedDim] -
-          array_.GetDimension(zeroBasedDim).LowerBound() + 1;
-    } else {
+      *p = gotAnything_ ? location_[zeroBasedDim] -
+              array_.GetDimension(zeroBasedDim).LowerBound() + 1
+                        : 0;
+    } else if (gotAnything_) {
       for (int j{0}; j < rank_; ++j) {
         p[j] = location_[j] - array_.GetDimension(j).LowerBound() + 1;
       }
+    } else {
+      // no unmasked hits? result is all zeroes
+      for (int j{0}; j < rank_; ++j) {
+        p[j] = 0;
+      }
     }
   }
   template <typename IGNORED> bool AccumulateAt(const SubscriptValue at[]) {
     if (equality_(array_, at, target_)) {
+      gotAnything_ = true;
       for (int j{0}; j < rank_; ++j) {
         location_[j] = at[j];
       }
@@ -119,6 +119,7 @@ template <typename EQUALITY> class LocationAccumulator {
   const Descriptor &target_;
   const bool back_{false};
   const int rank_{array_.rank()};
+  bool gotAnything_{false};
   SubscriptValue location_[maxRank];
   const EQUALITY equality_{};
 };



More information about the flang-commits mailing list