Skip to content

Commit c1654c3

Browse files
authored
[flang] Carry over alignment computed by frontend for COMMON (#94280)
The frontend computes the necessary alignment for COMMON blocks but this information is never carried over to the code generation and can lead to segfault for COMMON block that requires a non default alignment. This patch add an optional attribute on fir.global and carries over the information.
1 parent 7103e60 commit c1654c3

13 files changed

+38
-22
lines changed

flang/include/flang/Optimizer/Dialect/FIROps.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2800,7 +2800,8 @@ def fir_GlobalOp : fir_Op<"global", [IsolatedFromAbove, Symbol]> {
28002800
OptionalAttr<UnitAttr>:$constant,
28012801
OptionalAttr<UnitAttr>:$target,
28022802
OptionalAttr<StrAttr>:$linkName,
2803-
OptionalAttr<cuf_DataAttributeAttr>:$data_attr
2803+
OptionalAttr<cuf_DataAttributeAttr>:$data_attr,
2804+
OptionalAttr<I64Attr>:$alignment
28042805
);
28052806

28062807
let regions = (region AtMostRegion<1>:$region);

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,9 @@ declareCommonBlock(Fortran::lower::AbstractConverter &converter,
12951295
getCommonMembersWithInitAliases(common);
12961296
mlir::Location loc = converter.genLocation(common.name());
12971297
mlir::StringAttr linkage = builder.createCommonLinkage();
1298+
const auto *details =
1299+
common.detailsIf<Fortran::semantics::CommonBlockDetails>();
1300+
assert(details && "Expect CommonBlockDetails on the common symbol");
12981301
if (!commonBlockHasInit(cmnBlkMems)) {
12991302
// A COMMON block sans initializers is initialized to zero.
13001303
// mlir::Vector types must have a strictly positive size, so at least
@@ -1307,7 +1310,8 @@ declareCommonBlock(Fortran::lower::AbstractConverter &converter,
13071310
auto vecTy = mlir::VectorType::get(sz, i8Ty);
13081311
mlir::Attribute zero = builder.getIntegerAttr(i8Ty, 0);
13091312
auto init = mlir::DenseElementsAttr::get(vecTy, llvm::ArrayRef(zero));
1310-
builder.createGlobal(loc, commonTy, commonName, linkage, init);
1313+
global = builder.createGlobal(loc, commonTy, commonName, linkage, init);
1314+
global.setAlignment(details->alignment());
13111315
// No need to add any initial value later.
13121316
return std::nullopt;
13131317
}
@@ -1320,6 +1324,7 @@ declareCommonBlock(Fortran::lower::AbstractConverter &converter,
13201324
getTypeOfCommonWithInit(converter, cmnBlkMems, commonSize);
13211325
// Create the global object, the initial value will be added later.
13221326
global = builder.createGlobal(loc, commonTy, commonName);
1327+
global.setAlignment(details->alignment());
13231328
return std::make_tuple(global, std::move(cmnBlkMems), loc);
13241329
}
13251330

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2742,6 +2742,9 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {
27422742
loc, tyAttr, isConst, linkage, global.getSymName(), initAttr, 0, 0,
27432743
false, false, comdat, attrs, dbgExpr);
27442744

2745+
if (global.getAlignment() && *global.getAlignment() > 0)
2746+
g.setAlignment(*global.getAlignment());
2747+
27452748
auto module = global->getParentOfType<mlir::ModuleOp>();
27462749
// Add comdat if necessary
27472750
if (fir::getTargetTriple(module).supportsCOMDAT() &&

flang/test/Lower/OpenMP/declare-target-data.f90

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,25 @@ module test_0
6262
end module test_0
6363

6464
PROGRAM commons
65-
!CHECK-DAG: fir.global @numbers_ {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : tuple<f32, f32> {
65+
!CHECK-DAG: fir.global @numbers_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : tuple<f32, f32> {
6666
REAL :: one = 1
6767
REAL :: two = 2
6868
COMMON /numbers/ one, two
6969
!$omp declare target(/numbers/)
7070

71-
!CHECK-DAG: fir.global @numbers_link_ {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : tuple<f32, f32> {
71+
!CHECK-DAG: fir.global @numbers_link_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : tuple<f32, f32> {
7272
REAL :: one_link = 1
7373
REAL :: two_link = 2
7474
COMMON /numbers_link/ one_link, two_link
7575
!$omp declare target link(/numbers_link/)
7676

77-
!CHECK-DAG: fir.global @numbers_to_ {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : tuple<f32, f32> {
77+
!CHECK-DAG: fir.global @numbers_to_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : tuple<f32, f32> {
7878
REAL :: one_to = 1
7979
REAL :: two_to = 2
8080
COMMON /numbers_to/ one_to, two_to
8181
!$omp declare target to(/numbers_to/)
8282

83-
!CHECK-DAG: fir.global @numbers_enter_ {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} : tuple<f32, f32> {
83+
!CHECK-DAG: fir.global @numbers_enter_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} : tuple<f32, f32> {
8484
REAL :: one_enter = 1
8585
REAL :: two_enter = 2
8686
COMMON /numbers_enter/ one_enter, two_enter

flang/test/Lower/OpenMP/lastprivate-commonblock.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
22

3-
!CHECK: fir.global common @[[CB_C:.*]](dense<0> : vector<8xi8>) : !fir.array<8xi8>
3+
!CHECK: fir.global common @[[CB_C:.*]](dense<0> : vector<8xi8>) {alignment = 4 : i64} : !fir.array<8xi8>
44
!CHECK-LABEL: func.func @_QPlastprivate_common
55
!CHECK: %[[CB_C_REF:.*]] = fir.address_of(@[[CB_C]]) : !fir.ref<!fir.array<8xi8>>
66
!CHECK: %[[CB_C_REF_CVT:.*]] = fir.convert %[[CB_C_REF]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>

flang/test/Lower/OpenMP/threadprivate-commonblock-use.f90

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

55
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
66

7-
!CHECK: fir.global common @cmn_(dense<0> : vector<4xi8>) : !fir.array<4xi8>
7+
!CHECK: fir.global common @cmn_(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>
88
module m0
99
common /cmn/ k1
1010
!$omp threadprivate(/cmn/)

flang/test/Lower/OpenMP/threadprivate-commonblock.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module test
1212

1313
!$omp threadprivate(/blk/)
1414

15-
!CHECK: fir.global common @blk_(dense<0> : vector<103xi8>) : !fir.array<103xi8>
15+
!CHECK: fir.global common @blk_(dense<0> : vector<103xi8>) {alignment = 8 : i64} : !fir.array<103xi8>
1616

1717
contains
1818
subroutine sub()

flang/test/Lower/OpenMP/threadprivate-use-association.f90

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

44
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
55

6-
!CHECK-DAG: fir.global common @blk_(dense<0> : vector<24xi8>) : !fir.array<24xi8>
6+
!CHECK-DAG: fir.global common @blk_(dense<0> : vector<24xi8>) {alignment = 4 : i64} : !fir.array<24xi8>
77
!CHECK-DAG: fir.global @_QMtestEy : f32 {
88

99
module test

flang/test/Lower/common-block-2.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
! - A blank common that is initialized
66
! - A common block that is initialized outside of a BLOCK DATA.
77

8-
! CHECK-LABEL: fir.global @__BLNK__ : tuple<i32, !fir.array<8xi8>> {
8+
! CHECK-LABEL: fir.global @__BLNK__ {alignment = 4 : i64} : tuple<i32, !fir.array<8xi8>> {
99
! CHECK: %[[undef:.*]] = fir.zero_bits tuple<i32, !fir.array<8xi8>>
1010
! CHECK: %[[init:.*]] = fir.insert_value %[[undef]], %c42{{.*}}, [0 : index] : (tuple<i32, !fir.array<8xi8>>, i32) -> tuple<i32, !fir.array<8xi8>>
1111
! CHECK: fir.has_value %[[init]] : tuple<i32, !fir.array<8xi8>>
1212

13-
! CHECK-LABEL: fir.global @a_ : tuple<i32, !fir.array<8xi8>> {
13+
! CHECK-LABEL: fir.global @a_ {alignment = 4 : i64} : tuple<i32, !fir.array<8xi8>> {
1414
! CHECK: %[[undef:.*]] = fir.zero_bits tuple<i32, !fir.array<8xi8>>
1515
! CHECK: %[[init:.*]] = fir.insert_value %[[undef]], %c42{{.*}}, [0 : index] : (tuple<i32, !fir.array<8xi8>>, i32) -> tuple<i32, !fir.array<8xi8>>
1616
! CHECK: fir.has_value %[[init]] : tuple<i32, !fir.array<8xi8>>

flang/test/Lower/common-block.f90

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
! RUN: %flang -emit-llvm -S -mmlir -disable-external-name-interop %s -o - | FileCheck %s
33

44
! CHECK: @__BLNK__ = common global [8 x i8] zeroinitializer
5+
! CHECK: @co1_ = common global [16 x i8] zeroinitializer, align 16
56
! CHECK: @rien_ = common global [1 x i8] zeroinitializer
67
! CHECK: @with_empty_equiv_ = common global [8 x i8] zeroinitializer
78
! CHECK: @x_ = global { float, float } { float 1.0{{.*}}, float 2.0{{.*}} }
@@ -72,3 +73,9 @@ subroutine s6
7273
common /with_empty_equiv/ x, r1, y
7374
equivalence(r1, r2)
7475
end subroutine s6
76+
77+
subroutine s7()
78+
real(16) r16
79+
common /co1/ r16
80+
end subroutine
81+

flang/test/Lower/module_definition.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ module modCommonNoInit1
1212
real :: x_named1
1313
common /named1/ x_named1
1414
end module
15-
! CHECK-LABEL: fir.global common @__BLNK__(dense<0> : vector<4xi8>) : !fir.array<4xi8>
16-
! CHECK-LABEL: fir.global common @named1_(dense<0> : vector<4xi8>) : !fir.array<4xi8>
15+
! CHECK-LABEL: fir.global common @__BLNK__(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>
16+
! CHECK-LABEL: fir.global common @named1_(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>
1717

1818
! Module defines variable in common block with initialization
1919
module modCommonInit1
2020
integer :: i_named2 = 42
2121
common /named2/ i_named2
2222
end module
23-
! CHECK-LABEL: fir.global @named2_ : tuple<i32> {
23+
! CHECK-LABEL: fir.global @named2_ {alignment = 4 : i64} : tuple<i32> {
2424
! CHECK: %[[init:.*]] = fir.insert_value %{{.*}}, %c42{{.*}}, [0 : index] : (tuple<i32>, i32) -> tuple<i32>
2525
! CHECK: fir.has_value %[[init]] : tuple<i32>
2626

flang/test/Lower/module_use.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
! The modules are defined in module_definition.f90
66
! The first runs ensures the module file is generated.
77

8-
! CHECK: fir.global common @__BLNK__(dense<0> : vector<4xi8>) : !fir.array<4xi8>
9-
! CHECK-NEXT: fir.global common @named1_(dense<0> : vector<4xi8>) : !fir.array<4xi8>
10-
! CHECK-NEXT: fir.global common @named2_(dense<0> : vector<4xi8>) : !fir.array<4xi8>
8+
! CHECK: fir.global common @__BLNK__(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>
9+
! CHECK-NEXT: fir.global common @named1_(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>
10+
! CHECK-NEXT: fir.global common @named2_(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>
1111

1212
! CHECK-LABEL: func @_QPm1use()
1313
real function m1use()

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
real, save, target :: b
1212
common /a/ p
1313
data p /b/
14-
! CHECK-LABEL: fir.global @a_ : tuple<!fir.box<!fir.ptr<f32>>>
14+
! CHECK-LABEL: fir.global @a_ {alignment = 8 : i64} : tuple<!fir.box<!fir.ptr<f32>>>
1515
! CHECK: %[[undef:.*]] = fir.zero_bits tuple<!fir.box<!fir.ptr<f32>>>
1616
! CHECK: %[[b:.*]] = fir.address_of(@_QEb) : !fir.ref<f32>
1717
! CHECK: %[[box:.*]] = fir.embox %[[b]] : (!fir.ref<f32>) -> !fir.box<f32>
@@ -29,9 +29,9 @@ block data tied
2929
real, pointer :: p2 => x1
3030
common /c1/ x1, p1
3131
common /c2/ x2, p2
32-
! CHECK-LABEL: fir.global @c1_ : tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>
32+
! CHECK-LABEL: fir.global @c1_ {alignment = 8 : i64} : tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>
3333
! CHECK: fir.address_of(@c2_) : !fir.ref<tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>>
34-
! CHECK-LABEL: fir.global @c2_ : tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>
34+
! CHECK-LABEL: fir.global @c2_ {alignment = 8 : i64} : tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>
3535
! CHECK: fir.address_of(@c1_) : !fir.ref<tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>>
3636
end block data
3737

@@ -40,7 +40,7 @@ block data bdsnake
4040
integer, target :: b = 42
4141
integer, pointer :: p => b
4242
common /snake/ p, b
43-
! CHECK-LABEL: fir.global @snake_ : tuple<!fir.box<!fir.ptr<i32>>, i32>
43+
! CHECK-LABEL: fir.global @snake_ {alignment = 8 : i64} : tuple<!fir.box<!fir.ptr<i32>>, i32>
4444
! CHECK: %[[tuple0:.*]] = fir.zero_bits tuple<!fir.box<!fir.ptr<i32>>, i32>
4545
! CHECK: %[[snakeAddr:.*]] = fir.address_of(@snake_) : !fir.ref<tuple<!fir.box<!fir.ptr<i32>>, i32>>
4646
! CHECK: %[[byteView:.*]] = fir.convert %[[snakeAddr:.*]] : (!fir.ref<tuple<!fir.box<!fir.ptr<i32>>, i32>>) -> !fir.ref<!fir.array<?xi8>>

0 commit comments

Comments
 (0)