[Mlir-commits] [mlir] [MLIR][LLVMIR] Add support for empty global ctor/dtor lists (PR #128969)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Feb 26 15:48:02 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-llvm

Author: Bruno Cardoso Lopes (bcardosolopes)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/128969.diff


5 Files Affected:

- (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+24-17) 
- (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+31-10) 
- (modified) mlir/test/Dialect/LLVMIR/global.mlir (+8) 
- (modified) mlir/test/Target/LLVMIR/Import/global-variables.ll (+8) 
- (modified) mlir/test/Target/LLVMIR/llvmir.mlir (+8) 


``````````diff
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 8445e609c2244..edaacb883f0c2 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1071,32 +1071,39 @@ 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();
 
   SmallVector<Attribute> funcs;
   SmallVector<int32_t> priorities;
-  for (llvm::Value *operand : initializer->operands()) {
-    auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
-    if (!aggregate || aggregate->getNumOperands() != 3)
-      return failure();
+  if (auto caInit = dyn_cast<llvm::ConstantArray>(initializer)) {
+    for (llvm::Value *operand : initializer->operands()) {
+      auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
+      if (!aggregate || aggregate->getNumOperands() != 3)
+        return failure();
 
-    auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
-    auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
-    auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
-    if (!priority || !func || !data)
-      return failure();
+      auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
+      auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
+      auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
+      if (!priority || !func || !data)
+        return failure();
 
-    // GlobalCtorsOps and GlobalDtorsOps do not support non-null data fields.
-    if (!data->isNullValue())
-      return failure();
+      // GlobalCtorsOps and GlobalDtorsOps do not support non-null data fields.
+      if (!data->isNullValue())
+        return failure();
 
-    funcs.push_back(FlatSymbolRefAttr::get(context, func->getName()));
-    priorities.push_back(priority->getValue().getZExtValue());
+      funcs.push_back(FlatSymbolRefAttr::get(context, func->getName()));
+      priorities.push_back(priority->getValue().getZExtValue());
+    }
   }
 
+  // Note: no action needed for ConstantAggregateZero, which implies empty
+  // ctor/dtor lists.
+
   // Insert the global after the last one or at the start of the module.
   OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
 
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 5cd841ee2df91..c6bfb9566a4e1 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1258,16 +1258,37 @@ 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 (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);
+      }
     }
   }
 
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]}
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/128969


More information about the Mlir-commits mailing list