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

via flang-commits flang-commits at lists.llvm.org
Tue Dec 12 15:02:21 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-runtime

Author: Peter Klausler (klausler)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/75251.diff


1 Files Affected:

- (modified) flang/runtime/findloc.cpp (+13-12) 


``````````diff
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_{};
 };

``````````

</details>


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


More information about the flang-commits mailing list