[PATCH] D91440: [flang] Fix "EQ" comparison of arrays

Pete Steinfeld via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 13 09:33:39 PST 2020


PeteSteinfeld created this revision.
PeteSteinfeld added reviewers: klausler, tskeith.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
PeteSteinfeld requested review of this revision.

When comparing arrays whose shapes do not conform, the contant folding
code ran into problems trying to get the value of an extent that did not
exist.  There were actually two problems.  First, the routine
"CheckConformance()" was returning "true" when the compiler was unable
to get the extent of an array.  Second, the function
"ApplyElementwise()" was calling "CheckConformance()" prior to folding
the elements of two arrays, but it was ignoring the return value.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D91440

Files:
  flang/lib/Evaluate/fold-implementation.h
  flang/lib/Evaluate/shape.cpp
  flang/test/Semantics/shape.f90


Index: flang/test/Semantics/shape.f90
===================================================================
--- /dev/null
+++ flang/test/Semantics/shape.f90
@@ -0,0 +1,43 @@
+! RUN: %S/test_errors.sh %s %t %f18
+! Test comparisons that use the intrinsic SHAPE() as an operand
+program testShape
+contains
+  subroutine sub1(arrayDummy)
+    integer :: arrayDummy(:)
+    integer, allocatable :: arrayDeferred(:)
+    integer :: arrayLocal(2) = [88, 99]
+    if (all(shape(arrayDummy)==shape(8))) then
+      print *, "hello"
+    end if
+    if (all(shape(27)==shape(arrayDummy))) then
+      print *, "hello"
+    end if
+    if (all(64==shape(arrayDummy))) then
+      print *, "hello"
+    end if
+    if (all(shape(arrayDeferred)==shape(8))) then
+      print *, "hello"
+    end if
+    if (all(shape(27)==shape(arrayDeferred))) then
+      print *, "hello"
+    end if
+    if (all(64==shape(arrayDeferred))) then
+      print *, "hello"
+    end if
+    !ERROR: Dimension 1 of left operand has extent 1, but right operand has extent 0
+    !ERROR: Dimension 1 of left operand has extent 1, but right operand has extent 0
+    !ERROR: Dimension 1 of left operand has extent 1, but right operand has extent 0
+    if (all(shape(arrayLocal)==shape(8))) then
+      print *, "hello"
+    end if
+    !ERROR: Dimension 1 of left operand has extent 0, but right operand has extent 1
+    !ERROR: Dimension 1 of left operand has extent 0, but right operand has extent 1
+    !ERROR: Dimension 1 of left operand has extent 0, but right operand has extent 1
+    if (all(shape(27)==shape(arrayLocal))) then
+      print *, "hello"
+    end if
+    if (all(64==shape(arrayLocal))) then
+      print *, "hello"
+    end if
+  end subroutine sub1
+end program testShape
Index: flang/lib/Evaluate/shape.cpp
===================================================================
--- flang/lib/Evaluate/shape.cpp
+++ flang/lib/Evaluate/shape.cpp
@@ -682,6 +682,8 @@
   return std::nullopt;
 }
 
+// Check conformance of the passed shapes.  Only return true if we can verify
+// that they conform
 bool CheckConformance(parser::ContextualMessages &messages, const Shape &left,
     const Shape &right, const char *leftIs, const char *rightIs) {
   int n{GetRank(left)};
@@ -701,7 +703,11 @@
                   j + 1, leftIs, *leftDim, rightIs, *rightDim);
               return false;
             }
+          } else { // Couldn't get the right extent
+            return false;
           }
+        } else { // Couldn't get the left extent
+          return false;
         }
       }
     }
Index: flang/lib/Evaluate/fold-implementation.h
===================================================================
--- flang/lib/Evaluate/fold-implementation.h
+++ flang/lib/Evaluate/fold-implementation.h
@@ -1113,7 +1113,13 @@
         if (rightExpr.Rank() > 0) {
           if (std::optional<Shape> rightShape{GetShape(context, rightExpr)}) {
             if (auto right{AsFlatArrayConstructor(rightExpr)}) {
-              CheckConformance(context.messages(), *leftShape, *rightShape);
+              if (CheckConformance(
+                      context.messages(), *leftShape, *rightShape)) {
+                return MapOperation(context, std::move(f), *leftShape,
+                    std::move(*left), std::move(*right));
+              } else {
+                return std::nullopt;
+              }
               return MapOperation(context, std::move(f), *leftShape,
                   std::move(*left), std::move(*right));
             }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91440.305197.patch
Type: text/x-patch
Size: 3531 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201113/af8cb947/attachment.bin>


More information about the llvm-commits mailing list