[flang-commits] [PATCH] D117686: [flang] Prevent any non constant result extent to be inlined on caller side

Jean Perier via Phabricator via flang-commits flang-commits at lists.llvm.org
Wed Jan 19 08:34:08 PST 2022


jeanPerier created this revision.
jeanPerier added a reviewer: klausler.
jeanPerier added a project: Flang.
Herald added a subscriber: jdoerfert.
jeanPerier requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

UBOUND, SIZE, and SHAPE folding was still creating expressions that are
invalid on the caller side without the call expression context.
A previous patch intended to deal with this situation (https://reviews.llvm.org/D116933)
but it assumed the return expression would be a descriptor inquiry to
the result symbol, which is not the case if the extent expression is
"scope invariant" inside the called subroutine (e.g., referring to
intent(in) dummy arguments). Simply prevent folding from inlining non
constant extent expression on the caller side.

Folding could be later improved by having ad-hoc folding for UBOUND, SIZE, and
SHAPE on function references where it could try replacing the dummy symbols
by the actual expression, but this is left as a possible later improvement.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D117686

Files:
  flang/lib/Evaluate/shape.cpp
  flang/test/Evaluate/rewrite01.f90


Index: flang/test/Evaluate/rewrite01.f90
===================================================================
--- flang/test/Evaluate/rewrite01.f90
+++ flang/test/Evaluate/rewrite01.f90
@@ -12,6 +12,17 @@
   returns_array = 0
 end function
 
+function returns_array_2(n)
+  integer, intent(in) :: n
+  integer :: returns_array_2(n)
+  returns_array_2 = 0
+end function
+
+function returns_array_3()
+  integer :: returns_array_3(7:46+2)
+  returns_array_3 = 0
+end function
+
 subroutine ubound_test(x, n, m)
   integer :: x(n, m)
   !CHECK: PRINT *, [INTEGER(4)::int(size(x,dim=1),kind=4),int(size(x,dim=2),kind=4)]
@@ -20,6 +31,10 @@
   print *, ubound(returns_array(n, m))
   !CHECK: PRINT *, ubound(returns_array(n,m),dim=1_4)
   print *, ubound(returns_array(n, m), dim=1)
+  !CHECK: PRINT *, ubound(returns_array_2(m))
+  print *, ubound(returns_array_2(m))
+  !CHECK: PRINT *, 42_8
+  print *, ubound(returns_array_3(), dim=1, kind=8)
 end subroutine
 
 subroutine size_test(x, n, m)
@@ -30,6 +45,10 @@
   print *, size(returns_array(n, m))
   !CHECK: PRINT *, size(returns_array(n,m),dim=1_4)
   print *, size(returns_array(n, m), dim=1)
+  !CHECK: PRINT *, size(returns_array_2(m))
+  print *, size(returns_array_2(m))
+  !CHECK: PRINT *, 42_8
+  print *, size(returns_array_3(), kind=8)
 end subroutine
 
 subroutine shape_test(x, n, m)
@@ -38,6 +57,10 @@
   print *, shape(x)
   !CHECK: PRINT *, shape(returns_array(n,m))
   print *, shape(returns_array(n, m))
+  !CHECK: PRINT *, shape(returns_array_2(m))
+  print *, shape(returns_array_2(m))
+  !CHECK: PRINT *, [INTEGER(8)::42_8]
+  print *, shape(returns_array_3(), kind=8)
 end subroutine
 
 subroutine lbound_test(x, n, m)
@@ -48,5 +71,9 @@
   print *, lbound(returns_array(n, m))
   !CHECK: PRINT *, 1_4
   print *, lbound(returns_array(n, m), dim=1)
+  !CHECK: PRINT *, 1_4
+  print *, lbound(returns_array_2(m), dim=1)
+  !CHECK: PRINT *, 1_4
+  print *, lbound(returns_array_3(), dim=1)
 end subroutine
 end module
Index: flang/lib/Evaluate/shape.cpp
===================================================================
--- flang/lib/Evaluate/shape.cpp
+++ flang/lib/Evaluate/shape.cpp
@@ -560,13 +560,12 @@
             if (subp.isFunction()) {
               auto resultShape{(*this)(subp.result())};
               if (resultShape && !useResultSymbolShape_) {
-                // Ensure the shape does not contain descriptor inquiries, they
-                // may refer to symbols belonging to the called subprogram scope
-                // that are meaningless on the caller side without the related
-                // call expression.
+                // Ensure the shape is constant. Otherwise, it may be referring
+                // to symbols that belong to the subroutine scope and are
+                // meaningless on the caller side without the related call
+                // expression.
                 for (auto extent : *resultShape) {
-                  if (extent &&
-                      std::holds_alternative<DescriptorInquiry>(extent->u)) {
+                  if (extent && !IsConstantExpr(*extent)) {
                     return std::nullopt;
                   }
                 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D117686.401259.patch
Type: text/x-patch
Size: 3184 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20220119/233fd2b9/attachment.bin>


More information about the flang-commits mailing list