[flang-commits] [flang] 057b6fb - [flang] Fix CONTIGUOUS attribute for construct entities

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Mar 2 14:06:44 PST 2023


Author: Peter Klausler
Date: 2023-03-02T14:06:37-08:00
New Revision: 057b6fb61f129e085e469d3675ead1c9b2f93e83

URL: https://github.com/llvm/llvm-project/commit/057b6fb61f129e085e469d3675ead1c9b2f93e83
DIFF: https://github.com/llvm/llvm-project/commit/057b6fb61f129e085e469d3675ead1c9b2f93e83.diff

LOG: [flang] Fix CONTIGUOUS attribute for construct entities

Currently, the selector of a construct entity (e.g., ASSOCIATE(x=>a(1:20)))
is inheriting the CONTIGUOUS attribute from its associated variable
even if it has subscripts that make it noncontiguous (a(1:20:2)).
Add construct entities to the dynamic contiguity predicate instead.

Differential Revision: https://reviews.llvm.org/D145114

Added: 
    

Modified: 
    flang/lib/Evaluate/check-expression.cpp
    flang/lib/Semantics/resolve-names.cpp
    flang/test/Evaluate/folding09.f90
    flang/test/Lower/HLFIR/associate-construct.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index 12ffdc9b0a194..57d25c8091872 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -765,6 +765,8 @@ class IsContiguousHelper
       // simple contiguity to allow their use in contexts like
       // data targets in pointer assignments with remapping.
       return true;
+    } else if (ultimate.has<semantics::AssocEntityDetails>()) {
+      return Base::operator()(ultimate); // use expr
     } else if (semantics::IsPointer(ultimate) ||
         semantics::IsAssumedShape(ultimate)) {
       return std::nullopt;

diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index dbce1ac262cb1..637d133798a51 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6655,8 +6655,8 @@ void ConstructVisitor::SetTypeFromAssociation(Symbol &symbol) {
 // If current selector is a variable, set some of its attributes on symbol.
 void ConstructVisitor::SetAttrsFromAssociation(Symbol &symbol) {
   Attrs attrs{evaluate::GetAttrs(GetCurrentAssociation().selector.expr)};
-  symbol.attrs() |= attrs &
-      Attrs{Attr::TARGET, Attr::ASYNCHRONOUS, Attr::VOLATILE, Attr::CONTIGUOUS};
+  symbol.attrs() |=
+      attrs & Attrs{Attr::TARGET, Attr::ASYNCHRONOUS, Attr::VOLATILE};
   if (attrs.test(Attr::POINTER)) {
     SetImplicitAttr(symbol, Attr::TARGET);
   }

diff  --git a/flang/test/Evaluate/folding09.f90 b/flang/test/Evaluate/folding09.f90
index 58ddc44925e49..055cdaf161915 100644
--- a/flang/test/Evaluate/folding09.f90
+++ b/flang/test/Evaluate/folding09.f90
@@ -1,6 +1,5 @@
 ! RUN: %python %S/test_folding.py %s %flang_fc1
-! Test folding of IS_CONTIGUOUS on simply contiguous items (9.5.4)
-! When IS_CONTIGUOUS() is constant, it's .TRUE.
+! Test folding of IS_CONTIGUOUS
 
 module m
   real, target :: hosted(2)
@@ -14,17 +13,39 @@ subroutine test(arr1, arr2, arr3, mat, alloc)
     real, intent(in), contiguous :: arr3(:)
     real, allocatable :: alloc(:)
     real :: scalar
-    logical, parameter :: test_isc01 = is_contiguous(0)
-    logical, parameter :: test_isc02 = is_contiguous(scalar)
-    logical, parameter :: test_isc03 = is_contiguous(scalar + scalar)
-    logical, parameter :: test_isc04 = is_contiguous([0, 1, 2])
-    logical, parameter :: test_isc05 = is_contiguous(arr1 + 1.0)
-    logical, parameter :: test_isc06 = is_contiguous(arr2)
-    logical, parameter :: test_isc07 = is_contiguous(mat)
-    logical, parameter :: test_isc08 = is_contiguous(mat(1:10,1))
-    logical, parameter :: test_isc09 = is_contiguous(arr2(1:10:1))
-    logical, parameter :: test_isc10 = is_contiguous(arr3)
-    logical, parameter :: test_isc11 = is_contiguous(f())
-    logical, parameter :: test_isc12 = is_contiguous(alloc)
+    integer(kind=merge(1,-1,       is_contiguous(0)))               t01
+    integer(kind=merge(1,-1,       is_contiguous(scalar)))          t02
+    integer(kind=merge(1,-1,       is_contiguous(scalar + scalar))) t03
+    integer(kind=merge(1,-1,       is_contiguous([0, 1, 2])))       t04
+    integer(kind=merge(1,-1,       is_contiguous(arr1 + 1.0)))      t05
+    integer(kind=merge(1,-1,       is_contiguous(arr2)))            t06
+    integer(kind=merge(1,-1,       is_contiguous(mat)))             t07
+    integer(kind=merge(1,-1,       is_contiguous(mat(1:10,1))))     t08
+    integer(kind=merge(1,-1,       is_contiguous(arr2(1:10:1))))    t09
+    integer(kind=merge(1,-1, .not. is_contiguous(arr2(1:10:2))))    t10
+    integer(kind=merge(1,-1,       is_contiguous(arr3)))            t11
+    integer(kind=merge(1,-1, .not. is_contiguous(arr3(1:10:2))))    t12
+    integer(kind=merge(1,-1,       is_contiguous(f())))             t13
+    integer(kind=merge(1,-1,       is_contiguous(alloc)))           t14
+    associate (x => arr2)
+      block
+        integer(kind=merge(1,-1,is_contiguous(x))) n
+      end block
+    end associate
+    associate (x => arr2(1:10:2))
+      block
+        integer(kind=merge(1,-1,.not. is_contiguous(x))) n
+      end block
+    end associate
+    associate (x => arr3)
+      block
+        integer(kind=merge(1,-1,is_contiguous(x))) n
+      end block
+    end associate
+    associate (x => arr3(1:10:2))
+      block
+        integer(kind=merge(1,-1,.not. is_contiguous(x))) n
+      end block
+    end associate
   end subroutine
 end module

diff  --git a/flang/test/Lower/HLFIR/associate-construct.f90 b/flang/test/Lower/HLFIR/associate-construct.f90
index c9f7f2fa35249..be3ace28bf52e 100644
--- a/flang/test/Lower/HLFIR/associate-construct.f90
+++ b/flang/test/Lower/HLFIR/associate-construct.f90
@@ -32,7 +32,7 @@ subroutine associate_var(x)
 
 subroutine associate_pointer(x)
   integer, pointer, contiguous :: x(:)
-  ! Check that "y" has the target and contiguous attributes.
+  ! Check that "y" has the target attribute.
   associate(y => x)
     print *, y
   end associate
@@ -44,7 +44,7 @@ subroutine associate_pointer(x)
 ! CHECK:  %[[VAL_4:.*]] = arith.constant 0 : index
 ! CHECK:  %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
 ! CHECK:  %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
-! CHECK:  %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_6]]) {fortran_attrs = #fir.var_attrs<contiguous, target>, uniq_name = "_QFassociate_pointerEy"} : (!fir.ptr<!fir.array<?xi32>>, !fir.shapeshift<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ptr<!fir.array<?xi32>>)
+! CHECK:  %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_6]]) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFassociate_pointerEy"} : (!fir.ptr<!fir.array<?xi32>>, !fir.shapeshift<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ptr<!fir.array<?xi32>>)
 ! CHECK:  fir.call @_FortranAioEndIoStatement
 ! CHECK-NEXT:  return
 
@@ -92,6 +92,6 @@ subroutine associate_pointer_section(x)
 ! CHECK:  %[[VAL_6:.*]] = arith.constant 20 : index
 ! CHECK:  %[[VAL_8:.*]] = hlfir.designate %[[VAL_2]]{{.*}}
 ! CHECK:  %[[VAL_9:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
-! CHECK:  %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]](%[[VAL_9]]) {fortran_attrs = #fir.var_attrs<contiguous, target>, uniq_name = "_QFassociate_pointer_sectionEy"} : (!fir.ref<!fir.array<20xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<20xi32>>, !fir.ref<!fir.array<20xi32>>)
+! CHECK:  %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]](%[[VAL_9]]) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFassociate_pointer_sectionEy"} : (!fir.ref<!fir.array<20xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<20xi32>>, !fir.ref<!fir.array<20xi32>>)
 ! CHECK:  fir.call @_FortranAioEndIoStatement
 ! CHECK-NEXT:  return


        


More information about the flang-commits mailing list