Skip to content

Commit

Permalink
[flang] Fix CONTIGUOUS attribute for construct entities
Browse files Browse the repository at this point in the history
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
  • Loading branch information
klausler committed Mar 2, 2023
1 parent 51b2f21 commit 057b6fb
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 19 deletions.
2 changes: 2 additions & 0 deletions flang/lib/Evaluate/check-expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
49 changes: 35 additions & 14 deletions flang/test/Evaluate/folding09.f90
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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
6 changes: 3 additions & 3 deletions flang/test/Lower/HLFIR/associate-construct.f90
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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

0 comments on commit 057b6fb

Please sign in to comment.