[clang] [CIR] Fix dso_local and comdat handling for global vars (PR #142214)

Andy Kaylor via cfe-commits cfe-commits at lists.llvm.org
Fri May 30 14:14:01 PDT 2025


https://github.com/andykaylor created https://github.com/llvm/llvm-project/pull/142214

This change adds extra processing of global variable definitions to correctly set the dso_local and comdat attributes.

>From f23b194d46956bd0af34413fa4f4919ea610e643 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Fri, 23 May 2025 17:54:58 -0700
Subject: [PATCH] [CIR] Fix dso_local and comdat handling for global vars

This change adds extra processing of global variable definitions to
correctly set the dso_local and comdat attributes.
---
 clang/include/clang/CIR/MissingFeatures.h     |  8 +-
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        | 64 +++++++++++++---
 clang/lib/CIR/CodeGen/CIRGenModule.h          |  9 +++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 32 ++++++--
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   |  5 ++
 clang/test/CIR/CodeGen/dso-local.c            | 76 +++++++++++++++++++
 clang/test/CIR/CodeGen/namespace.cpp          |  2 +-
 clang/test/CIR/CodeGen/string-literals.c      | 12 +--
 clang/test/CIR/global-var-linkage.cpp         | 15 ++--
 9 files changed, 191 insertions(+), 32 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/dso-local.c

diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 11250be483edc..bc5b251074b94 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -34,17 +34,18 @@ struct MissingFeatures {
   static bool opGlobalThreadLocal() { return false; }
   static bool opGlobalConstant() { return false; }
   static bool opGlobalWeakRef() { return false; }
-  static bool opGlobalLinkage() { return false; }
   static bool opGlobalUnnamedAddr() { return false; }
   static bool opGlobalSection() { return false; }
   static bool opGlobalVisibility() { return false; }
   static bool opGlobalDLLImportExport() { return false; }
   static bool opGlobalPartition() { return false; }
+  static bool opGlobalUsedOrCompilerUsed() { return false; }
 
   static bool supportIFuncAttr() { return false; }
   static bool supportVisibility() { return false; }
   static bool hiddenVisibility() { return false; }
   static bool protectedVisibility() { return false; }
+  static bool defaultVisibility() { return false; }
 
   // Load/store attributes
   static bool opLoadStoreThreadLocal() { return false; }
@@ -77,6 +78,9 @@ struct MissingFeatures {
   static bool opFuncLinkage() { return false; }
   static bool opFuncVisibility() { return false; }
   static bool opFuncNoProto() { return false; }
+  static bool opFuncCPUAndFeaturesAttributes() { return false; }
+  static bool opFuncSection() { return false; }
+  static bool opFuncSetComdat() { return false; }
 
   // CallOp handling
   static bool opCallBuiltinFunc() { return false; }
@@ -137,7 +141,6 @@ struct MissingFeatures {
   // Misc
   static bool cxxABI() { return false; }
   static bool cirgenABIInfo() { return false; }
-  static bool cirgenTargetInfo() { return false; }
   static bool abiArgInfo() { return false; }
   static bool tryEmitAsConstant() { return false; }
   static bool constructABIArgDirectExtend() { return false; }
@@ -200,6 +203,7 @@ struct MissingFeatures {
   static bool cleanupsToDeactivate() { return false; }
   static bool stackBase() { return false; }
   static bool deferredDecls() { return false; }
+  static bool setTargetAttributes() { return false; }
 
   // Missing types
   static bool dataMemberType() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 11c3bd4d7be84..9da7fcc0f89d5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -317,6 +317,36 @@ cir::GlobalOp CIRGenModule::createGlobalOp(CIRGenModule &cgm,
   return g;
 }
 
+void CIRGenModule::setCommonAttributes(GlobalDecl gd, mlir::Operation *gv) {
+  const Decl *d = gd.getDecl();
+  if (isa_and_nonnull<NamedDecl>(d))
+    setGVProperties(gv, dyn_cast<NamedDecl>(d));
+  assert(!cir::MissingFeatures::defaultVisibility());
+  assert(!cir::MissingFeatures::opGlobalUsedOrCompilerUsed());
+}
+
+void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
+  setCommonAttributes(gd, op);
+
+  assert(!cir::MissingFeatures::opGlobalUsedOrCompilerUsed());
+  assert(!cir::MissingFeatures::opGlobalSection());
+  assert(!cir::MissingFeatures::opFuncCPUAndFeaturesAttributes());
+  assert(!cir::MissingFeatures::opFuncSection());
+
+  assert(!cir::MissingFeatures::setTargetAttributes());
+}
+
+static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd) {
+  // Set linkage and visibility in case we never see a definition.
+  LinkageInfo lv = nd->getLinkageAndVisibility();
+  // Don't set internal linkage on declarations.
+  // "extern_weak" is overloaded in LLVM; we probably should have
+  // separate linkage types for this.
+  if (isExternallyVisible(lv.getLinkage()) &&
+      (nd->hasAttr<WeakAttr>() || nd->isWeakImported()))
+    gv.setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
+}
+
 /// If the specified mangled name is not in the module,
 /// create and return an mlir GlobalOp with the specified type (TODO(cir):
 /// address space).
@@ -387,7 +417,8 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
 
     gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
     assert(!cir::MissingFeatures::opGlobalConstant());
-    assert(!cir::MissingFeatures::opGlobalLinkage());
+
+    setLinkageForGV(gv, d);
 
     if (d->getTLSKind())
       errorNYI(d->getSourceRange(), "thread local global variable");
@@ -555,8 +586,6 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
     errorNYI(vd->getSourceRange(), "annotate global variable");
   }
 
-  assert(!cir::MissingFeatures::opGlobalLinkage());
-
   if (langOpts.CUDA) {
     errorNYI(vd->getSourceRange(), "CUDA global variable");
   }
@@ -577,6 +606,12 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
   assert(!cir::MissingFeatures::opGlobalDLLImportExport());
   if (linkage == cir::GlobalLinkageKind::CommonLinkage)
     errorNYI(initExpr->getSourceRange(), "common linkage");
+
+  setNonAliasAttributes(vd, gv);
+
+  assert(!cir::MissingFeatures::opGlobalThreadLocal());
+
+  maybeSetTrivialComdat(*vd, gv);
 }
 
 void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd,
@@ -668,6 +703,15 @@ static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d) {
   llvm_unreachable("No such linkage");
 }
 
+void CIRGenModule::maybeSetTrivialComdat(const Decl &d, mlir::Operation *op) {
+  if (!shouldBeInCOMDAT(*this, d))
+    return;
+  if (auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op))
+    globalOp.setComdat(true);
+
+  assert(!cir::MissingFeatures::opFuncSetComdat());
+}
+
 // TODO(CIR): this could be a common method between LLVM codegen.
 static bool isVarDeclStrongDefinition(const ASTContext &astContext,
                                       CIRGenModule &cgm, const VarDecl *vd,
@@ -830,10 +874,10 @@ CIRGenModule::getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant) {
   return getCIRLinkageForDeclarator(vd, linkage, isConstant);
 }
 
-static cir::GlobalOp generateStringLiteral(mlir::Location loc,
-                                           mlir::TypedAttr c, CIRGenModule &cgm,
-                                           StringRef globalName,
-                                           CharUnits alignment) {
+static cir::GlobalOp
+generateStringLiteral(mlir::Location loc, mlir::TypedAttr c,
+                      cir::GlobalLinkageKind lt, CIRGenModule &cgm,
+                      StringRef globalName, CharUnits alignment) {
   assert(!cir::MissingFeatures::addressSpace());
 
   // Create a global variable for this string
@@ -843,7 +887,8 @@ static cir::GlobalOp generateStringLiteral(mlir::Location loc,
 
   // Set up extra information and add to the module
   gv.setAlignmentAttr(cgm.getSize(alignment));
-  assert(!cir::MissingFeatures::opGlobalLinkage());
+  gv.setLinkageAttr(
+      cir::GlobalLinkageKindAttr::get(cgm.getBuilder().getContext(), lt));
   assert(!cir::MissingFeatures::opGlobalThreadLocal());
   assert(!cir::MissingFeatures::opGlobalUnnamedAddr());
   CIRGenModule::setInitializer(gv, c);
@@ -907,7 +952,8 @@ cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
   mlir::Location loc = getLoc(s->getSourceRange());
   auto typedC = llvm::cast<mlir::TypedAttr>(c);
   cir::GlobalOp gv =
-      generateStringLiteral(loc, typedC, *this, uniqueName, alignment);
+      generateStringLiteral(loc, typedC, cir::GlobalLinkageKind::PrivateLinkage,
+                            *this, uniqueName, alignment);
   setDSOLocal(static_cast<mlir::Operation *>(gv));
 
   assert(!cir::MissingFeatures::sanitizers());
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index 697c2450ec38b..234c5f1710176 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -149,6 +149,12 @@ class CIRGenModule : public CIRGenTypeCache {
   cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s,
                                           llvm::StringRef name = ".str");
 
+  /// Set attributes which are common to any form of a global definition (alias,
+  /// Objective-C method, function, global variable).
+  ///
+  /// NOTE: This should only be called for definitions.
+  void setCommonAttributes(GlobalDecl gd, mlir::Operation *op);
+
   const TargetCIRGenInfo &getTargetCIRGenInfo();
 
   /// Helpers to convert the presumed location of Clang's SourceLocation to an
@@ -209,6 +215,7 @@ class CIRGenModule : public CIRGenTypeCache {
   void emitTentativeDefinition(const VarDecl *d);
 
   bool supportsCOMDAT() const;
+  void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op);
 
   static void setInitializer(cir::GlobalOp &op, mlir::Attribute value);
 
@@ -285,6 +292,8 @@ class CIRGenModule : public CIRGenTypeCache {
   // An ordered map of canonical GlobalDecls to their mangled names.
   llvm::MapVector<clang::GlobalDecl, llvm::StringRef> mangledDeclNames;
   llvm::StringMap<clang::GlobalDecl, llvm::BumpPtrAllocator> manglings;
+
+  void setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op);
 };
 } // namespace CIRGen
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index b07e61638c3b4..73732a81c039b 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -969,13 +969,13 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
   const uint64_t alignment = op.getAlignment().value_or(0);
   const mlir::LLVM::Linkage linkage = convertLinkage(op.getLinkage());
   const StringRef symbol = op.getSymName();
+  mlir::SymbolRefAttr comdatAttr = getComdatAttr(op, rewriter);
 
   SmallVector<mlir::NamedAttribute> attributes;
   mlir::LLVM::GlobalOp newGlobalOp =
       rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
           op, llvmType, isConst, linkage, symbol, nullptr, alignment, addrSpace,
-          isDsoLocal, isThreadLocal,
-          /*comdat=*/mlir::SymbolRefAttr(), attributes);
+          isDsoLocal, isThreadLocal, comdatAttr, attributes);
   newGlobalOp.getRegion().emplaceBlock();
   rewriter.setInsertionPointToEnd(newGlobalOp.getInitializerBlock());
 }
@@ -1024,6 +1024,7 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
   const mlir::LLVM::Linkage linkage = convertLinkage(op.getLinkage());
   const StringRef symbol = op.getSymName();
   SmallVector<mlir::NamedAttribute> attributes;
+  mlir::SymbolRefAttr comdatAttr = getComdatAttr(op, rewriter);
 
   if (init.has_value()) {
     if (mlir::isa<cir::FPAttr, cir::IntAttr, cir::BoolAttr>(init.value())) {
@@ -1054,12 +1055,33 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
   // Rewrite op.
   rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
       op, llvmType, isConst, linkage, symbol, init.value_or(mlir::Attribute()),
-      alignment, addrSpace, isDsoLocal, isThreadLocal,
-      /*comdat=*/mlir::SymbolRefAttr(), attributes);
-
+      alignment, addrSpace, isDsoLocal, isThreadLocal, comdatAttr, attributes);
   return mlir::success();
 }
 
+mlir::SymbolRefAttr
+CIRToLLVMGlobalOpLowering::getComdatAttr(cir::GlobalOp &op,
+                                         mlir::OpBuilder &builder) const {
+  if (!op.getComdat())
+    return mlir::SymbolRefAttr{};
+
+  mlir::ModuleOp module = op->getParentOfType<mlir::ModuleOp>();
+  mlir::OpBuilder::InsertionGuard guard(builder);
+  StringRef comdatName("__llvm_comdat_globals");
+  if (!comdatOp) {
+    builder.setInsertionPointToStart(module.getBody());
+    comdatOp =
+        builder.create<mlir::LLVM::ComdatOp>(module.getLoc(), comdatName);
+  }
+
+  builder.setInsertionPointToStart(&comdatOp.getBody().back());
+  auto selectorOp = builder.create<mlir::LLVM::ComdatSelectorOp>(
+      comdatOp.getLoc(), op.getSymName(), mlir::LLVM::comdat::Comdat::Any);
+  return mlir::SymbolRefAttr::get(
+      builder.getContext(), comdatName,
+      mlir::FlatSymbolRefAttr::get(selectorOp.getSymNameAttr()));
+}
+
 mlir::LogicalResult CIRToLLVMSwitchFlatOpLowering::matchAndRewrite(
     cir::SwitchFlatOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
index 6b8862db2c8be..de043dfba77b5 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
@@ -13,6 +13,7 @@
 #define CLANG_CIR_LOWERTOLLVM_H
 
 #include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 #include "mlir/Transforms/DialectConversion.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 
@@ -192,6 +193,10 @@ class CIRToLLVMGlobalOpLowering
 
   void setupRegionInitializedLLVMGlobalOp(
       cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const;
+
+  mutable mlir::LLVM::ComdatOp comdatOp = nullptr;
+  mlir::SymbolRefAttr getComdatAttr(cir::GlobalOp &op,
+                                    mlir::OpBuilder &builder) const;
 };
 
 class CIRToLLVMUnaryOpLowering
diff --git a/clang/test/CIR/CodeGen/dso-local.c b/clang/test/CIR/CodeGen/dso-local.c
new file mode 100644
index 0000000000000..07c833d2fbc94
--- /dev/null
+++ b/clang/test/CIR/CodeGen/dso-local.c
@@ -0,0 +1,76 @@
+// This test is copied from clang/test/CodeGen/dso-local-executable.c with
+// unsupported targets, thread_local variables, and function checks removed.
+
+// These are here so we find this test when grepping for missing features.
+// cir::MissingFeatures::opGlobalThreadLocal()
+// cir::MissingFeatures::opFuncDsoLocal()
+
+/// Static relocation model defaults to -fdirect-access-external-data and sets
+/// dso_local on most global objects.
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -mrelocation-model static %s -o - | FileCheck --check-prefix=STATIC %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -mrelocation-model static -fdirect-access-external-data %s -o - | FileCheck --check-prefix=STATIC %s
+// STATIC:      @baz = dso_local global i32 42
+// STATIC-NEXT: @import_var = external dso_local global i32
+// STATIC-NEXT: @weak_bar = extern_weak dso_local global i32
+// STATIC-NEXT: @bar = external dso_local global i32
+
+/// If -fno-direct-access-external-data is set, drop dso_local from global variable
+/// declarations.
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -mrelocation-model static -fno-direct-access-external-data  %s -o - | FileCheck --check-prefix=STATIC-INDIRECT %s
+// STATIC-INDIRECT:      @baz = dso_local global i32 42
+// STATIC-INDIRECT-NEXT: @import_var = external global i32
+// STATIC-INDIRECT-NEXT: @weak_bar = extern_weak global i32
+// STATIC-INDIRECT-NEXT: @bar = external global i32
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -pic-level 1 -pic-is-pie %s -o - | FileCheck --check-prefix=PIE %s
+// PIE:      @baz = dso_local global i32 42
+// PIE-NEXT: @import_var = external global i32
+// PIE-NEXT: @weak_bar = extern_weak global i32
+// PIE-NEXT: @bar = external global i32
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -pic-level 1 -pic-is-pie -fdirect-access-external-data %s -o - | FileCheck --check-prefix=PIE-DIRECT %s
+// PIE-DIRECT:      @baz = dso_local global i32 42
+// PIE-DIRECT-NEXT: @import_var = external dso_local global i32
+// PIE-DIRECT-NEXT: @weak_bar = extern_weak global i32
+// PIE-DIRECT-NEXT: @bar = external dso_local global i32
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -mrelocation-model static -fno-plt %s -o - | FileCheck --check-prefix=NOPLT %s
+// NOPLT:      @baz = dso_local global i32 42
+// NOPLT-NEXT: @import_var = external dso_local global i32
+// NOPLT-NEXT: @weak_bar = extern_weak dso_local global i32
+// NOPLT-NEXT: @bar = external dso_local global i32
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -fno-plt -pic-level 1 -pic-is-pie -fdirect-access-external-data %s -o - | FileCheck --check-prefix=PIE-DIRECT-NOPLT %s
+// PIE-DIRECT-NOPLT:      @baz = dso_local global i32 42
+// PIE-DIRECT-NOPLT-NEXT: @import_var = external dso_local global i32
+// PIE-DIRECT-NOPLT-NEXT: @weak_bar = extern_weak global i32
+// PIE-DIRECT-NOPLT-NEXT: @bar = external dso_local global i32
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -pic-level 1 -pic-is-pie -fno-plt %s -o - | FileCheck --check-prefix=PIE-NO-PLT %s
+// RUN: %clang_cc1 -triple powerpc64le -fclangir -emit-llvm -mrelocation-model static %s -o - | FileCheck --check-prefix=PIE-NO-PLT %s
+// PIE-NO-PLT:      @baz = dso_local global i32 42
+// PIE-NO-PLT-NEXT: @import_var = external global i32
+// PIE-NO-PLT-NEXT: @weak_bar = extern_weak global i32
+// PIE-NO-PLT-NEXT: @bar = external global i32
+
+/// -fdirect-access-external-data is currently ignored for -fPIC.
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -pic-level 2 %s -o - | FileCheck --check-prefix=SHARED %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -pic-level 2 -fdirect-access-external-data %s -o - | FileCheck --check-prefix=SHARED %s
+// SHARED-DAG: @bar = external global i32
+// SHARED-DAG: @weak_bar = extern_weak global i32
+// SHARED-DAG: @baz ={{.*}} global i32 42
+
+int baz = 42;
+__attribute__((dllimport)) extern int import_var;
+__attribute__((weak)) extern int weak_bar;
+extern int bar;
+
+int *use_import(void) {
+  return &import_var;
+}
+
+int *zed(void) {
+  if (baz)
+    return &weak_bar;
+  return &bar;
+}
diff --git a/clang/test/CIR/CodeGen/namespace.cpp b/clang/test/CIR/CodeGen/namespace.cpp
index e0cf6333c1197..caa43f960c6c2 100644
--- a/clang/test/CIR/CodeGen/namespace.cpp
+++ b/clang/test/CIR/CodeGen/namespace.cpp
@@ -20,7 +20,7 @@ namespace test {
   }
 }
 
-// CHECK-DAG: cir.global "private" internal @_ZN12_GLOBAL__N_12g1E = #cir.int<1> : !s32i
+// CHECK-DAG: cir.global "private" internal dsolocal @_ZN12_GLOBAL__N_12g1E = #cir.int<1> : !s32i
 // CHECK-DAG: cir.global external @_ZN4test2g2E = #cir.int<2> : !s32i
 // CHECK-DAG: cir.global external @_ZN4test5test22g3E = #cir.int<3> : !s32i
 // CHECK-DAG: cir.func @_ZN12_GLOBAL__N_12f1Ev()
diff --git a/clang/test/CIR/CodeGen/string-literals.c b/clang/test/CIR/CodeGen/string-literals.c
index 549fdcb74f48a..00f59b09400c8 100644
--- a/clang/test/CIR/CodeGen/string-literals.c
+++ b/clang/test/CIR/CodeGen/string-literals.c
@@ -5,13 +5,13 @@
 // RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-llvm %s -o %t.ll
 // RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
 
-// CIR: cir.global "private" external @[[STR1_GLOBAL:.*]] = #cir.const_array<"1\00" : !cir.array<!s8i x 2>> : !cir.array<!s8i x 2>
-// CIR: cir.global "private" external @[[STR2_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 1>
-// CIR: cir.global "private" external @[[STR3_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 2>
+// CIR: cir.global "private" cir_private dsolocal @[[STR1_GLOBAL:.*]] = #cir.const_array<"1\00" : !cir.array<!s8i x 2>> : !cir.array<!s8i x 2>
+// CIR: cir.global "private" cir_private dsolocal @[[STR2_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 1>
+// CIR: cir.global "private" cir_private dsolocal @[[STR3_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 2>
 
-// LLVM: @[[STR1_GLOBAL:.*]] = global [2 x i8] c"1\00"
-// LLVM: @[[STR2_GLOBAL:.*]] = global [1 x i8] zeroinitializer
-// LLVM: @[[STR3_GLOBAL:.*]] = global [2 x i8] zeroinitializer
+// LLVM: @[[STR1_GLOBAL:.*]] = private global [2 x i8] c"1\00"
+// LLVM: @[[STR2_GLOBAL:.*]] = private global [1 x i8] zeroinitializer
+// LLVM: @[[STR3_GLOBAL:.*]] = private global [2 x i8] zeroinitializer
 
 // OGCG: @[[STR1_GLOBAL:.*]] = private unnamed_addr constant [2 x i8] c"1\00"
 // OGCG: @[[STR2_GLOBAL:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer
diff --git a/clang/test/CIR/global-var-linkage.cpp b/clang/test/CIR/global-var-linkage.cpp
index 1c0c1b121427f..3a288b8990ad7 100644
--- a/clang/test/CIR/global-var-linkage.cpp
+++ b/clang/test/CIR/global-var-linkage.cpp
@@ -12,22 +12,19 @@ int aaaa;
 // OGCG: @aaaa = global i32 0
 
 [[gnu::selectany]] int dddd;
-// CIR: cir.global weak_odr @dddd
-// LLVM: @dddd = weak_odr global i32 0
-// This actually should be here, but we aren't emitting it yet so I want the
-// test to reflect that.
-// LLVM-NOT: comdat
+// CIR: cir.global weak_odr comdat @dddd
+// LLVM: @dddd = weak_odr global i32 0, comdat
 // OGCG: @dddd = weak_odr global i32 0, comdat
 
 static int bbbb;
-// CIR: cir.global "private" internal @_ZL4bbbb
+// CIR: cir.global "private" internal dsolocal @_ZL4bbbb
 // LLVM: @_ZL4bbbb = internal global i32 0
 // OGCG: @_ZL4bbbb = internal global i32 0
 
 inline int cccc;
-// CIR: cir.global linkonce_odr @cccc
-// LLVM: @cccc = linkonce_odr global i32 0
-// OGCG: @cccc = linkonce_odr global i32 0
+// CIR: cir.global linkonce_odr comdat @cccc
+// LLVM: @cccc = linkonce_odr global i32 0, comdat
+// OGCG: @cccc = linkonce_odr global i32 0, comdat
 
 // Force the global variables to be emitted
 void reference_vars() {



More information about the cfe-commits mailing list