[Mlir-commits] [mlir] af2dd15 - [MLIR][LLVMIR] Add support for empty global ctor/dtor lists (#128969)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Feb 28 10:46:22 PST 2025
Author: Bruno Cardoso Lopes
Date: 2025-02-28T10:46:17-08:00
New Revision: af2dd15a4b6b8e4f7d126f90e0dd4e9120a37503
URL: https://github.com/llvm/llvm-project/commit/af2dd15a4b6b8e4f7d126f90e0dd4e9120a37503
DIFF: https://github.com/llvm/llvm-project/commit/af2dd15a4b6b8e4f7d126f90e0dd4e9120a37503.diff
LOG: [MLIR][LLVMIR] Add support for empty global ctor/dtor lists (#128969)
LLVM IR emitted in from C++ may contain `@llvm.global_ctors = appending
global [0 x { i32, ptr, ptr }] zeroinitializer`. Before this PR, if we
try to roundtrip code like this from the importer, we'll end up with
nothing in place.
Note that `llvm::appendToGlobalCtors` ignores empty lists and this PR
uses the same approach as `llvm-as`, which doesn't use the utilities
from `llvm/lib/Transforms/Utils/ModuleUtils.cpp` in order to build this
- it calls into creating a global variable from scratch.
Added:
Modified:
mlir/lib/Target/LLVMIR/ModuleImport.cpp
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Dialect/LLVMIR/global.mlir
mlir/test/Target/LLVMIR/Import/global-variables.ll
mlir/test/Target/LLVMIR/llvmir.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 8445e609c2244..7ea82f61fadbb 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1071,11 +1071,21 @@ LogicalResult
ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
return failure();
- auto *initializer =
- dyn_cast<llvm::ConstantArray>(globalVar->getInitializer());
- if (!initializer)
+ llvm::Constant *initializer = globalVar->getInitializer();
+
+ bool knownInit = isa<llvm::ConstantArray>(initializer) ||
+ isa<llvm::ConstantAggregateZero>(initializer);
+ if (!knownInit)
return failure();
+ // ConstantAggregateZero does not engage with the operand initialization
+ // in the loop that follows - there should be no operands. This implies
+ // empty ctor/dtor lists.
+ if (auto *caz = dyn_cast<llvm::ConstantAggregateZero>(initializer)) {
+ if (caz->getElementCount().getFixedValue() != 0)
+ return failure();
+ }
+
SmallVector<Attribute> funcs;
SmallVector<int32_t> priorities;
for (llvm::Value *operand : initializer->operands()) {
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 5cd841ee2df91..eda6b51ff45ea 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1258,16 +1258,35 @@ LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
auto dtorOp = dyn_cast<GlobalDtorsOp>(op);
if (!ctorOp && !dtorOp)
continue;
- auto range = ctorOp ? llvm::zip(ctorOp.getCtors(), ctorOp.getPriorities())
- : llvm::zip(dtorOp.getDtors(), dtorOp.getPriorities());
- auto appendGlobalFn =
- ctorOp ? llvm::appendToGlobalCtors : llvm::appendToGlobalDtors;
- for (auto symbolAndPriority : range) {
- llvm::Function *f = lookupFunction(
- cast<FlatSymbolRefAttr>(std::get<0>(symbolAndPriority)).getValue());
- appendGlobalFn(*llvmModule, f,
- cast<IntegerAttr>(std::get<1>(symbolAndPriority)).getInt(),
- /*Data=*/nullptr);
+
+ // The empty / zero initialized version of llvm.global_(c|d)tors cannot be
+ // handled by appendGlobalFn logic below, which just ignores empty (c|d)tor
+ // lists. Make sure it gets emitted.
+ if ((ctorOp && ctorOp.getCtors().empty()) ||
+ (dtorOp && dtorOp.getDtors().empty())) {
+ llvm::IRBuilder<llvm::TargetFolder> builder(
+ llvmModule->getContext(),
+ llvm::TargetFolder(llvmModule->getDataLayout()));
+ llvm::Type *eltTy = llvm::StructType::get(
+ builder.getInt32Ty(), builder.getPtrTy(), builder.getPtrTy());
+ llvm::ArrayType *at = llvm::ArrayType::get(eltTy, 0);
+ llvm::Constant *zeroInit = llvm::Constant::getNullValue(at);
+ (void)new llvm::GlobalVariable(
+ *llvmModule, zeroInit->getType(), false,
+ llvm::GlobalValue::AppendingLinkage, zeroInit,
+ ctorOp ? "llvm.global_ctors" : "llvm.global_dtors");
+ } else {
+ auto range = ctorOp
+ ? llvm::zip(ctorOp.getCtors(), ctorOp.getPriorities())
+ : llvm::zip(dtorOp.getDtors(), dtorOp.getPriorities());
+ auto appendGlobalFn =
+ ctorOp ? llvm::appendToGlobalCtors : llvm::appendToGlobalDtors;
+ for (const auto &[sym, prio] : range) {
+ llvm::Function *f =
+ lookupFunction(cast<FlatSymbolRefAttr>(sym).getValue());
+ appendGlobalFn(*llvmModule, f, cast<IntegerAttr>(prio).getInt(),
+ /*Data=*/nullptr);
+ }
}
}
diff --git a/mlir/test/Dialect/LLVMIR/global.mlir b/mlir/test/Dialect/LLVMIR/global.mlir
index 79d1cafabfbed..bd3584de9a405 100644
--- a/mlir/test/Dialect/LLVMIR/global.mlir
+++ b/mlir/test/Dialect/LLVMIR/global.mlir
@@ -233,6 +233,14 @@ llvm.mlir.global_ctors { ctors = [@ctor], priorities = [0 : i32]}
// -----
+// CHECK: llvm.mlir.global_ctors {ctors = [], priorities = []}
+llvm.mlir.global_ctors {ctors = [], priorities = []}
+
+// CHECK: llvm.mlir.global_dtors {dtors = [], priorities = []}
+llvm.mlir.global_dtors {dtors = [], priorities = []}
+
+// -----
+
llvm.func @dtor() {
llvm.return
}
diff --git a/mlir/test/Target/LLVMIR/Import/global-variables.ll b/mlir/test/Target/LLVMIR/Import/global-variables.ll
index fbeda4cd42af8..b809c93d772f5 100644
--- a/mlir/test/Target/LLVMIR/Import/global-variables.ll
+++ b/mlir/test/Target/LLVMIR/Import/global-variables.ll
@@ -256,6 +256,14 @@ define void @bar() {
; // -----
+; CHECK: llvm.mlir.global_ctors {ctors = [], priorities = []}
+ at llvm.global_ctors = appending global [0 x { i32, ptr, ptr }] zeroinitializer
+
+; CHECK: llvm.mlir.global_dtors {dtors = [], priorities = []}
+ at llvm.global_dtors = appending global [0 x { i32, ptr, ptr }] zeroinitializer
+
+; // -----
+
; Visibility attribute.
; CHECK: llvm.mlir.global external hidden constant @hidden("string")
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 7f9a3ba79d724..db2e08742dbca 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -1859,6 +1859,14 @@ llvm.func @foo() {
// -----
+// CHECK: @llvm.global_ctors = appending global [0 x { i32, ptr, ptr }] zeroinitializer
+llvm.mlir.global_ctors {ctors = [], priorities = []}
+
+// CHECK: @llvm.global_dtors = appending global [0 x { i32, ptr, ptr }] zeroinitializer
+llvm.mlir.global_dtors {dtors = [], priorities = []}
+
+// -----
+
// CHECK: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @foo, ptr null }]
llvm.mlir.global_dtors { dtors = [@foo], priorities = [0 : i32]}
More information about the Mlir-commits
mailing list