Skip to content

Commit e7b8e18

Browse files
authored
[flang] Set SAVE attribute for EQUIVALENCEd symbols consistently. (llvm#67078)
Example: ``` subroutine global_sub() integer, dimension(4) :: iarr4=(/1,2,3,4/) integer, dimension(4) :: jarr4 equivalence(iarr4,jarr4) call sub1 print *, iarr4 contains subroutine sub1 iarr4=jarr4((/4:1:-1/)) end subroutine sub1 end subroutine global_sub ``` `iarr4` and `jarr4` are equivalenced via a global aggregate storage, but the references inside `sub1` are lowered differently. `iarr4` is accessed via the global aggregate storage, while `jarr4` is accessed via the argument tuple. This confuses the FIR alias analysis, that claims that a host associated entity cannot alias with a global (if they have different source and do not have Target/Pointer attributes deduced by the alias analysis). I am not convinced that there is an issue in the alias analysis yet. I think we'd better lower the accesses uniformly, i.e. if one variable from an equivalence is lowered via the global aggregate storage, then any other variable from this equivalence should be lowered the same way (even if they are used via host association). This patch makes sure that all symbols from an EQUIVALENCE get and implicit SAVE attribute, if they do not have it already and any symbol from the EQUIVALENCE is SAVEd (explicitly or implicitly). This makes the further lowering consistent.
1 parent 0455596 commit e7b8e18

File tree

7 files changed

+265
-18
lines changed

7 files changed

+265
-18
lines changed

flang/lib/Lower/HostAssociations.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,12 +508,13 @@ void Fortran::lower::HostAssociations::addSymbolsToBind(
508508
"must be initially empty");
509509
this->hostScope = &hostScope;
510510
for (const auto *s : symbols)
511-
if (Fortran::lower::symbolIsGlobal(*s))
511+
if (Fortran::lower::symbolIsGlobal(*s)) {
512512
// The ultimate symbol is stored here so that global symbols from the
513513
// host scope can later be searched in this set.
514514
globalSymbols.insert(&s->GetUltimate());
515-
else
515+
} else {
516516
tupleSymbols.insert(s);
517+
}
517518
}
518519

519520
void Fortran::lower::HostAssociations::hostProcedureBindings(

flang/lib/Semantics/resolve-names-utils.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -353,17 +353,17 @@ Bound ArraySpecAnalyzer::GetBound(const parser::SpecificationExpr &x) {
353353
return Bound{std::move(expr)};
354354
}
355355

356-
// If SAVE is set on src, set it on all members of dst
356+
// If src is SAVE (explicitly or implicitly),
357+
// set SAVE attribute on all members of dst.
357358
static void PropagateSaveAttr(
358359
const EquivalenceObject &src, EquivalenceSet &dst) {
359-
if (src.symbol.attrs().test(Attr::SAVE)) {
360-
bool isImplicit{src.symbol.implicitAttrs().test(Attr::SAVE)};
360+
if (IsSaved(src.symbol)) {
361361
for (auto &obj : dst) {
362362
if (!obj.symbol.attrs().test(Attr::SAVE)) {
363363
obj.symbol.attrs().set(Attr::SAVE);
364-
if (isImplicit) {
365-
obj.symbol.implicitAttrs().set(Attr::SAVE);
366-
}
364+
// If the other equivalenced symbol itself is not SAVE,
365+
// then adding SAVE here implies that it has to be implicit.
366+
obj.symbol.implicitAttrs().set(Attr::SAVE);
367367
}
368368
}
369369
}

flang/lib/Semantics/resolve-names.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,6 +2391,12 @@ Symbol &ScopeHandler::MakeHostAssocSymbol(
23912391
// on the host-associated name, at most once (C815).
23922392
symbol.implicitAttrs() =
23932393
symbol.attrs() & Attrs{Attr::ASYNCHRONOUS, Attr::VOLATILE};
2394+
// SAVE statement in the inner scope will create a new symbol.
2395+
// If the host variable is used via host association,
2396+
// we have to propagate whether SAVE is implicit in the host scope.
2397+
// Otherwise, verifications that do not allow explicit SAVE
2398+
// attribute would fail.
2399+
symbol.implicitAttrs() |= hostSymbol.implicitAttrs() & Attrs{Attr::SAVE};
23942400
symbol.flags() = hostSymbol.flags();
23952401
return symbol;
23962402
}
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
! RUN: bbc -emit-fir -o - %s | FileCheck %s --check-prefixes=FIR
2+
! RUN: bbc -emit-hlfir -o - %s | FileCheck %s --check-prefixes=HLFIR
3+
4+
subroutine test1()
5+
integer :: i1 = 1
6+
integer :: j1
7+
equivalence(i1,j1)
8+
contains
9+
subroutine inner
10+
i1 = j1
11+
end subroutine inner
12+
end subroutine test1
13+
! FIR-LABEL: func.func @_QFtest1Pinner() attributes {fir.internal_proc} {
14+
! FIR: %[[VAL_0:.*]] = fir.address_of(@_QFtest1Ei1) : !fir.ref<!fir.array<1xi32>>
15+
! FIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<1xi32>>) -> !fir.ref<!fir.array<4xi8>>
16+
! FIR: %[[VAL_2:.*]] = arith.constant 0 : index
17+
! FIR: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
18+
! FIR: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ptr<i32>
19+
! FIR: %[[VAL_5:.*]] = arith.constant 0 : index
20+
! FIR: %[[VAL_6:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_5]] : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
21+
! FIR: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<i8>) -> !fir.ptr<i32>
22+
! FIR: %[[VAL_8:.*]] = fir.load %[[VAL_7]] : !fir.ptr<i32>
23+
! FIR: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ptr<i32>
24+
! FIR: return
25+
! FIR: }
26+
27+
! HLFIR-LABEL: func.func @_QFtest1Pinner() attributes {fir.internal_proc} {
28+
! HLFIR: %[[VAL_0:.*]] = fir.address_of(@_QFtest1Ei1) : !fir.ref<!fir.array<1xi32>>
29+
! HLFIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<1xi32>>) -> !fir.ref<!fir.array<4xi8>>
30+
! HLFIR: %[[VAL_2:.*]] = arith.constant 0 : index
31+
! HLFIR: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
32+
! HLFIR: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ptr<i32>
33+
! HLFIR: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QFtest1Ei1"} : (!fir.ptr<i32>) -> (!fir.ptr<i32>, !fir.ptr<i32>)
34+
! HLFIR: %[[VAL_6:.*]] = arith.constant 0 : index
35+
! HLFIR: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_6]] : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
36+
! HLFIR: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<i8>) -> !fir.ptr<i32>
37+
! HLFIR: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_8]] {uniq_name = "_QFtest1Ej1"} : (!fir.ptr<i32>) -> (!fir.ptr<i32>, !fir.ptr<i32>)
38+
! HLFIR: %[[VAL_10:.*]] = fir.load %[[VAL_9]]#0 : !fir.ptr<i32>
39+
! HLFIR: hlfir.assign %[[VAL_10]] to %[[VAL_5]]#0 : i32, !fir.ptr<i32>
40+
! HLFIR: return
41+
! HLFIR: }
42+
43+
module test2
44+
real :: f1, f2
45+
equivalence(f1, f2)
46+
contains
47+
subroutine host
48+
real :: f1 = 1
49+
real :: f2
50+
equivalence(f1, f2)
51+
contains
52+
subroutine inner
53+
f1 = f2
54+
end subroutine inner
55+
end subroutine host
56+
end module test2
57+
! FIR-LABEL: func.func @_QMtest2FhostPinner() attributes {fir.internal_proc} {
58+
! FIR: %[[VAL_0:.*]] = fir.address_of(@_QMtest2FhostEf1) : !fir.ref<!fir.array<1xi32>>
59+
! FIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<1xi32>>) -> !fir.ref<!fir.array<4xi8>>
60+
! FIR: %[[VAL_2:.*]] = arith.constant 0 : index
61+
! FIR: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
62+
! FIR: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ptr<f32>
63+
! FIR: %[[VAL_5:.*]] = arith.constant 0 : index
64+
! FIR: %[[VAL_6:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_5]] : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
65+
! FIR: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<i8>) -> !fir.ptr<f32>
66+
! FIR: %[[VAL_8:.*]] = fir.load %[[VAL_7]] : !fir.ptr<f32>
67+
! FIR: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ptr<f32>
68+
! FIR: return
69+
! FIR: }
70+
71+
! HLFIR-LABEL: func.func @_QMtest2FhostPinner() attributes {fir.internal_proc} {
72+
! HLFIR: %[[VAL_0:.*]] = fir.address_of(@_QMtest2FhostEf1) : !fir.ref<!fir.array<1xi32>>
73+
! HLFIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<1xi32>>) -> !fir.ref<!fir.array<4xi8>>
74+
! HLFIR: %[[VAL_2:.*]] = arith.constant 0 : index
75+
! HLFIR: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
76+
! HLFIR: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ptr<f32>
77+
! HLFIR: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QMtest2FhostEf1"} : (!fir.ptr<f32>) -> (!fir.ptr<f32>, !fir.ptr<f32>)
78+
! HLFIR: %[[VAL_6:.*]] = arith.constant 0 : index
79+
! HLFIR: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_6]] : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
80+
! HLFIR: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<i8>) -> !fir.ptr<f32>
81+
! HLFIR: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_8]] {uniq_name = "_QMtest2FhostEf2"} : (!fir.ptr<f32>) -> (!fir.ptr<f32>, !fir.ptr<f32>)
82+
! HLFIR: %[[VAL_19:.*]] = fir.load %[[VAL_9]]#0 : !fir.ptr<f32>
83+
! HLFIR: hlfir.assign %[[VAL_19]] to %[[VAL_5]]#0 : f32, !fir.ptr<f32>
84+
! HLFIR: return
85+
! HLFIR: }
86+
87+
subroutine test3()
88+
integer :: i1 = 1
89+
integer :: j1, k1
90+
common /blk/ k1
91+
equivalence(i1,j1,k1)
92+
contains
93+
subroutine inner
94+
i1 = j1 + k1
95+
end subroutine inner
96+
end subroutine test3
97+
! FIR-LABEL: func.func @_QFtest3Pinner() attributes {fir.internal_proc} {
98+
! FIR: %[[VAL_0:.*]] = fir.address_of(@blk_) : !fir.ref<tuple<i32>>
99+
! FIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
100+
! FIR: %[[VAL_2:.*]] = arith.constant 0 : index
101+
! FIR: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
102+
! FIR: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ptr<i32>
103+
! FIR: %[[VAL_5:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
104+
! FIR: %[[VAL_6:.*]] = arith.constant 0 : index
105+
! FIR: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_5]], %[[VAL_6]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
106+
! FIR: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<i8>) -> !fir.ptr<i32>
107+
! FIR: %[[VAL_9:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
108+
! FIR: %[[VAL_10:.*]] = arith.constant 0 : index
109+
! FIR: %[[VAL_11:.*]] = fir.coordinate_of %[[VAL_9]], %[[VAL_10]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
110+
! FIR: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.ref<i8>) -> !fir.ptr<i32>
111+
! FIR: %[[VAL_13:.*]] = fir.load %[[VAL_8]] : !fir.ptr<i32>
112+
! FIR: %[[VAL_14:.*]] = fir.load %[[VAL_12]] : !fir.ptr<i32>
113+
! FIR: %[[VAL_15:.*]] = arith.addi %[[VAL_13]], %[[VAL_14]] : i32
114+
! FIR: fir.store %[[VAL_15]] to %[[VAL_4]] : !fir.ptr<i32>
115+
! FIR: return
116+
! FIR: }
117+
118+
! HLFIR-LABEL: func.func @_QFtest3Pinner() attributes {fir.internal_proc} {
119+
! HLFIR: %[[VAL_0:.*]] = fir.address_of(@blk_) : !fir.ref<tuple<i32>>
120+
! HLFIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
121+
! HLFIR: %[[VAL_2:.*]] = arith.constant 0 : index
122+
! HLFIR: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
123+
! HLFIR: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ptr<i32>
124+
! HLFIR: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QFtest3Ei1"} : (!fir.ptr<i32>) -> (!fir.ptr<i32>, !fir.ptr<i32>)
125+
! HLFIR: %[[VAL_6:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
126+
! HLFIR: %[[VAL_7:.*]] = arith.constant 0 : index
127+
! HLFIR: %[[VAL_8:.*]] = fir.coordinate_of %[[VAL_6]], %[[VAL_7]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
128+
! HLFIR: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<i8>) -> !fir.ptr<i32>
129+
! HLFIR: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_9]] {uniq_name = "_QFtest3Ej1"} : (!fir.ptr<i32>) -> (!fir.ptr<i32>, !fir.ptr<i32>)
130+
! HLFIR: %[[VAL_11:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
131+
! HLFIR: %[[VAL_12:.*]] = arith.constant 0 : index
132+
! HLFIR: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_11]], %[[VAL_12]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
133+
! HLFIR: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (!fir.ref<i8>) -> !fir.ptr<i32>
134+
! HLFIR: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_14]] {uniq_name = "_QFtest3Ek1"} : (!fir.ptr<i32>) -> (!fir.ptr<i32>, !fir.ptr<i32>)
135+
! HLFIR: %[[VAL_16:.*]] = fir.load %[[VAL_10]]#0 : !fir.ptr<i32>
136+
! HLFIR: %[[VAL_17:.*]] = fir.load %[[VAL_15]]#0 : !fir.ptr<i32>
137+
! HLFIR: %[[VAL_18:.*]] = arith.addi %[[VAL_16]], %[[VAL_17]] : i32
138+
! HLFIR: hlfir.assign %[[VAL_18]] to %[[VAL_5]]#0 : i32, !fir.ptr<i32>
139+
! HLFIR: return
140+
! HLFIR: }
141+
142+
subroutine test4()
143+
integer :: i1
144+
integer :: j1, k1
145+
common /blk/ k1
146+
equivalence(i1,j1,k1)
147+
contains
148+
subroutine inner
149+
i1 = j1 + k1
150+
end subroutine inner
151+
end subroutine test4
152+
! FIR-LABEL: func.func @_QFtest4Pinner() attributes {fir.internal_proc} {
153+
! FIR: %[[VAL_0:.*]] = fir.address_of(@blk_) : !fir.ref<tuple<i32>>
154+
! FIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
155+
! FIR: %[[VAL_2:.*]] = arith.constant 0 : index
156+
! FIR: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
157+
! FIR: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ptr<i32>
158+
! FIR: %[[VAL_5:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
159+
! FIR: %[[VAL_6:.*]] = arith.constant 0 : index
160+
! FIR: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_5]], %[[VAL_6]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
161+
! FIR: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<i8>) -> !fir.ptr<i32>
162+
! FIR: %[[VAL_9:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
163+
! FIR: %[[VAL_10:.*]] = arith.constant 0 : index
164+
! FIR: %[[VAL_11:.*]] = fir.coordinate_of %[[VAL_9]], %[[VAL_10]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
165+
! FIR: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.ref<i8>) -> !fir.ptr<i32>
166+
! FIR: %[[VAL_13:.*]] = fir.load %[[VAL_8]] : !fir.ptr<i32>
167+
! FIR: %[[VAL_14:.*]] = fir.load %[[VAL_12]] : !fir.ptr<i32>
168+
! FIR: %[[VAL_15:.*]] = arith.addi %[[VAL_13]], %[[VAL_14]] : i32
169+
! FIR: fir.store %[[VAL_15]] to %[[VAL_4]] : !fir.ptr<i32>
170+
! FIR: return
171+
! FIR: }
172+
173+
! HLFIR-LABEL: func.func @_QFtest4Pinner() attributes {fir.internal_proc} {
174+
! HLFIR: %[[VAL_0:.*]] = fir.address_of(@blk_) : !fir.ref<tuple<i32>>
175+
! HLFIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
176+
! HLFIR: %[[VAL_2:.*]] = arith.constant 0 : index
177+
! HLFIR: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
178+
! HLFIR: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ptr<i32>
179+
! HLFIR: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QFtest4Ei1"} : (!fir.ptr<i32>) -> (!fir.ptr<i32>, !fir.ptr<i32>)
180+
! HLFIR: %[[VAL_6:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
181+
! HLFIR: %[[VAL_7:.*]] = arith.constant 0 : index
182+
! HLFIR: %[[VAL_8:.*]] = fir.coordinate_of %[[VAL_6]], %[[VAL_7]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
183+
! HLFIR: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<i8>) -> !fir.ptr<i32>
184+
! HLFIR: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_9]] {uniq_name = "_QFtest4Ej1"} : (!fir.ptr<i32>) -> (!fir.ptr<i32>, !fir.ptr<i32>)
185+
! HLFIR: %[[VAL_11:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
186+
! HLFIR: %[[VAL_12:.*]] = arith.constant 0 : index
187+
! HLFIR: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_11]], %[[VAL_12]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
188+
! HLFIR: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (!fir.ref<i8>) -> !fir.ptr<i32>
189+
! HLFIR: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_14]] {uniq_name = "_QFtest4Ek1"} : (!fir.ptr<i32>) -> (!fir.ptr<i32>, !fir.ptr<i32>)
190+
! HLFIR: %[[VAL_16:.*]] = fir.load %[[VAL_10]]#0 : !fir.ptr<i32>
191+
! HLFIR: %[[VAL_17:.*]] = fir.load %[[VAL_15]]#0 : !fir.ptr<i32>
192+
! HLFIR: %[[VAL_18:.*]] = arith.addi %[[VAL_16]], %[[VAL_17]] : i32
193+
! HLFIR: hlfir.assign %[[VAL_18]] to %[[VAL_5]]#0 : i32, !fir.ptr<i32>
194+
! HLFIR: return
195+
! HLFIR: }

flang/test/Semantics/data13.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
! initialization produces a combined initializer, with explicit
44
! initialization overriding any default component initialization.
55
! CHECK: .F18.0, SAVE (CompilerCreated) size=8 offset=0: ObjectEntity type: INTEGER(4) shape: 1_8:2_8 init:[INTEGER(4)::456_4,234_4]
6-
! CHECK: ja (InDataStmt) size=8 offset=0: ObjectEntity type: INTEGER(4) shape: 1_8:2_8
6+
! CHECK: ja, SAVE (InDataStmt) size=8 offset=0: ObjectEntity type: INTEGER(4) shape: 1_8:2_8
77
! CHECK-NOT: x0, SAVE size=8 offset=8: ObjectEntity type: TYPE(t1) init:t1(m=123_4,n=234_4)
88
! CHECK: x1 size=8 offset=16: ObjectEntity type: TYPE(t1) init:t1(m=345_4,n=234_4)
9-
! CHECK: x2 size=8 offset=0: ObjectEntity type: TYPE(t1)
9+
! CHECK: x2, SAVE size=8 offset=0: ObjectEntity type: TYPE(t1)
1010
! CHECK-NOT: x3a, SAVE size=8 offset=24: ObjectEntity type: TYPE(t3) init:t3(t2=t2(k=567_4),j=0_4)
1111
! CHECK: x3b size=8 offset=32: ObjectEntity type: TYPE(t3) init:t3(k=567_4,j=678_4)
1212
! CHECK: Equivalence Sets: (x2,ja(1)) (.F18.0,x2)

flang/test/Semantics/offsets03.f90

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@
55
! a1 depends on a2 depends on a3
66
module ma
77
real :: a1(10), a2(10), a3(10)
8-
equivalence(a1, a2(3)) !CHECK: a1, PUBLIC size=40 offset=20:
9-
equivalence(a2, a3(4)) !CHECK: a2, PUBLIC size=40 offset=12:
10-
!CHECK: a3, PUBLIC size=40 offset=0:
8+
equivalence(a1, a2(3)) !CHECK: a1, PUBLIC, SAVE size=40 offset=20:
9+
equivalence(a2, a3(4)) !CHECK: a2, PUBLIC, SAVE size=40 offset=12:
10+
!CHECK: a3, PUBLIC, SAVE size=40 offset=0:
1111
end
1212

1313
! equivalence and 2-dimensional array
1414
module mb
1515
real :: b1(4), b2, b3, b4
16-
real :: b(-1:1,2:6) !CHECK: b, PUBLIC size=60 offset=0:
17-
equivalence(b(1,6), b1) !CHECK: b1, PUBLIC size=16 offset=56:
18-
equivalence(b(1,5), b2) !CHECK: b2, PUBLIC size=4 offset=44:
19-
equivalence(b(0,6), b3) !CHECK: b3, PUBLIC size=4 offset=52:
20-
equivalence(b(0,4), b4) !CHECK: b4, PUBLIC size=4 offset=28:
16+
real :: b(-1:1,2:6) !CHECK: b, PUBLIC, SAVE size=60 offset=0:
17+
equivalence(b(1,6), b1) !CHECK: b1, PUBLIC, SAVE size=16 offset=56:
18+
equivalence(b(1,5), b2) !CHECK: b2, PUBLIC, SAVE size=4 offset=44:
19+
equivalence(b(0,6), b3) !CHECK: b3, PUBLIC, SAVE size=4 offset=52:
20+
equivalence(b(0,4), b4) !CHECK: b4, PUBLIC, SAVE size=4 offset=28:
2121
end
2222

2323
! equivalence and substring
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
! Check that symbols without SAVE attribute from an EQUIVALENCE
2+
! with at least one symbol being SAVEd (explicitly or implicitly)
3+
! have implicit SAVE attribute.
4+
!RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s
5+
6+
subroutine test1()
7+
! CHECK-LABEL: Subprogram scope: test1
8+
! CHECK: i1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4) init:1_4
9+
! CHECK: j1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
10+
integer :: i1 = 1
11+
integer :: j1
12+
equivalence(i1,j1)
13+
end subroutine test1
14+
15+
subroutine test2()
16+
! CHECK-LABEL: Subprogram scope: test2
17+
! CHECK: i1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4) init:1_4
18+
! CHECK: j1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
19+
integer :: i1 = 1
20+
integer :: j1
21+
equivalence(j1,i1)
22+
end subroutine test2
23+
24+
subroutine test3()
25+
! CHECK-LABEL: Subprogram scope: test3
26+
! CHECK: i1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
27+
! CHECK: j1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
28+
! CHECK: k1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
29+
integer :: i1
30+
integer :: j1, k1
31+
common /blk/ k1
32+
save /blk/
33+
equivalence(i1,j1,k1)
34+
end subroutine test3
35+
36+
subroutine test4()
37+
! CHECK-LABEL: Subprogram scope: test4
38+
! CHECK: i1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4) init:1_4
39+
! CHECK: j1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
40+
! CHECK: k1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
41+
integer :: i1 = 1
42+
integer :: j1, k1
43+
common /blk/ k1
44+
equivalence(i1,j1,k1)
45+
end subroutine test4

0 commit comments

Comments
 (0)