[flang-commits] [flang] [flang] Set common linkage to common block with zero initializer (PR #179548)
Valentin Clement バレンタイン クレメン via flang-commits
flang-commits at lists.llvm.org
Tue Feb 3 12:59:52 PST 2026
https://github.com/clementval created https://github.com/llvm/llvm-project/pull/179548
Currently, we do not set a linkage for common block with an init region. With some linker this is problematic because we can have multiple global for the common block with different linkage and the linker will complain about multiple definition.
```
MODULE M
INTEGER*4 CODE(100)
COMMON/COM/CODE
DATA CODE/100*0/
END MODULE
```
```
SUBROUTINE SUB1(CODE)
IMPLICIT NONE
INTEGER*4 CODE
INTEGER*4 CODE(100)
COMMON/COM/CODE
END SUBROUTINE
```
This patch detect zero initializer region and set the linkage to common when it was not set.
>From e850c7f09867ba2cb93959b82f99fd6fbe2bd938 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Tue, 3 Feb 2026 12:12:49 -0800
Subject: [PATCH] [flang] Set common linkage to common block with zero
initializer
---
flang/lib/Optimizer/CodeGen/CodeGen.cpp | 8 ++++++++
flang/test/Fir/common-block-zero-init.fir | 12 ++++++++++++
2 files changed, 20 insertions(+)
create mode 100644 flang/test/Fir/common-block-zero-init.fir
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 625701725003f..619ff61b7927b 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -3323,7 +3323,10 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {
// Replace insert_on_range with a constant dense attribute if the
// initialization is on the full range.
auto insertOnRangeOps = gr.front().getOps<fir::InsertOnRangeOp>();
+ unsigned nbZeroInitializers = 0;
+ unsigned nbRanges = 0;
for (auto insertOp : insertOnRangeOps) {
+ ++nbRanges;
if (insertOp.isFullRange()) {
auto seqTyAttr = convertType(insertOp.getType());
auto *op = insertOp.getVal().getDefiningOp();
@@ -3342,8 +3345,13 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {
rewriter.setInsertionPointAfter(insertOp);
rewriter.replaceOpWithNewOp<mlir::arith::ConstantOp>(
insertOp, seqTyAttr, denseAttr);
+ if (auto intAttr = mlir::dyn_cast<mlir::IntegerAttr>(constant.getValue()))
+ if (intAttr.getInt() == 0)
+ ++nbZeroInitializers;
}
}
+ if (nbRanges > 0 && nbRanges == nbZeroInitializers && linkage == mlir::LLVM::Linkage::External)
+ g.setLinkage(mlir::LLVM::Linkage::Common);
}
if (global.getDataAttr() &&
diff --git a/flang/test/Fir/common-block-zero-init.fir b/flang/test/Fir/common-block-zero-init.fir
new file mode 100644
index 0000000000000..cb24d9b430054
--- /dev/null
+++ b/flang/test/Fir/common-block-zero-init.fir
@@ -0,0 +1,12 @@
+ // RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
+
+ fir.global @cdb_com_ {acc.declare = #acc.declare<dataClause = acc_create>, alignment = 4 : i64} : tuple<!fir.array<100xi32>> {
+ %c0_i32 = arith.constant 0 : i32
+ %0 = fir.zero_bits tuple<!fir.array<100xi32>>
+ %1 = fir.undefined !fir.array<100xi32>
+ %2 = fir.insert_on_range %1, %c0_i32 from (0) to (99) : (!fir.array<100xi32>, i32) -> !fir.array<100xi32>
+ %3 = fir.insert_value %0, %2, [0 : index] : (tuple<!fir.array<100xi32>>, !fir.array<100xi32>) -> tuple<!fir.array<100xi32>>
+ fir.has_value %3 : tuple<!fir.array<100xi32>>
+ }
+
+// CHECK-LABEL: @cdb_com_ = common global { [100 x i32] } zeroinitializer
More information about the flang-commits
mailing list