Skip to content

Commit d2ae11c

Browse files
[flang]Fix global variables going missing in optimisation
When using `opt` or `clang` to convert llvm-ir produced by `tco`, globals that are declared in a fortran module, but not actually used by that module, the optimiser decides to remove the variable when it is marked `linkonce`. This patch removes the `linkonce` attribute from module global variables, and updates related tests.
1 parent d07dad8 commit d2ae11c

File tree

6 files changed

+19
-24
lines changed

6 files changed

+19
-24
lines changed

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,14 +1650,9 @@ void Fortran::lower::mapSymbolAttributes(
16501650

16511651
void Fortran::lower::defineModuleVariable(
16521652
AbstractConverter &converter, const Fortran::lower::pft::Variable &var) {
1653-
// linkOnce linkage allows the definition to be kept by LLVM
1654-
// even if it is unused and there is not init (other than undef).
1655-
// Emitting llvm :'@glob = global type undef' would also work, but mlir
1656-
// always insert "external" and removes the undef init when lowering a
1657-
// global without explicit linkage. This ends-up in llvm removing the
1658-
// symbol if unsued potentially creating linking issues. Hence the use
1659-
// of linkOnce.
1660-
auto linkOnce = converter.getFirOpBuilder().createLinkOnceLinkage();
1653+
// Use empty linkage for module variables, which makes them available
1654+
// for use in another unit.
1655+
mlir::StringAttr externalLinkage;
16611656
// Only define variable owned by this module
16621657
if (var.isDeclaration())
16631658
return;
@@ -1668,7 +1663,7 @@ void Fortran::lower::defineModuleVariable(
16681663
if (var.isAggregateStore()) {
16691664
auto &aggregate = var.getAggregateStore();
16701665
auto aggName = mangleGlobalAggregateStore(aggregate);
1671-
defineGlobalAggregateStore(converter, aggregate, aggName, linkOnce);
1666+
defineGlobalAggregateStore(converter, aggregate, aggName, externalLinkage);
16721667
return;
16731668
}
16741669
const auto &sym = var.getSymbol();
@@ -1680,7 +1675,7 @@ void Fortran::lower::defineModuleVariable(
16801675
// Do nothing. Mapping will be done on user side.
16811676
} else {
16821677
auto globalName = Fortran::lower::mangle::mangleName(sym);
1683-
defineGlobal(converter, var, globalName, linkOnce);
1678+
defineGlobal(converter, var, globalName, externalLinkage);
16841679
}
16851680
}
16861681

flang/test/Lower/allocatable-globals.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
! Test global allocatable definition lowering
55

6-
! CHECK-LABEL: fir.global linkonce @_QMmod_allocatablesEc : !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>> {
6+
! CHECK-LABEL: fir.global @_QMmod_allocatablesEc : !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>> {
77
! CHECK-DAG: %[[modcNullAddr:.*]] = fir.zero_bits !fir.heap<!fir.array<?x!fir.char<1,10>>>
88
! CHECK-DAG: %[[modcShape:.*]] = fir.shape %c0{{.*}} : (index) -> !fir.shape<1>
99
! CHECK: %[[modcInitBox:.*]] = fir.embox %[[modcNullAddr]](%[[modcShape]]) : (!fir.heap<!fir.array<?x!fir.char<1,10>>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>

flang/test/Lower/default-initialization-globals.f90

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ module tinit
5757

5858
! Test scalar with default init
5959
type(t0) :: at0
60-
! CHECK-LABEL: fir.global linkonce @_QMtinitEat0 : !fir.type<_QMtinitTt0{k:i32}> {
60+
! CHECK-LABEL: fir.global @_QMtinitEat0 : !fir.type<_QMtinitTt0{k:i32}> {
6161
! CHECK: %[[VAL_0:.*]] = constant 66 : i32
6262
! CHECK: %[[VAL_1:.*]] = fir.undefined !fir.type<_QMtinitTt0{k:i32}>
6363
! CHECK: %[[VAL_2:.*]] = fir.insert_value %[[VAL_1]], %[[VAL_0]], ["k", !fir.type<_QMtinitTt0{k:i32}>] : (!fir.type<_QMtinitTt0{k:i32}>, i32) -> !fir.type<_QMtinitTt0{k:i32}>
6464
! CHECK: fir.has_value %[[VAL_2]] : !fir.type<_QMtinitTt0{k:i32}>
6565

6666
! Test array with default init
6767
type(t0) :: bt0(100)
68-
! CHECK-LABEL: linkonce @_QMtinitEbt0 : !fir.array<100x!fir.type<_QMtinitTt0{k:i32}>> {
68+
! CHECK-LABEL: @_QMtinitEbt0 : !fir.array<100x!fir.type<_QMtinitTt0{k:i32}>> {
6969
! CHECK: %[[VAL_3:.*]] = constant 66 : i32
7070
! CHECK: %[[VAL_4:.*]] = fir.undefined !fir.type<_QMtinitTt0{k:i32}>
7171
! CHECK: %[[VAL_5:.*]] = fir.insert_value %[[VAL_4]], %[[VAL_3]], ["k", !fir.type<_QMtinitTt0{k:i32}>] : (!fir.type<_QMtinitTt0{k:i32}>, i32) -> !fir.type<_QMtinitTt0{k:i32}>
@@ -75,15 +75,15 @@ module tinit
7575

7676
! Test default init overridden by explicit init
7777
type(t0) :: ct0 = t0(42)
78-
! CHECK-LABEL: fir.global linkonce @_QMtinitEct0 : !fir.type<_QMtinitTt0{k:i32}> {
78+
! CHECK-LABEL: fir.global @_QMtinitEct0 : !fir.type<_QMtinitTt0{k:i32}> {
7979
! CHECK: %[[VAL_8:.*]] = constant 42 : i32
8080
! CHECK: %[[VAL_9:.*]] = fir.undefined !fir.type<_QMtinitTt0{k:i32}>
8181
! CHECK: %[[VAL_10:.*]] = fir.insert_value %[[VAL_9]], %[[VAL_8]], ["k", !fir.type<_QMtinitTt0{k:i32}>] : (!fir.type<_QMtinitTt0{k:i32}>, i32) -> !fir.type<_QMtinitTt0{k:i32}>
8282
! CHECK: fir.has_value %[[VAL_10]] : !fir.type<_QMtinitTt0{k:i32}>
8383

8484
! Test a non trivial derived type mixing all sorts of default initialization
8585
type(t1) :: dt1
86-
! CHECK-LABEL: linkonce @_QMtinitEdt1 : !fir.type<_QMtinitTt1{{.*}}> {
86+
! CHECK-LABEL: @_QMtinitEdt1 : !fir.type<_QMtinitTt1{{.*}}> {
8787
! CHECK-DAG: %[[VAL_11:.*]] = constant 42 : i32
8888
! CHECK-DAG: %[[VAL_12:.*]] = constant 100 : index
8989
! CHECK-DAG: %[[VAL_13:.*]] = constant 0 : index
@@ -118,7 +118,7 @@ module tinit
118118

119119
! Test a type extending other type with a default init
120120
type(textendst0) :: etextendst0
121-
! CHECK-LABEL: linkonce @_QMtinitEetextendst0 : !fir.type<_QMtinitTtextendst0{k:i32,l:i32}> {
121+
! CHECK-LABEL: @_QMtinitEetextendst0 : !fir.type<_QMtinitTtextendst0{k:i32,l:i32}> {
122122
! CHECK: %[[VAL_42:.*]] = constant 66 : i32
123123
! CHECK: %[[VAL_43:.*]] = fir.undefined !fir.type<_QMtinitTtextendst0{k:i32,l:i32}>
124124
! CHECK: %[[VAL_44:.*]] = fir.insert_value %[[VAL_43]], %[[VAL_42]], ["k", !fir.type<_QMtinitTtextendst0{k:i32,l:i32}>] : (!fir.type<_QMtinitTtextendst0{k:i32,l:i32}>, i32) -> !fir.type<_QMtinitTtextendst0{k:i32,l:i32}>

flang/test/Lower/derived-types.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ module data_mod
190190

191191
! Test globals
192192

193-
! CHECK-DAG: fir.global linkonce @_QMdata_modEsome_c2 : !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}>
194-
! CHECK-DAG: fir.global linkonce @_QMdata_modEsome_r : !fir.type<_QMdTr{x:f32}>
193+
! CHECK-DAG: fir.global @_QMdata_modEsome_c2 : !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}>
194+
! CHECK-DAG: fir.global @_QMdata_modEsome_r : !fir.type<_QMdTr{x:f32}>
195195
! CHECK-DAG: fir.global internal @_QMdFsaved_derivedEsome_c2 : !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}>
196196
! CHECK-DAG: fir.global internal @_QMdFsaved_derivedEsome_r : !fir.type<_QMdTr{x:f32}>

flang/test/Lower/module_definition.f90

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ module m1
88
real :: x
99
integer :: y(100)
1010
end module
11-
! CHECK: fir.global linkonce @_QMm1Ex : f32
12-
! CHECK: fir.global linkonce @_QMm1Ey : !fir.array<100xi32>
11+
! CHECK: fir.global @_QMm1Ex : f32
12+
! CHECK: fir.global @_QMm1Ey : !fir.array<100xi32>
1313

1414
! Module modEq1 defines data that is equivalenced and not used in this
1515
! file.
@@ -21,8 +21,8 @@ module modEq1
2121
real :: y2(10)
2222
equivalence (x1(1), x2(5), x3(10)), (y1, y2(5))
2323
end module
24-
! CHECK-LABEL: fir.global linkonce @_QMmodeq1Ex1 : !fir.array<76xi8>
25-
! CHECK-LABEL: fir.global linkonce @_QMmodeq1Ey1 : !fir.array<10xi32> {
24+
! CHECK-LABEL: fir.global @_QMmodeq1Ex1 : !fir.array<76xi8>
25+
! CHECK-LABEL: fir.global @_QMmodeq1Ey1 : !fir.array<10xi32> {
2626
! CHECK: %[[undef:.*]] = fir.undefined !fir.array<10xi32>
2727
! CHECK: %[[v1:.*]] = fir.insert_on_range %0, %c0{{.*}}, [0 : index, 3 : index] : (!fir.array<10xi32>, i32) -> !fir.array<10xi32>
2828
! CHECK: %[[v2:.*]] = fir.insert_value %1, %c1109917696{{.*}}, [4 : index] : (!fir.array<10xi32>, i32) -> !fir.array<10xi32>

flang/test/Lower/pointer-initial-target-2.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
module some_mod
1010
real, target :: x(100)
1111
real, pointer :: p(:) => x
12-
! CHECK-LABEL: fir.global linkonce @_QMsome_modEp : !fir.box<!fir.ptr<!fir.array<?xf32>>> {
12+
! CHECK-LABEL: fir.global @_QMsome_modEp : !fir.box<!fir.ptr<!fir.array<?xf32>>> {
1313
! CHECK: %[[x:.*]] = fir.address_of(@_QMsome_modEx) : !fir.ref<!fir.array<100xf32>>
1414
! CHECK: %[[shape:.*]] = fir.shape %c100{{.*}} : (index) -> !fir.shape<1>
1515
! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
@@ -22,7 +22,7 @@ module some_mod_2
2222
common /com/ x, y
2323
save :: /com/
2424
real, pointer :: p(:) => y
25-
! CHECK-LABEL: fir.global linkonce @_QMsome_mod_2Ep : !fir.box<!fir.ptr<!fir.array<?xf32>>> {
25+
! CHECK-LABEL: fir.global @_QMsome_mod_2Ep : !fir.box<!fir.ptr<!fir.array<?xf32>>> {
2626
! CHECK: %[[c:.*]] = fir.address_of(@_QBcom) : !fir.ref<!fir.array<1200xi8>>
2727
! CHECK: %[[com:.*]] = fir.convert %[[c]] : (!fir.ref<!fir.array<1200xi8>>) -> !fir.ref<!fir.array<?xi8>>
2828
! CHECK: %[[yRaw:.*]] = fir.coordinate_of %[[com]], %c400{{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>

0 commit comments

Comments
 (0)