aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorJonathon Penix <jpenix@quicinc.com>2022-09-29 13:10:19 -0700
committerJonathon Penix <jpenix@quicinc.com>2022-10-03 12:19:53 -0700
commit403d0b7a4e13e8e3bcaa1a0c57ab66ffe761c7af (patch)
treee7884bf37957cba747fe887ed92d8bf3d9a0ed69 /flang
parent5b06ccb6115cc721e7cb8ee650fea93764106e18 (diff)
downloadllvm-403d0b7a4e13e8e3bcaa1a0c57ab66ffe761c7af.zip
llvm-403d0b7a4e13e8e3bcaa1a0c57ab66ffe761c7af.tar.gz
llvm-403d0b7a4e13e8e3bcaa1a0c57ab66ffe761c7af.tar.bz2
[flang] Skip creating AggregateStores for common block associated aggregates
Previously, AggregateStores were created for aggregates associated with common blocks. As a) AggregateStoreMap uses scope and offset information to search for aggregate stores and b) variables related to common blocks have their offsets set relative to the common block itself, if there were multiple equivalences and at least one involved variables defined in a common block there was an opportunity for the scope/offset pairs to match between distinct aggregate stores. As a result, entries in AggregateStoreMap could collide, resulting in incorrect stores being returned for a particular variable. To prevent these collisions, skip creating AggregateStores for aggregates which are associated with common blocks. This information was already unused as aggregates associated with common blocks are handled by instantiateCommon. Fixes https://github.com/llvm/llvm-project/issues/57749 Differential Revision: https://reviews.llvm.org/D134828
Diffstat (limited to 'flang')
-rw-r--r--flang/lib/Lower/PFTBuilder.cpp7
-rw-r--r--flang/test/Lower/equivalence-2.f9031
2 files changed, 38 insertions, 0 deletions
diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp
index 1c93fd4..62ec5ad 100644
--- a/flang/lib/Lower/PFTBuilder.cpp
+++ b/flang/lib/Lower/PFTBuilder.cpp
@@ -1324,6 +1324,13 @@ struct SymbolDependenceDepth {
const Fortran::semantics::Symbol *aggregateSym = nullptr;
bool isGlobal = false;
const semantics::Symbol &first = *aggregate.front();
+ // Skip aggregates related to common blocks as they will be handled by
+ // instantiateCommon and the aggregate store information will not be used.
+ // Additionally, the AggregateStoreKeys for common block related aggregate
+ // stores can collide with non common block ones, potentially resulting in
+ // incorrect stores being used.
+ if (lower::definedInCommonBlock(first))
+ continue;
std::size_t start = first.offset();
std::size_t end = first.offset() + first.size();
const Fortran::semantics::Symbol *namingSym = nullptr;
diff --git a/flang/test/Lower/equivalence-2.f90 b/flang/test/Lower/equivalence-2.f90
index 476a9a4..610e741 100644
--- a/flang/test/Lower/equivalence-2.f90
+++ b/flang/test/Lower/equivalence-2.f90
@@ -97,3 +97,34 @@ end
! CHECK: %[[xCast:.*]] = fir.convert %[[x]] : (!fir.ptr<!fir.array<2xf32>>) -> !fir.ref<!fir.array<2xf32>>
! CHECK: %[[iCast:.*]] = fir.convert %[[i]] : (!fir.ptr<i32>) -> !fir.ref<i32>
! CHECK: fir.call @_QPfoo2(%[[xCast]], %[[iCast]]) : (!fir.ref<!fir.array<2xf32>>, !fir.ref<i32>) -> ()
+
+
+! Check that cases where equivalenced local variables and common blocks will
+! share the same offset use the correct stores
+! CHECK-LABEL: @_QPeq_and_comm_same_offset()
+subroutine eq_and_comm_same_offset
+ real common_arr1(133),common_arr2(133)
+ common /my_common_block/ common_arr1,common_arr2
+ real arr1(133),arr2(133)
+ real arr3(133,133),arr4(133,133)
+ equivalence(arr1,common_arr1),(arr2,common_arr2)
+ equivalence(arr3,arr4)
+
+ ! CHECK: %[[arr4Store:.*]] = fir.alloca !fir.array<70756xi8> {uniq_name = "_QFeq_and_comm_same_offsetEarr3"}
+ ! CHECK: %[[mcbAddr:.*]] = fir.address_of(@_QBmy_common_block) : !fir.ref<!fir.array<1064xi8>>
+ ! CHECK: %[[mcbCast:.*]] = fir.convert %[[mcbAddr]] : (!fir.ref<!fir.array<1064xi8>>) -> !fir.ref<!fir.array<?xi8>>
+ ! CHECK: %[[c0:.*]] = arith.constant 0 : index
+ ! CHECK: %[[mcbCoor:.*]] = fir.coordinate_of %[[mcbCast]], %[[c0]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+ ! CHECK: %[[mcbCoorCast:.*]] = fir.convert %[[mcbCoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.array<133xf32>>
+ ! CHECK: %[[c1:.*]] = arith.constant 0 : index
+ ! CHECK: %[[arr4Addr:.*]] = fir.coordinate_of %[[arr4Store]], %[[c1]] : (!fir.ref<!fir.array<70756xi8>>, index) -> !fir.ref<i8>
+ ! CHECK: %[[arr4Cast:.*]] = fir.convert %[[arr4Addr]] : (!fir.ref<i8>) -> !fir.ptr<!fir.array<133x133xf32>>
+
+ arr1(1) = 1
+ ! CHECK:%[[mcbFinalAddr:.*]] = fir.coordinate_of %[[mcbCoorCast]], %{{.*}} : (!fir.ptr<!fir.array<133xf32>>, i64) -> !fir.ref<f32>
+ ! CHECK:fir.store %{{.*}} to %[[mcbFinalAddr]] : !fir.ref<f32>
+
+ arr4(1,1) = 2
+ ! CHECK: %[[arr4FinalAddr:.*]] = fir.coordinate_of %[[arr4Cast]], %{{.*}}, %{{.*}} : (!fir.ptr<!fir.array<133x133xf32>>, i64, i64) -> !fir.ref<f32>
+ ! CHECK: fir.store %{{.*}} to %[[arr4FinalAddr]] : !fir.ref<f32>
+end subroutine