Author: Erich Keane
Date: 2026-05-29T09:56:29-07:00
New Revision: df697a65e67300c72851dddb31f7e1b5e869c931

URL: 
https://github.com/llvm/llvm-project/commit/df697a65e67300c72851dddb31f7e1b5e869c931
DIFF: 
https://github.com/llvm/llvm-project/commit/df697a65e67300c72851dddb31f7e1b5e869c931.diff

LOG: [CIR] Set the linkage properly for the _GLOBAL__SUB_I_ function (#200443)

These are required to have internal linkage, however we were generating
them with external linkage. This causes problems with linking together
files with the same name for one reason or another.

This patch does NOT change the module initializer linkage, which based
on all uses I could find, should remain external linkage.

Added: 
    

Modified: 
    clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
    clang/test/CIR/CodeGen/global-array-dtor.cpp
    clang/test/CIR/CodeGen/global-init.cpp
    clang/test/CIR/CodeGen/static-members.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp 
b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
index fa970158058e0..1f0bf563b1856 100644
--- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
@@ -1832,6 +1832,7 @@ void LoweringPreparePass::buildCXXGlobalInitFunc() {
   assert(!cir::MissingFeatures::opGlobalCtorPriority());
 
   SmallString<256> fnName;
+  cir::GlobalLinkageKind linkage;
   // Include the filename in the symbol name. Including "sub_" matches gcc
   // and makes sure these symbols appear lexicographically behind the symbols
   // with priority (TBD).  Module implementation units behave the same
@@ -1844,17 +1845,18 @@ void LoweringPreparePass::buildCXXGlobalInitFunc() {
         astCtx->createMangleContext());
     cast<clang::ItaniumMangleContext>(*mangleCtx)
         .mangleModuleInitializer(astCtx->getCurrentNamedModule(), out);
+    linkage = cir::GlobalLinkageKind::ExternalLinkage;
   } else {
     fnName += "_GLOBAL__sub_I_";
     fnName += getTransformedFileName(mlirModule);
+    linkage = cir::GlobalLinkageKind::InternalLinkage;
   }
 
   CIRBaseBuilderTy builder(getContext());
   builder.setInsertionPointToEnd(&mlirModule.getBodyRegion().back());
   auto fnType = cir::FuncType::get({}, builder.getVoidTy());
-  cir::FuncOp f =
-      buildRuntimeFunction(builder, fnName, mlirModule.getLoc(), fnType,
-                           cir::GlobalLinkageKind::ExternalLinkage);
+  cir::FuncOp f = buildRuntimeFunction(builder, fnName, mlirModule.getLoc(),
+                                       fnType, linkage);
   builder.setInsertionPointToStart(f.addEntryBlock());
   for (cir::FuncOp &f : dynamicInitializers)
     builder.createCallOp(f.getLoc(), f, {});

diff  --git a/clang/test/CIR/CodeGen/global-array-dtor.cpp 
b/clang/test/CIR/CodeGen/global-array-dtor.cpp
index ef2a313546fcd..4714fc9d4e365 100644
--- a/clang/test/CIR/CodeGen/global-array-dtor.cpp
+++ b/clang/test/CIR/CodeGen/global-array-dtor.cpp
@@ -102,10 +102,10 @@ ArrayDtor arrDtor[16];
 
 // Common init function for all globals with default priority
 
-// CIR: cir.func private @_GLOBAL__sub_I_[[FILENAME:.*]]() {
+// CIR: cir.func internal private @_GLOBAL__sub_I_[[FILENAME:.*]]() {
 // CIR:   cir.call @__cxx_global_var_init() : () -> ()
 
-// LLVM: define void @_GLOBAL__sub_I_[[FILENAME:.*]]()
+// LLVM: define internal void @_GLOBAL__sub_I_[[FILENAME:.*]]()
 // LLVM:   call void @__cxx_global_var_init()
 
 // OGCG: define internal void @_GLOBAL__sub_I_[[FILENAME:.*]]() {{.*}} section 
".text.startup" {

diff  --git a/clang/test/CIR/CodeGen/global-init.cpp 
b/clang/test/CIR/CodeGen/global-init.cpp
index 47cad1bd724dd..a9f4e75732562 100644
--- a/clang/test/CIR/CodeGen/global-init.cpp
+++ b/clang/test/CIR/CodeGen/global-init.cpp
@@ -263,7 +263,7 @@ ArrayDtor arrDtor[16];
 
 // Common init function for all globals with default priority
 
-// CIR: cir.func private @_GLOBAL__sub_I_[[FILENAME:.*]]() {
+// CIR: cir.func internal private @_GLOBAL__sub_I_[[FILENAME:.*]]() {
 // CIR:   cir.call @__cxx_global_var_init() : () -> ()
 // CIR:   cir.call @__cxx_global_var_init.1() : () -> ()
 // CIR:   cir.call @__cxx_global_var_init.2() : () -> ()
@@ -271,7 +271,7 @@ ArrayDtor arrDtor[16];
 // CIR:   cir.call @__cxx_global_var_init.4() : () -> ()
 // CIR:   cir.call @__cxx_global_var_init.5() : () -> ()
 
-// LLVM: define void @_GLOBAL__sub_I_[[FILENAME]]()
+// LLVM: define internal void @_GLOBAL__sub_I_[[FILENAME]]()
 // LLVM:   call void @__cxx_global_var_init()
 // LLVM:   call void @__cxx_global_var_init.1()
 // LLVM:   call void @__cxx_global_var_init.2()

diff  --git a/clang/test/CIR/CodeGen/static-members.cpp 
b/clang/test/CIR/CodeGen/static-members.cpp
index 8722dc2a2bc6f..40e4201946094 100644
--- a/clang/test/CIR/CodeGen/static-members.cpp
+++ b/clang/test/CIR/CodeGen/static-members.cpp
@@ -87,8 +87,12 @@ struct Outer {
 // OGCG: [[INIT_END]]:
 
 
-// CIR: cir.func private @_GLOBAL__sub_I_static_members.cpp()
+// CIR: cir.func internal private @_GLOBAL__sub_I_static_members.cpp()
 // CIR:   cir.call @__cxx_global_var_init()
 
-// LLVM: define void @_GLOBAL__sub_I_static_members.cpp()
+// LLVM: define internal void @_GLOBAL__sub_I_static_members.cpp()
 // LLVM:   call void @__cxx_global_var_init()
+
+// Note: OGCG doesn't actually generate this function, and just adds these to
+// the `llvm.global_ctors` instead. It isn't clear whether that is meaningful
+// or important.


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to