[clang] [CIR] Add support for global linkage and visibility (PR #141973)
Andy Kaylor via cfe-commits
cfe-commits at lists.llvm.org
Thu May 29 09:17:37 PDT 2025
https://github.com/andykaylor created https://github.com/llvm/llvm-project/pull/141973
This change adds support for the CIRGlobalValueInterface and attributes for visibility and comdat to GlobalOp.
The comdat attribute isn't correctly calculated yet, but it was required for the CIRGlobalValueInterface interface. There are also some cases where dso_local isn't set correctly, but it is better than it was before this change. Those issues will be addressed in a future patch.
>From 70aa8d668cf610eb7d2486b60112591a19d3db89 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Fri, 23 May 2025 11:03:05 -0700
Subject: [PATCH] [CIR] Add support for global linkage and visibility
This change adds support for the CIRGlobalValueInterface and attributes
for visibility and comdat to GlobalOp.
---
clang/include/clang/CIR/Dialect/IR/CIRAttrs.h | 1 +
.../include/clang/CIR/Dialect/IR/CIRAttrs.td | 43 ++++
clang/include/clang/CIR/Dialect/IR/CIROps.td | 17 +-
.../clang/CIR/Dialect/IR/CMakeLists.txt | 4 +-
clang/include/clang/CIR/MissingFeatures.h | 6 +-
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 218 ++++++++++++++++--
clang/lib/CIR/CodeGen/CIRGenModule.h | 25 +-
clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 3 +
clang/lib/CIR/Interfaces/CIROpInterfaces.cpp | 17 +-
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 6 +-
clang/test/CIR/CodeGen/array.cpp | 24 +-
clang/test/CIR/CodeGen/namespace.cpp | 2 +-
clang/test/CIR/CodeGen/string-literals.c | 12 +-
clang/test/CIR/CodeGen/struct.c | 22 +-
clang/test/CIR/CodeGen/struct.cpp | 4 +-
clang/test/CIR/CodeGen/union.c | 2 +-
clang/test/CIR/CodeGen/vector-ext.cpp | 10 +-
clang/test/CIR/CodeGen/vector.cpp | 8 +-
clang/test/CIR/IR/array.cir | 16 +-
clang/test/CIR/IR/global-var-linkage.cir | 16 +-
clang/test/CIR/IR/global.cir | 108 ++++-----
clang/test/CIR/Lowering/array.cpp | 18 +-
clang/test/CIR/Lowering/global-var-simple.cpp | 66 +++---
clang/test/CIR/Lowering/hello.c | 7 +-
clang/test/CIR/global-var-linkage.cpp | 14 +-
clang/test/CIR/global-var-simple.cpp | 2 +-
26 files changed, 477 insertions(+), 194 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
index 1451ea47c50c8..64556bcb92baa 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H
#define LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H
+#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "mlir/IR/Attributes.h"
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 8152535930095..bddd7a825c505 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -276,4 +276,47 @@ def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> {
}];
}
+//===----------------------------------------------------------------------===//
+// VisibilityAttr
+//===----------------------------------------------------------------------===//
+
+def VK_Default : I32EnumAttrCase<"Default", 1, "default">;
+def VK_Hidden : I32EnumAttrCase<"Hidden", 2, "hidden">;
+def VK_Protected : I32EnumAttrCase<"Protected", 3, "protected">;
+
+def VisibilityKind : I32EnumAttr<"VisibilityKind", "C/C++ visibility", [
+ VK_Default, VK_Hidden, VK_Protected
+]> {
+ let cppNamespace = "::cir";
+}
+
+def VisibilityAttr : CIR_Attr<"Visibility", "visibility"> {
+ let summary = "Visibility attribute";
+ let description = [{
+ Visibility attributes.
+ }];
+ let parameters = (ins "VisibilityKind":$value);
+
+ let assemblyFormat = [{
+ $value
+ }];
+
+ let builders = [
+ AttrBuilder<(ins CArg<"VisibilityKind", "cir::VisibilityKind::Default">:$value), [{
+ return $_get($_ctxt, value);
+ }]>
+ ];
+
+ let skipDefaultBuilders = 1;
+
+ // Make DefaultValuedAttr accept VisibilityKind as default value ($0).
+ let constBuilderCall = "cir::VisibilityAttr::get($_builder.getContext(), $0)";
+
+ let extraClassDeclaration = [{
+ bool isDefault() const { return getValue() == VisibilityKind::Default; };
+ bool isHidden() const { return getValue() == VisibilityKind::Hidden; };
+ bool isProtected() const { return getValue() == VisibilityKind::Protected; };
+ }];
+}
+
#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_TD
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 5ce03c19369cb..6637ad14091cc 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1634,7 +1634,8 @@ def GlobalLinkageKind : I32EnumAttr<
// properties of a global variable will be added over time as more of ClangIR
// is upstreamed.
-def GlobalOp : CIR_Op<"global"> {
+def GlobalOp : CIR_Op<"global",
+ [DeclareOpInterfaceMethods<CIRGlobalValueInterface>]> {
let summary = "Declare or define a global variable";
let description = [{
The `cir.global` operation declares or defines a named global variable.
@@ -1643,17 +1644,31 @@ def GlobalOp : CIR_Op<"global"> {
described by the type of the variable.
The `linkage` tracks C/C++ linkage types, currently very similar to LLVM's.
+ Symbol visibility in `sym_visibility` is defined in terms of MLIR's visibility
+ and verified to be in accordance to `linkage`.
}];
+ // Note that both sym_name and sym_visibility are tied to Symbol trait.
+ // TODO: sym_visibility can possibly be represented by implementing the
+ // necessary Symbol's interface in terms of linkage instead.
let arguments = (ins SymbolNameAttr:$sym_name,
+ DefaultValuedAttr<
+ VisibilityAttr,
+ "VisibilityKind::Default"
+ >:$global_visibility,
+ OptionalAttr<StrAttr>:$sym_visibility,
TypeAttr:$sym_type,
Arg<GlobalLinkageKind, "linkage type">:$linkage,
OptionalAttr<AnyAttr>:$initial_value,
+ UnitAttr:$comdat,
UnitAttr:$dsolocal,
OptionalAttr<I64Attr>:$alignment);
let assemblyFormat = [{
+ ($sym_visibility^)?
+ (`` $global_visibility^)?
$linkage
+ (`comdat` $comdat^)?
(`dsolocal` $dsolocal^)?
$sym_name
custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value)
diff --git a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
index 6e6d59ea5dadb..6e7f3da4add3e 100644
--- a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
+++ b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
@@ -14,10 +14,10 @@ mlir_tablegen(CIROpsDialect.cpp.inc -gen-dialect-defs)
add_public_tablegen_target(MLIRCIROpsIncGen)
add_dependencies(mlir-headers MLIRCIROpsIncGen)
-mlir_tablegen(CIROpsAttributes.h.inc -gen-attrdef-decls)
-mlir_tablegen(CIROpsAttributes.cpp.inc -gen-attrdef-defs)
mlir_tablegen(CIROpsEnums.h.inc -gen-enum-decls)
mlir_tablegen(CIROpsEnums.cpp.inc -gen-enum-defs)
+mlir_tablegen(CIROpsAttributes.h.inc -gen-attrdef-decls)
+mlir_tablegen(CIROpsAttributes.cpp.inc -gen-attrdef-defs)
add_public_tablegen_target(MLIRCIREnumsGen)
set(LLVM_TARGET_DEFINITIONS CIRTypeConstraints.td)
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 56bf9b1130f12..11250be483edc 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -31,7 +31,6 @@ struct MissingFeatures {
static bool cgfSymbolTable() { return false; }
// Unhandled global/linkage information.
- static bool opGlobalDSOLocal() { return false; }
static bool opGlobalThreadLocal() { return false; }
static bool opGlobalConstant() { return false; }
static bool opGlobalWeakRef() { return false; }
@@ -41,11 +40,11 @@ struct MissingFeatures {
static bool opGlobalVisibility() { return false; }
static bool opGlobalDLLImportExport() { return false; }
static bool opGlobalPartition() { return false; }
- static bool opGlobalCIRGlobalValueInterface() { return false; }
static bool supportIFuncAttr() { return false; }
static bool supportVisibility() { return false; }
- static bool supportComdat() { return false; }
+ static bool hiddenVisibility() { return false; }
+ static bool protectedVisibility() { return false; }
// Load/store attributes
static bool opLoadStoreThreadLocal() { return false; }
@@ -188,7 +187,6 @@ struct MissingFeatures {
static bool updateCompletedType() { return false; }
static bool targetSpecificCXXABI() { return false; }
static bool moduleNameHash() { return false; }
- static bool setDSOLocal() { return false; }
static bool constantFoldSwitchStatement() { return false; }
static bool cudaSupport() { return false; }
static bool maybeHandleStaticInExternC() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index b31b2b33d7d86..0d315aa277140 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/GlobalDecl.h"
#include "clang/Basic/SourceManager.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Interfaces/CIROpInterfaces.h"
#include "clang/CIR/MissingFeatures.h"
#include "CIRGenFunctionInfo.h"
@@ -391,9 +392,7 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
if (d->getTLSKind())
errorNYI(d->getSourceRange(), "thread local global variable");
- assert(!cir::MissingFeatures::opGlobalDLLImportExport());
- assert(!cir::MissingFeatures::opGlobalPartition());
- assert(!cir::MissingFeatures::setDSOLocal());
+ setGVProperties(gv, d);
// If required by the ABI, treat declarations of static data members with
// inline initializers as definitions.
@@ -401,15 +400,20 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
errorNYI(d->getSourceRange(), "MS static data member inline definition");
assert(!cir::MissingFeatures::opGlobalSection());
- assert(!cir::MissingFeatures::opGlobalVisibility());
+ gv.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(d));
// Handle XCore specific ABI requirements.
if (getTriple().getArch() == llvm::Triple::xcore)
errorNYI(d->getSourceRange(), "XCore specific ABI requirements");
- // We need to check for external const declarations with initializers here,
- // but the 'isPublic()' part of the check uses the CIRGlobalValueInterface.
- assert(!cir::MissingFeatures::opGlobalCIRGlobalValueInterface());
+ // Check if we a have a const declaration with an initializer, we may be
+ // able to emit it as available_externally to expose it's value to the
+ // optimizer.
+ if (getLangOpts().CPlusPlus && gv.isPublic() &&
+ d->getType().isConstQualified() && gv.isDeclaration() &&
+ !d->hasDefinition() && d->hasInit() && !d->hasAttr<DLLImportAttr>())
+ errorNYI(d->getSourceRange(),
+ "external const declaration with initializer");
}
return gv;
@@ -568,7 +572,9 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
// Set CIR linkage and DLL storage class.
gv.setLinkage(linkage);
-
+ // FIXME(cir): setLinkage should likely set MLIR's visibility automatically.
+ gv.setVisibility(getMLIRVisibilityFromCIRLinkage(linkage));
+ assert(!cir::MissingFeatures::opGlobalDLLImportExport());
if (linkage == cir::GlobalLinkageKind::CommonLinkage)
errorNYI(initExpr->getSourceRange(), "common linkage");
}
@@ -632,8 +638,13 @@ CIRGenModule::getConstantArrayFromStringLiteral(const StringLiteral *e) {
return mlir::Attribute();
}
+bool CIRGenModule::supportsCOMDAT() const {
+ return getTriple().supportsCOMDAT();
+}
+
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d) {
- assert(!cir::MissingFeatures::supportComdat());
+ if (!cgm.supportsCOMDAT())
+ return false;
if (d.hasAttr<SelectAnyAttr>())
return true;
@@ -836,8 +847,11 @@ static cir::GlobalOp generateStringLiteral(mlir::Location loc,
assert(!cir::MissingFeatures::opGlobalThreadLocal());
assert(!cir::MissingFeatures::opGlobalUnnamedAddr());
CIRGenModule::setInitializer(gv, c);
- assert(!cir::MissingFeatures::supportComdat());
- assert(!cir::MissingFeatures::opGlobalDSOLocal());
+ if (gv.isWeakForLinker()) {
+ assert(cgm.supportsCOMDAT() && "Only COFF uses weak string literals");
+ gv.setComdat(true);
+ }
+ cgm.setDSOLocal(static_cast<mlir::Operation *>(gv));
return gv;
}
@@ -894,7 +908,7 @@ cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
auto typedC = llvm::cast<mlir::TypedAttr>(c);
cir::GlobalOp gv =
generateStringLiteral(loc, typedC, *this, uniqueName, alignment);
- assert(!cir::MissingFeatures::opGlobalDSOLocal());
+ setDSOLocal(static_cast<mlir::Operation *>(gv));
assert(!cir::MissingFeatures::sanitizers());
@@ -1075,6 +1089,135 @@ void CIRGenModule::emitTentativeDefinition(const VarDecl *d) {
emitGlobalVarDefinition(d);
}
+static bool shouldAssumeDSOLocal(const CIRGenModule &cgm,
+ cir::CIRGlobalValueInterface gv) {
+ if (gv.hasLocalLinkage())
+ return true;
+
+ if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
+ return true;
+
+ // DLLImport explicitly marks the GV as external.
+ // so it shouldn't be dso_local
+ // But we don't have the info set now
+ assert(!cir::MissingFeatures::opGlobalDLLImportExport());
+
+ const llvm::Triple &tt = cgm.getTriple();
+ const auto &cgOpts = cgm.getCodeGenOpts();
+ if (tt.isWindowsGNUEnvironment()) {
+ // In MinGW, variables without DLLImport can still be automatically
+ // imported from a DLL by the linker; don't mark variables that
+ // potentially could come from another DLL as DSO local.
+
+ // With EmulatedTLS, TLS variables can be autoimported from other DLLs
+ // (and this actually happens in the public interface of libstdc++), so
+ // such variables can't be marked as DSO local. (Native TLS variables
+ // can't be dllimported at all, though.)
+ cgm.errorNYI("shouldAssumeDSOLocal: MinGW");
+ }
+
+ // On COFF, don't mark 'extern_weak' symbols as DSO local. If these symbols
+ // remain unresolved in the link, they can be resolved to zero, which is
+ // outside the current DSO.
+ if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
+ return false;
+
+ // Every other GV is local on COFF.
+ // Make an exception for windows OS in the triple: Some firmware builds use
+ // *-win32-macho triples. This (accidentally?) produced windows relocations
+ // without GOT tables in older clang versions; Keep this behaviour.
+ // FIXME: even thread local variables?
+ if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
+ return true;
+
+ // Only handle COFF and ELF for now.
+ if (!tt.isOSBinFormatELF())
+ return false;
+
+ llvm::Reloc::Model rm = cgOpts.RelocationModel;
+ const auto &lOpts = cgm.getLangOpts();
+ if (rm != llvm::Reloc::Static && !lOpts.PIE) {
+ // On ELF, if -fno-semantic-interposition is specified and the target
+ // supports local aliases, there will be neither CC1
+ // -fsemantic-interposition nor -fhalf-no-semantic-interposition. Set
+ // dso_local on the function if using a local alias is preferable (can avoid
+ // PLT indirection).
+ if (!(isa<cir::FuncOp>(gv) && gv.canBenefitFromLocalAlias()))
+ return false;
+ return !(cgm.getLangOpts().SemanticInterposition ||
+ cgm.getLangOpts().HalfNoSemanticInterposition);
+ }
+
+ // A definition cannot be preempted from an executable.
+ if (!gv.isDeclarationForLinker())
+ return true;
+
+ // Most PIC code sequences that assume that a symbol is local cannot produce a
+ // 0 if it turns out the symbol is undefined. While this is ABI and relocation
+ // depended, it seems worth it to handle it here.
+ if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
+ return false;
+
+ // PowerPC64 prefers TOC indirection to avoid copy relocations.
+ if (tt.isPPC64())
+ return false;
+
+ if (cgOpts.DirectAccessExternalData) {
+ // If -fdirect-access-external-data (default for -fno-pic), set dso_local
+ // for non-thread-local variables. If the symbol is not defined in the
+ // executable, a copy relocation will be needed at link time. dso_local is
+ // excluded for thread-local variables because they generally don't support
+ // copy relocations.
+ if (auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
+ // Assume variables are not thread-local until that support is added.
+ assert(!cir::MissingFeatures::opGlobalThreadLocal());
+ return true;
+ }
+
+ // -fno-pic sets dso_local on a function declaration to allow direct
+ // accesses when taking its address (similar to a data symbol). If the
+ // function is not defined in the executable, a canonical PLT entry will be
+ // needed at link time. -fno-direct-access-external-data can avoid the
+ // canonical PLT entry. We don't generalize this condition to -fpie/-fpic as
+ // it could just cause trouble without providing perceptible benefits.
+ if (isa<cir::FuncOp>(gv) && !cgOpts.NoPLT && rm == llvm::Reloc::Static)
+ return true;
+ }
+
+ // If we can use copy relocations we can assume it is local.
+
+ // Otherwise don't assume it is local.
+
+ return false;
+}
+
+void CIRGenModule::setGlobalVisibility(mlir::Operation *gv,
+ const NamedDecl *d) const {
+ assert(!cir::MissingFeatures::opGlobalVisibility());
+}
+
+void CIRGenModule::setDSOLocal(cir::CIRGlobalValueInterface gv) const {
+ gv.setDSOLocal(shouldAssumeDSOLocal(*this, gv));
+}
+
+void CIRGenModule::setDSOLocal(mlir::Operation *op) const {
+ if (auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
+ setDSOLocal(globalValue);
+}
+
+void CIRGenModule::setGVProperties(mlir::Operation *op,
+ const NamedDecl *d) const {
+ assert(!cir::MissingFeatures::opGlobalDLLImportExport());
+ setGVPropertiesAux(op, d);
+}
+
+void CIRGenModule::setGVPropertiesAux(mlir::Operation *op,
+ const NamedDecl *d) const {
+ setGlobalVisibility(op, d);
+ setDSOLocal(op);
+ assert(!cir::MissingFeatures::opGlobalPartition());
+}
+
cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable,
bool dontDefer, bool isThunk, ForDefinition_t isForDefinition,
@@ -1111,7 +1254,7 @@ cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
// Handle dropped DLL attributes.
if (d && !d->hasAttr<DLLImportAttr>() && !d->hasAttr<DLLExportAttr>()) {
assert(!cir::MissingFeatures::setDLLStorageClass());
- assert(!cir::MissingFeatures::setDSOLocal());
+ setDSOLocal(entry);
}
// If there are two attempts to define the same mangled name, issue an
@@ -1165,6 +1308,55 @@ CIRGenModule::createCIRFunction(mlir::Location loc, StringRef name,
return func;
}
+mlir::SymbolTable::Visibility
+CIRGenModule::getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind glk) {
+ switch (glk) {
+ case cir::GlobalLinkageKind::InternalLinkage:
+ case cir::GlobalLinkageKind::PrivateLinkage:
+ return mlir::SymbolTable::Visibility::Private;
+ case cir::GlobalLinkageKind::ExternalLinkage:
+ case cir::GlobalLinkageKind::ExternalWeakLinkage:
+ case cir::GlobalLinkageKind::LinkOnceODRLinkage:
+ case cir::GlobalLinkageKind::AvailableExternallyLinkage:
+ case cir::GlobalLinkageKind::CommonLinkage:
+ case cir::GlobalLinkageKind::WeakAnyLinkage:
+ case cir::GlobalLinkageKind::WeakODRLinkage:
+ return mlir::SymbolTable::Visibility::Public;
+ default: {
+ llvm::errs() << "visibility not implemented for '"
+ << stringifyGlobalLinkageKind(glk) << "'\n";
+ assert(0 && "not implemented");
+ }
+ }
+ llvm_unreachable("linkage should be handled above!");
+}
+
+cir::VisibilityKind CIRGenModule::getGlobalVisibilityKindFromClangVisibility(
+ clang::VisibilityAttr::VisibilityType visibility) {
+ switch (visibility) {
+ case clang::VisibilityAttr::VisibilityType::Default:
+ return cir::VisibilityKind::Default;
+ case clang::VisibilityAttr::VisibilityType::Hidden:
+ return cir::VisibilityKind::Hidden;
+ case clang::VisibilityAttr::VisibilityType::Protected:
+ return cir::VisibilityKind::Protected;
+ }
+ llvm_unreachable("unexpected visibility value");
+}
+
+cir::VisibilityAttr
+CIRGenModule::getGlobalVisibilityAttrFromDecl(const Decl *decl) {
+ const clang::VisibilityAttr *va = decl->getAttr<clang::VisibilityAttr>();
+ cir::VisibilityAttr cirVisibility =
+ cir::VisibilityAttr::get(&getMLIRContext());
+ if (va) {
+ cirVisibility = cir::VisibilityAttr::get(
+ &getMLIRContext(),
+ getGlobalVisibilityKindFromClangVisibility(va->getVisibility()));
+ }
+ return cirVisibility;
+}
+
mlir::Type CIRGenModule::convertType(QualType type) {
return genTypes.convertType(type);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index aac8fe72b1890..19cb5eda3507c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -179,6 +179,16 @@ class CIRGenModule : public CIRGenTypeCache {
mlir::Type convertType(clang::QualType type);
+ /// Set the visibility for the given global.
+ void setGlobalVisibility(mlir::Operation *op, const NamedDecl *d) const;
+ void setDSOLocal(mlir::Operation *op) const;
+ void setDSOLocal(cir::CIRGlobalValueInterface gv) const;
+
+ /// Set visibility, dllimport/dllexport and dso_local.
+ /// This must be called after dllimport/dllexport is set.
+ void setGVProperties(mlir::Operation *op, const NamedDecl *d) const;
+ void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const;
+
void emitGlobalDefinition(clang::GlobalDecl gd,
mlir::Operation *op = nullptr);
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op);
@@ -198,6 +208,8 @@ class CIRGenModule : public CIRGenTypeCache {
void emitTentativeDefinition(const VarDecl *d);
+ bool supportsCOMDAT() const;
+
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value);
cir::FuncOp
@@ -217,6 +229,17 @@ class CIRGenModule : public CIRGenTypeCache {
const llvm::Triple &getTriple() const { return target.getTriple(); }
+ /// -------
+ /// Visibility and Linkage
+ /// -------
+
+ static mlir::SymbolTable::Visibility
+ getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK);
+ static cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility(
+ clang::VisibilityAttr::VisibilityType visibility);
+ cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl);
+ static mlir::SymbolTable::Visibility getMLIRVisibility(cir::GlobalOp op);
+
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd,
GVALinkage linkage,
bool isConstantVariable);
@@ -243,7 +266,7 @@ class CIRGenModule : public CIRGenTypeCache {
return diags.Report(diagID) << feature;
}
- DiagnosticBuilder errorNYI(llvm::StringRef feature) {
+ DiagnosticBuilder errorNYI(llvm::StringRef feature) const {
// TODO: Make a default location? currSrcLoc?
unsigned diagID = diags.getCustomDiagID(
DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0");
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 9e2b2908b22d8..68bae8ecfdb1c 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -1132,6 +1132,9 @@ void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState,
cir::GlobalLinkageKindAttr linkageAttr =
cir::GlobalLinkageKindAttr::get(odsBuilder.getContext(), linkage);
odsState.addAttribute(getLinkageAttrName(odsState.name), linkageAttr);
+
+ odsState.addAttribute(getGlobalVisibilityAttrName(odsState.name),
+ cir::VisibilityAttr::get(odsBuilder.getContext()));
}
static void printGlobalOpTypeAndInitialValue(OpAsmPrinter &p, cir::GlobalOp op,
diff --git a/clang/lib/CIR/Interfaces/CIROpInterfaces.cpp b/clang/lib/CIR/Interfaces/CIROpInterfaces.cpp
index 3ae103c2e65b4..82427e2c12222 100644
--- a/clang/lib/CIR/Interfaces/CIROpInterfaces.cpp
+++ b/clang/lib/CIR/Interfaces/CIROpInterfaces.cpp
@@ -18,9 +18,20 @@ using namespace cir;
#include "clang/CIR/MissingFeatures.h"
+bool CIRGlobalValueInterface::hasDefaultVisibility() {
+ assert(!cir::MissingFeatures::hiddenVisibility());
+ assert(!cir::MissingFeatures::protectedVisibility());
+ return isPublic() || isPrivate();
+}
+
bool CIRGlobalValueInterface::canBenefitFromLocalAlias() {
assert(!cir::MissingFeatures::supportIFuncAttr());
- assert(!cir::MissingFeatures::supportVisibility());
- assert(!cir::MissingFeatures::supportComdat());
- return false;
+ // hasComdat here should be isDeduplicateComdat, but as far as clang codegen
+ // is concerned, there is no case for Comdat::NoDeduplicate as all comdat
+ // would be Comdat::Any or Comdat::Largest (in the case of MS ABI). And CIRGen
+ // wouldn't even generate Comdat::Largest comdat as it tries to leave ABI
+ // specifics to LLVM lowering stage, thus here we don't need test Comdat
+ // selectionKind.
+ return hasDefaultVisibility() && hasExternalLinkage() && !isDeclaration() &&
+ !hasComdat();
}
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 8e82af7e62bc0..8f43d2564f472 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -966,8 +966,7 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
const bool isConst = false;
assert(!cir::MissingFeatures::addressSpace());
const unsigned addrSpace = 0;
- assert(!cir::MissingFeatures::opGlobalDSOLocal());
- const bool isDsoLocal = true;
+ const auto isDsoLocal = op.getDsolocal();
assert(!cir::MissingFeatures::opGlobalThreadLocal());
const bool isThreadLocal = false;
const uint64_t alignment = op.getAlignment().value_or(0);
@@ -1021,8 +1020,7 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
const bool isConst = false;
assert(!cir::MissingFeatures::addressSpace());
const unsigned addrSpace = 0;
- assert(!cir::MissingFeatures::opGlobalDSOLocal());
- const bool isDsoLocal = true;
+ const auto isDsoLocal = op.getDsolocal();
assert(!cir::MissingFeatures::opGlobalThreadLocal());
const bool isThreadLocal = false;
const uint64_t alignment = op.getAlignment().value_or(0);
diff --git a/clang/test/CIR/CodeGen/array.cpp b/clang/test/CIR/CodeGen/array.cpp
index 18f30b20ff8f7..7b90c1682ec45 100644
--- a/clang/test/CIR/CodeGen/array.cpp
+++ b/clang/test/CIR/CodeGen/array.cpp
@@ -8,35 +8,35 @@
int a[10];
// CIR: cir.global external @a = #cir.zero : !cir.array<!s32i x 10>
-// LLVM: @a = dso_local global [10 x i32] zeroinitializer
+// LLVM: @a = global [10 x i32] zeroinitializer
// OGCG: @a = global [10 x i32] zeroinitializer
int aa[10][5];
// CIR: cir.global external @aa = #cir.zero : !cir.array<!cir.array<!s32i x 5> x 10>
-// LLVM: @aa = dso_local global [10 x [5 x i32]] zeroinitializer
+// LLVM: @aa = global [10 x [5 x i32]] zeroinitializer
// OGCG: @aa = global [10 x [5 x i32]] zeroinitializer
int c[10] = {};
// CIR: cir.global external @c = #cir.zero : !cir.array<!s32i x 10>
-// LLVM: @c = dso_local global [10 x i32] zeroinitializer
+// LLVM: @c = global [10 x i32] zeroinitializer
// OGCG: @c = global [10 x i32] zeroinitializer
int d[3] = {1, 2, 3};
// CIR: cir.global external @d = #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i]> : !cir.array<!s32i x 3>
-// LLVM: @d = dso_local global [3 x i32] [i32 1, i32 2, i32 3]
+// LLVM: @d = global [3 x i32] [i32 1, i32 2, i32 3]
// OGCG: @d = global [3 x i32] [i32 1, i32 2, i32 3]
int dd[3][2] = {{1, 2}, {3, 4}, {5, 6}};
// CIR: cir.global external @dd = #cir.const_array<[#cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i]> : !cir.array<!s32i x 2>, #cir.const_array<[#cir.int<3> : !s32i, #cir.int<4> : !s32i]> : !cir.array<!s32i x 2>, #cir.const_array<[#cir.int<5> : !s32i, #cir.int<6> : !s32i]> : !cir.array<!s32i x 2>]> : !cir.array<!cir.array<!s32i x 2> x 3>
-// LLVM: @dd = dso_local global [3 x [2 x i32]] [
+// LLVM: @dd = global [3 x [2 x i32]] [
// LLVM: [2 x i32] [i32 1, i32 2], [2 x i32]
// LLVM: [i32 3, i32 4], [2 x i32] [i32 5, i32 6]]
@@ -47,23 +47,25 @@ int dd[3][2] = {{1, 2}, {3, 4}, {5, 6}};
int e[10] = {1, 2};
// CIR: cir.global external @e = #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i], trailing_zeros> : !cir.array<!s32i x 10>
-// LLVM: @e = dso_local global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]
+// LLVM: @e = global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]
+
+// OGCG: @e = global <{ i32, i32, [8 x i32] }> <{ i32 1, i32 2, [8 x i32] zeroinitializer }>
int f[5] = {1, 2};
// CIR: cir.global external @f = #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<0> : !s32i, #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.array<!s32i x 5>
-// LLVM: @f = dso_local global [5 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0]
+// LLVM: @f = global [5 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0]
// OGCG: @f = global [5 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0]
extern int b[10];
-// CIR: cir.global external @b : !cir.array<!s32i x 10>
-// LLVM: @b = external dso_local global [10 x i32]
+// CIR: cir.global "private" external @b : !cir.array<!s32i x 10>
+// LLVM: @b = external global [10 x i32]
// OGCG: @b = external global [10 x i32]
extern int bb[10][5];
-// CIR: cir.global external @bb : !cir.array<!cir.array<!s32i x 5> x 10>
-// LLVM: @bb = external dso_local global [10 x [5 x i32]]
+// CIR: cir.global "private" external @bb : !cir.array<!cir.array<!s32i x 5> x 10>
+// LLVM: @bb = external global [10 x [5 x i32]]
// OGCG: @bb = external global [10 x [5 x i32]]
// This function is only here to make sure the external globals are emitted.
diff --git a/clang/test/CIR/CodeGen/namespace.cpp b/clang/test/CIR/CodeGen/namespace.cpp
index bfb4e37c2fa74..e0cf6333c1197 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 internal @_ZN12_GLOBAL__N_12g1E = #cir.int<1> : !s32i
+// CHECK-DAG: cir.global "private" internal @_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 81d2a27591295..549fdcb74f48a 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 external @[[STR1_GLOBAL:.*]] = #cir.const_array<"1\00" : !cir.array<!s8i x 2>> : !cir.array<!s8i x 2>
-// CIR: cir.global external @[[STR2_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 1>
-// CIR: cir.global external @[[STR3_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 2>
+// 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>
-// LLVM: @[[STR1_GLOBAL:.*]] = dso_local global [2 x i8] c"1\00"
-// LLVM: @[[STR2_GLOBAL:.*]] = dso_local global [1 x i8] zeroinitializer
-// LLVM: @[[STR3_GLOBAL:.*]] = dso_local global [2 x i8] zeroinitializer
+// 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
// 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/CodeGen/struct.c b/clang/test/CIR/CodeGen/struct.c
index 4c18de295c68c..ed84edd97e5d0 100644
--- a/clang/test/CIR/CodeGen/struct.c
+++ b/clang/test/CIR/CodeGen/struct.c
@@ -48,13 +48,13 @@ struct CompleteS {
} cs;
// CIR: cir.global external @cs = #cir.zero : !rec_CompleteS
-// LLVM-DAG: @cs = dso_local global %struct.CompleteS zeroinitializer
+// LLVM-DAG: @cs = global %struct.CompleteS zeroinitializer
// OGCG-DAG: @cs = global %struct.CompleteS zeroinitializer, align 4
struct IncompleteS *p;
// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!rec_IncompleteS>
-// LLVM-DAG: @p = dso_local global ptr null
+// LLVM-DAG: @p = global ptr null
// OGCG-DAG: @p = global ptr null, align 8
struct InnerS {
@@ -70,7 +70,7 @@ struct OuterS {
struct OuterS os;
// CIR: cir.global external @os = #cir.zero : !rec_OuterS
-// LLVM-DAG: @os = dso_local global %struct.OuterS zeroinitializer
+// LLVM-DAG: @os = global %struct.OuterS zeroinitializer
// OGCG-DAG: @os = global %struct.OuterS zeroinitializer, align 4
#pragma pack(push)
@@ -82,7 +82,7 @@ struct PackedS {
} ps;
// CIR: cir.global external @ps = #cir.zero : !rec_PackedS
-// LLVM-DAG: @ps = dso_local global %struct.PackedS zeroinitializer
+// LLVM-DAG: @ps = global %struct.PackedS zeroinitializer
// OGCG-DAG: @ps = global %struct.PackedS zeroinitializer, align 1
struct PackedAndPaddedS {
@@ -91,7 +91,7 @@ struct PackedAndPaddedS {
} __attribute__((aligned(2))) pps;
// CIR: cir.global external @pps = #cir.zero : !rec_PackedAndPaddedS
-// LLVM-DAG: @pps = dso_local global %struct.PackedAndPaddedS zeroinitializer
+// LLVM-DAG: @pps = global %struct.PackedAndPaddedS zeroinitializer
// OGCG-DAG: @pps = global %struct.PackedAndPaddedS zeroinitializer, align 2
#pragma pack(pop)
@@ -102,7 +102,7 @@ struct NodeS {
} node;
// CIR: cir.global{{.*}} @node = #cir.zero : !rec_NodeS
-// LLVM-DAG: @node = dso_local global %struct.NodeS zeroinitializer
+// LLVM-DAG: @node = global %struct.NodeS zeroinitializer
// OGCG-DAG: @node = global %struct.NodeS zeroinitializer
// Mutually dependent types
@@ -112,7 +112,7 @@ struct LeftS {
} ls;
// CIR: cir.global{{.*}} @ls = #cir.zero : !rec_LeftS
-// LLVM-DAG: @ls = dso_local global %struct.LeftS zeroinitializer
+// LLVM-DAG: @ls = global %struct.LeftS zeroinitializer
// OGCG-DAG: @ls = global %struct.LeftS zeroinitializer
struct RightS {
@@ -120,7 +120,7 @@ struct RightS {
} rs;
// CIR: cir.global{{.*}} @rs = #cir.zero : !rec_RightS
-// LLVM-DAG: @rs = dso_local global %struct.RightS zeroinitializer
+// LLVM-DAG: @rs = global %struct.RightS zeroinitializer
// OGCG-DAG: @rs = global %struct.RightS zeroinitializer
struct CycleMiddle;
@@ -130,7 +130,7 @@ struct CycleStart {
} start;
// CIR: cir.global{{.*}} @start = #cir.zero : !rec_CycleStart
-// LLVM-DAG: @start = dso_local global %struct.CycleStart zeroinitializer
+// LLVM-DAG: @start = global %struct.CycleStart zeroinitializer
// OGCG-DAG: @start = global %struct.CycleStart zeroinitializer
struct CycleMiddle {
@@ -138,7 +138,7 @@ struct CycleMiddle {
} middle;
// CIR: cir.global{{.*}} @middle = #cir.zero : !rec_CycleMiddle
-// LLVM-DAG: @middle = dso_local global %struct.CycleMiddle zeroinitializer
+// LLVM-DAG: @middle = global %struct.CycleMiddle zeroinitializer
// OGCG-DAG: @middle = global %struct.CycleMiddle zeroinitializer
struct CycleEnd {
@@ -146,7 +146,7 @@ struct CycleEnd {
} end;
// CIR: cir.global{{.*}} @end = #cir.zero : !rec_CycleEnd
-// LLVM-DAG: @end = dso_local global %struct.CycleEnd zeroinitializer
+// LLVM-DAG: @end = global %struct.CycleEnd zeroinitializer
// OGCG-DAG: @end = global %struct.CycleEnd zeroinitializer
void f(void) {
diff --git a/clang/test/CIR/CodeGen/struct.cpp b/clang/test/CIR/CodeGen/struct.cpp
index 5948d1423d448..8b9c51bebf97f 100644
--- a/clang/test/CIR/CodeGen/struct.cpp
+++ b/clang/test/CIR/CodeGen/struct.cpp
@@ -9,7 +9,7 @@ struct IncompleteS;
IncompleteS *p;
// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!rec_IncompleteS>
-// LLVM: @p = dso_local global ptr null
+// LLVM: @p = global ptr null
// OGCG: @p = global ptr null, align 8
struct CompleteS {
@@ -20,7 +20,7 @@ struct CompleteS {
CompleteS cs;
// CIR: cir.global external @cs = #cir.zero : !rec_CompleteS
-// LLVM-DAG: @cs = dso_local global %struct.CompleteS zeroinitializer
+// LLVM-DAG: @cs = global %struct.CompleteS zeroinitializer
// OGCG-DAG: @cs = global %struct.CompleteS zeroinitializer, align 4
void f(void) {
diff --git a/clang/test/CIR/CodeGen/union.c b/clang/test/CIR/CodeGen/union.c
index 96c1e420e5ef0..d998b5add41a3 100644
--- a/clang/test/CIR/CodeGen/union.c
+++ b/clang/test/CIR/CodeGen/union.c
@@ -47,7 +47,7 @@ union U4 {
union IncompleteU *p;
// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!rec_IncompleteU>
-// LLVM: @p = dso_local global ptr null
+// LLVM: @p = global ptr null
// OGCG: @p = global ptr null, align 8
void f1(void) {
diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp
index aab723f041edf..b86cf94c83092 100644
--- a/clang/test/CIR/CodeGen/vector-ext.cpp
+++ b/clang/test/CIR/CodeGen/vector-ext.cpp
@@ -15,21 +15,21 @@ typedef double vd2 __attribute__((ext_vector_type(2)));
vi4 vec_a;
// CIR: cir.global external @[[VEC_A:.*]] = #cir.zero : !cir.vector<4 x !s32i>
-// LLVM: @[[VEC_A:.*]] = dso_local global <4 x i32> zeroinitializer
+// LLVM: @[[VEC_A:.*]] = global <4 x i32> zeroinitializer
// OGCG: @[[VEC_A:.*]] = global <4 x i32> zeroinitializer
vi3 vec_b;
// CIR: cir.global external @[[VEC_B:.*]] = #cir.zero : !cir.vector<3 x !s32i>
-// LLVM: @[[VEC_B:.*]] = dso_local global <3 x i32> zeroinitializer
+// LLVM: @[[VEC_B:.*]] = global <3 x i32> zeroinitializer
// OGCG: @[[VEC_B:.*]] = global <3 x i32> zeroinitializer
vi2 vec_c;
// CIR: cir.global external @[[VEC_C:.*]] = #cir.zero : !cir.vector<2 x !s32i>
-// LLVM: @[[VEC_C:.*]] = dso_local global <2 x i32> zeroinitializer
+// LLVM: @[[VEC_C:.*]] = global <2 x i32> zeroinitializer
// OGCG: @[[VEC_C:.*]] = global <2 x i32> zeroinitializer
@@ -37,7 +37,7 @@ vd2 vec_d;
// CIR: cir.global external @[[VEC_D:.*]] = #cir.zero : !cir.vector<2 x !cir.double>
-// LLVM: @[[VEC_D:.*]] = dso_local global <2 x double> zeroinitialize
+// LLVM: @[[VEC_D:.*]] = global <2 x double> zeroinitialize
// OGCG: @[[VEC_D:.*]] = global <2 x double> zeroinitializer
@@ -46,7 +46,7 @@ vi4 vec_e = { 1, 2, 3, 4 };
// CIR: cir.global external @[[VEC_E:.*]] = #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<2> :
// CIR-SAME: !s32i, #cir.int<3> : !s32i, #cir.int<4> : !s32i]> : !cir.vector<4 x !s32i>
-// LLVM: @[[VEC_E:.*]] = dso_local global <4 x i32> <i32 1, i32 2, i32 3, i32 4>
+// LLVM: @[[VEC_E:.*]] = global <4 x i32> <i32 1, i32 2, i32 3, i32 4>
// OGCG: @[[VEC_E:.*]] = global <4 x i32> <i32 1, i32 2, i32 3, i32 4>
diff --git a/clang/test/CIR/CodeGen/vector.cpp b/clang/test/CIR/CodeGen/vector.cpp
index f5a4fcacac4d4..7ffc68d55f2ce 100644
--- a/clang/test/CIR/CodeGen/vector.cpp
+++ b/clang/test/CIR/CodeGen/vector.cpp
@@ -14,21 +14,21 @@ typedef long long vll2 __attribute__((vector_size(16)));
vi4 vec_a;
// CIR: cir.global external @[[VEC_A:.*]] = #cir.zero : !cir.vector<4 x !s32i>
-// LLVM: @[[VEC_A:.*]] = dso_local global <4 x i32> zeroinitializer
+// LLVM: @[[VEC_A:.*]] = global <4 x i32> zeroinitializer
// OGCG: @[[VEC_A:.*]] = global <4 x i32> zeroinitializer
vd2 b;
// CIR: cir.global external @[[VEC_B:.*]] = #cir.zero : !cir.vector<2 x !cir.double>
-// LLVM: @[[VEC_B:.*]] = dso_local global <2 x double> zeroinitialize
+// LLVM: @[[VEC_B:.*]] = global <2 x double> zeroinitialize
// OGCG: @[[VEC_B:.*]] = global <2 x double> zeroinitializer
vll2 c;
// CIR: cir.global external @[[VEC_C:.*]] = #cir.zero : !cir.vector<2 x !s64i>
-// LLVM: @[[VEC_C:.*]] = dso_local global <2 x i64> zeroinitialize
+// LLVM: @[[VEC_C:.*]] = global <2 x i64> zeroinitialize
// OGCG: @[[VEC_C:.*]] = global <2 x i64> zeroinitializer
@@ -37,7 +37,7 @@ vi4 d = { 1, 2, 3, 4 };
// CIR: cir.global external @[[VEC_D:.*]] = #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<2> :
// CIR-SAME: !s32i, #cir.int<3> : !s32i, #cir.int<4> : !s32i]> : !cir.vector<4 x !s32i>
-// LLVM: @[[VEC_D:.*]] = dso_local global <4 x i32> <i32 1, i32 2, i32 3, i32 4>
+// LLVM: @[[VEC_D:.*]] = global <4 x i32> <i32 1, i32 2, i32 3, i32 4>
// OGCG: @[[VEC_D:.*]] = global <4 x i32> <i32 1, i32 2, i32 3, i32 4>
diff --git a/clang/test/CIR/IR/array.cir b/clang/test/CIR/IR/array.cir
index 5995c393730ae..4930fc493c5a7 100644
--- a/clang/test/CIR/IR/array.cir
+++ b/clang/test/CIR/IR/array.cir
@@ -4,17 +4,17 @@
module {
-cir.global external @a : !cir.array<!s32i x 10>
-// CHECK: cir.global external @a : !cir.array<!s32i x 10>
+cir.global external @a = #cir.zero : !cir.array<!s32i x 10>
+// CHECK: cir.global external @a = #cir.zero : !cir.array<!s32i x 10>
-cir.global external @aa : !cir.array<!cir.array<!s32i x 10> x 10>
-// CHECK: cir.global external @aa : !cir.array<!cir.array<!s32i x 10> x 10>
+cir.global external @aa = #cir.zero : !cir.array<!cir.array<!s32i x 10> x 10>
+// CHECK: cir.global external @aa = #cir.zero : !cir.array<!cir.array<!s32i x 10> x 10>
-cir.global external @b : !cir.array<!s32i x 10>
-// CHECK: cir.global external @b : !cir.array<!s32i x 10>
+cir.global external @b = #cir.zero : !cir.array<!s32i x 10>
+// CHECK: cir.global external @b = #cir.zero : !cir.array<!s32i x 10>
-cir.global external @bb : !cir.array<!cir.array<!s32i x 10> x 10>
-// CHECK: cir.global external @bb : !cir.array<!cir.array<!s32i x 10> x 10>
+cir.global external @bb = #cir.zero : !cir.array<!cir.array<!s32i x 10> x 10>
+// CHECK: cir.global external @bb = #cir.zero : !cir.array<!cir.array<!s32i x 10> x 10>
cir.global external @c = #cir.zero : !cir.array<!s32i x 10>
// CHECK: cir.global external @c = #cir.zero : !cir.array<!s32i x 10>
diff --git a/clang/test/CIR/IR/global-var-linkage.cir b/clang/test/CIR/IR/global-var-linkage.cir
index 6486b700bdbb2..e1b7de4bb2156 100644
--- a/clang/test/CIR/IR/global-var-linkage.cir
+++ b/clang/test/CIR/IR/global-var-linkage.cir
@@ -4,17 +4,17 @@
!s32i = !cir.int<s, 32>
module attributes {cir.triple = "x86_64-unknown-linux-gnu"} {
- cir.global external @aaaa : !s32i
- cir.global internal @bbbb : !s32i
- cir.global linkonce_odr @cccc : !s32i
+ cir.global external @aaaa = #cir.int<0> : !s32i
+ cir.global internal @bbbb = #cir.int<0> : !s32i
+ cir.global linkonce_odr @cccc = #cir.int<0> : !s32i
cir.global internal @ffff = #cir.int<0> : !s32i
- cir.global weak_odr @dddd : !s32i
+ cir.global weak_odr @dddd = #cir.int<0> : !s32i
}
// CHECK: module attributes {cir.triple = "x86_64-unknown-linux-gnu"} {
-// CHECK: cir.global external @aaaa : !s32i
-// CHECK: cir.global internal @bbbb : !s32i
-// CHECK: cir.global linkonce_odr @cccc : !s32i
+// CHECK: cir.global external @aaaa = #cir.int<0> : !s32i
+// CHECK: cir.global internal @bbbb = #cir.int<0> : !s32i
+// CHECK: cir.global linkonce_odr @cccc = #cir.int<0> : !s32i
// CHECK: cir.global internal @ffff = #cir.int<0> : !s32i
-// CHECK: cir.global weak_odr @dddd : !s32i
+// CHECK: cir.global weak_odr @dddd = #cir.int<0> : !s32i
// CHECK: }
diff --git a/clang/test/CIR/IR/global.cir b/clang/test/CIR/IR/global.cir
index e46a30c7cce40..28fad6bbf4471 100644
--- a/clang/test/CIR/IR/global.cir
+++ b/clang/test/CIR/IR/global.cir
@@ -13,69 +13,69 @@
!void = !cir.void
module attributes {cir.triple = "x86_64-unknown-linux-gnu"} {
- cir.global external @c : !s8i
- cir.global external @sc : !s8i
- cir.global external @uc : !u8i
- cir.global external @ss : !s16i
+ cir.global external @c = #cir.int<0> : !s8i
+ cir.global external @sc = #cir.int<0> : !s8i
+ cir.global external @uc = #cir.int<0> : !u8i
+ cir.global external @ss = #cir.int<0> : !s16i
cir.global external @us = #cir.int<100> : !u16i
cir.global external @si = #cir.int<42> : !s32i
- cir.global external @ui : !u32i
- cir.global external @sl : !s64i
- cir.global external @ul : !u64i
- cir.global external @sll : !s64i
+ cir.global external @ui = #cir.int<0> : !u32i
+ cir.global external @sl = #cir.int<0> : !s64i
+ cir.global external @ul = #cir.int<0> : !u64i
+ cir.global external @sll = #cir.int<0> : !s64i
cir.global external @ull = #cir.int<123456> : !u64i
- cir.global external @s128 : !s128i
- cir.global external @u128 : !u128i
- cir.global external @wc : !s32i
- cir.global external @c8 : !u8i
- cir.global external @c16 : !u16i
- cir.global external @c32 : !u32i
- cir.global external @sb20 : !cir.int<s, 20>
- cir.global external @ub48 : !cir.int<u, 48>
- cir.global external @f16 : !cir.f16
- cir.global external @bf16 : !cir.bf16
- cir.global external @f : !cir.float
+ cir.global external @s128 = #cir.int<0> : !s128i
+ cir.global external @u128 = #cir.int<0> : !u128i
+ cir.global external @wc = #cir.int<0> : !s32i
+ cir.global external @c8 = #cir.int<0> : !u8i
+ cir.global external @c16 = #cir.int<0> : !u16i
+ cir.global external @c32 = #cir.int<0> : !u32i
+ cir.global external @sb20 = #cir.int<0> : !cir.int<s, 20>
+ cir.global external @ub48 = #cir.int<0> : !cir.int<u, 48>
+ cir.global external @f16 = #cir.fp<0.000000e+00> : !cir.f16
+ cir.global external @bf16 = #cir.fp<0.000000e+00> : !cir.bf16
+ cir.global external @f = #cir.fp<0.000000e+00> : !cir.float
cir.global external @d = #cir.fp<1.250000e+00> : !cir.double
- cir.global external @ld : !cir.long_double<!cir.f80>
- cir.global external @f128 : !cir.f128
- cir.global external @vp : !cir.ptr<!void>
+ cir.global external @ld = #cir.fp<0.000000e+00> : !cir.long_double<!cir.f80>
+ cir.global external @f128 = #cir.fp<0.000000e+00> : !cir.f128
+ cir.global external @vp = #cir.ptr<null> : !cir.ptr<!void>
cir.global external @ip = #cir.ptr<null> : !cir.ptr<!s32i>
- cir.global external @dp : !cir.ptr<!cir.double>
- cir.global external @cpp : !cir.ptr<!cir.ptr<!s8i>>
- cir.global external @fp : !cir.ptr<!cir.func<()>>
+ cir.global external @dp = #cir.ptr<null> : !cir.ptr<!cir.double>
+ cir.global external @cpp = #cir.ptr<null> : !cir.ptr<!cir.ptr<!s8i>>
+ cir.global external @fp = #cir.ptr<null> : !cir.ptr<!cir.func<()>>
cir.global external @fpii = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i) -> !s32i>>
- cir.global external @fpvar : !cir.ptr<!cir.func<(!s32i, ...)>>
+ cir.global external @fpvar = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i, ...)>>
}
-// CHECK: cir.global external @c : !s8i
-// CHECK: cir.global external @sc : !s8i
-// CHECK: cir.global external @uc : !u8i
-// CHECK: cir.global external @ss : !s16i
-// CHECK: cir.global external @us = #cir.int<100>
-// CHECK: cir.global external @si = #cir.int<42>
-// CHECK: cir.global external @ui : !u32i
-// CHECK: cir.global external @sl : !s64i
-// CHECK: cir.global external @ul : !u64i
-// CHECK: cir.global external @sll : !s64i
+// CHECK: cir.global external @c = #cir.int<0> : !s8i
+// CHECK: cir.global external @sc = #cir.int<0> : !s8i
+// CHECK: cir.global external @uc = #cir.int<0> : !u8i
+// CHECK: cir.global external @ss = #cir.int<0> : !s16i
+// CHECK: cir.global external @us = #cir.int<100> : !u16i
+// CHECK: cir.global external @si = #cir.int<42> : !s32i
+// CHECK: cir.global external @ui = #cir.int<0> : !u32i
+// CHECK: cir.global external @sl = #cir.int<0> : !s64i
+// CHECK: cir.global external @ul = #cir.int<0> : !u64i
+// CHECK: cir.global external @sll = #cir.int<0> : !s64i
// CHECK: cir.global external @ull = #cir.int<123456> : !u64i
-// CHECK: cir.global external @s128 : !s128i
-// CHECK: cir.global external @u128 : !u128i
-// CHECK: cir.global external @wc : !s32i
-// CHECK: cir.global external @c8 : !u8i
-// CHECK: cir.global external @c16 : !u16i
-// CHECK: cir.global external @c32 : !u32i
-// CHECK: cir.global external @sb20 : !cir.int<s, 20>
-// CHECK: cir.global external @ub48 : !cir.int<u, 48>
-// CHECK: cir.global external @f16 : !cir.f16
-// CHECK: cir.global external @bf16 : !cir.bf16
-// CHECK: cir.global external @f : !cir.float
+// CHECK: cir.global external @s128 = #cir.int<0> : !s128i
+// CHECK: cir.global external @u128 = #cir.int<0> : !u128i
+// CHECK: cir.global external @wc = #cir.int<0> : !s32i
+// CHECK: cir.global external @c8 = #cir.int<0> : !u8i
+// CHECK: cir.global external @c16 = #cir.int<0> : !u16i
+// CHECK: cir.global external @c32 = #cir.int<0> : !u32i
+// CHECK: cir.global external @sb20 = #cir.int<0> : !cir.int<s, 20>
+// CHECK: cir.global external @ub48 = #cir.int<0> : !cir.int<u, 48>
+// CHECK: cir.global external @f16 = #cir.fp<0.000000e+00> : !cir.f16
+// CHECK: cir.global external @bf16 = #cir.fp<0.000000e+00> : !cir.bf16
+// CHECK: cir.global external @f = #cir.fp<0.000000e+00> : !cir.float
// CHECK: cir.global external @d = #cir.fp<1.250000e+00> : !cir.double
-// CHECK: cir.global external @ld : !cir.long_double<!cir.f80>
-// CHECK: cir.global external @f128 : !cir.f128
-// CHECK: cir.global external @vp : !cir.ptr<!void>
+// CHECK: cir.global external @ld = #cir.fp<0.000000e+00> : !cir.long_double<!cir.f80>
+// CHECK: cir.global external @f128 = #cir.fp<0.000000e+00> : !cir.f128
+// CHECK: cir.global external @vp = #cir.ptr<null> : !cir.ptr<!void>
// CHECK: cir.global external @ip = #cir.ptr<null> : !cir.ptr<!s32i>
-// CHECK: cir.global external @dp : !cir.ptr<!cir.double>
-// CHECK: cir.global external @cpp : !cir.ptr<!cir.ptr<!s8i>>
-// CHECK: cir.global external @fp : !cir.ptr<!cir.func<()>>
+// CHECK: cir.global external @dp = #cir.ptr<null> : !cir.ptr<!cir.double>
+// CHECK: cir.global external @cpp = #cir.ptr<null> : !cir.ptr<!cir.ptr<!s8i>>
+// CHECK: cir.global external @fp = #cir.ptr<null> : !cir.ptr<!cir.func<()>>
// CHECK: cir.global external @fpii = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i) -> !s32i>>
-// CHECK: cir.global external @fpvar : !cir.ptr<!cir.func<(!s32i, ...)>>
+// CHECK: cir.global external @fpvar = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i, ...)>>
diff --git a/clang/test/CIR/Lowering/array.cpp b/clang/test/CIR/Lowering/array.cpp
index 335042ca68f4c..9bd3464dc3145 100644
--- a/clang/test/CIR/Lowering/array.cpp
+++ b/clang/test/CIR/Lowering/array.cpp
@@ -2,33 +2,33 @@
// RUN: FileCheck --input-file=%t-cir.ll %s
int a[10];
-// CHECK: @a = dso_local global [10 x i32] zeroinitializer
+// CHECK: @a = global [10 x i32] zeroinitializer
int aa[10][5];
-// CHECK: @aa = dso_local global [10 x [5 x i32]] zeroinitializer
+// CHECK: @aa = global [10 x [5 x i32]] zeroinitializer
int c[10] = {};
-// CHECK: @c = dso_local global [10 x i32] zeroinitializer
+// CHECK: @c = global [10 x i32] zeroinitializer
int d[3] = {1, 2, 3};
-// CHECK: @d = dso_local global [3 x i32] [i32 1, i32 2, i32 3]
+// CHECK: @d = global [3 x i32] [i32 1, i32 2, i32 3]
int dd[3][2] = {{1, 2}, {3, 4}, {5, 6}};
-// CHECK: @dd = dso_local global [3 x [2 x i32]] [
+// CHECK: @dd = global [3 x [2 x i32]] [
// CHECK: [2 x i32] [i32 1, i32 2], [2 x i32]
// CHECK: [i32 3, i32 4], [2 x i32] [i32 5, i32 6]]
int e[10] = {1, 2};
-// CHECK: @e = dso_local global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]
+// CHECK: @e = global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]
int f[5] = {1, 2};
-// CHECK: @f = dso_local global [5 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0]
+// CHECK: @f = global [5 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0]
extern int b[10];
-// CHECK: @b = external dso_local global [10 x i32]
+// CHECK: @b = external global [10 x i32]
extern int bb[10][5];
-// CHECK: @bb = external dso_local global [10 x [5 x i32]]
+// CHECK: @bb = external global [10 x [5 x i32]]
// This function is only here to make sure the external globals are emitted.
void reference_externs() {
diff --git a/clang/test/CIR/Lowering/global-var-simple.cpp b/clang/test/CIR/Lowering/global-var-simple.cpp
index 5ff1c3ee96ee2..ecb766694ab50 100644
--- a/clang/test/CIR/Lowering/global-var-simple.cpp
+++ b/clang/test/CIR/Lowering/global-var-simple.cpp
@@ -8,133 +8,133 @@
// with ClangIR enabled and will be fixed in a future patch.
char c;
-// CHECK: @c = dso_local global i8 0, align 1
+// CHECK: @c = global i8 0, align 1
// OGCG: @c = global i8 0, align 1
signed char sc;
-// CHECK: @sc = dso_local global i8 0, align 1
+// CHECK: @sc = global i8 0, align 1
// OGCG: @sc = global i8 0, align 1
unsigned char uc;
-// CHECK: @uc = dso_local global i8 0, align 1
+// CHECK: @uc = global i8 0, align 1
// OGCG: @uc = global i8 0, align 1
short ss;
-// CHECK: @ss = dso_local global i16 0, align 2
+// CHECK: @ss = global i16 0, align 2
// OGCG: @ss = global i16 0, align 2
unsigned short us = 100;
-// CHECK: @us = dso_local global i16 100, align 2
+// CHECK: @us = global i16 100, align 2
// OGCG: @us = global i16 100, align 2
int si = 42;
-// CHECK: @si = dso_local global i32 42, align 4
+// CHECK: @si = global i32 42, align 4
// OGCG: @si = global i32 42, align 4
unsigned ui;
-// CHECK: @ui = dso_local global i32 0, align 4
+// CHECK: @ui = global i32 0, align 4
// OGCG: @ui = global i32 0, align 4
long sl;
-// CHECK: @sl = dso_local global i64 0, align 8
+// CHECK: @sl = global i64 0, align 8
// OGCG: @sl = global i64 0, align 8
unsigned long ul;
-// CHECK: @ul = dso_local global i64 0, align 8
+// CHECK: @ul = global i64 0, align 8
// OGCG: @ul = global i64 0, align 8
long long sll;
-// CHECK: @sll = dso_local global i64 0, align 8
+// CHECK: @sll = global i64 0, align 8
// OGCG: @sll = global i64 0, align 8
unsigned long long ull = 123456;
-// CHECK: @ull = dso_local global i64 123456, align 8
+// CHECK: @ull = global i64 123456, align 8
// OGCG: @ull = global i64 123456, align 8
__int128 s128;
-// CHECK: @s128 = dso_local global i128 0, align 16
+// CHECK: @s128 = global i128 0, align 16
// OGCG: @s128 = global i128 0, align 16
unsigned __int128 u128;
-// CHECK: @u128 = dso_local global i128 0, align 16
+// CHECK: @u128 = global i128 0, align 16
// OGCG: @u128 = global i128 0, align 16
wchar_t wc;
-// CHECK: @wc = dso_local global i32 0, align 4
+// CHECK: @wc = global i32 0, align 4
// OGCG: @wc = global i32 0, align 4
char8_t c8;
-// CHECK: @c8 = dso_local global i8 0, align 1
+// CHECK: @c8 = global i8 0, align 1
// OGCG: @c8 = global i8 0, align 1
char16_t c16;
-// CHECK: @c16 = dso_local global i16 0, align 2
+// CHECK: @c16 = global i16 0, align 2
// OGCG: @c16 = global i16 0, align 2
char32_t c32;
-// CHECK: @c32 = dso_local global i32 0, align 4
+// CHECK: @c32 = global i32 0, align 4
// OGCG: @c32 = global i32 0, align 4
_BitInt(20) sb20;
-// CHECK: @sb20 = dso_local global i20 0, align 4
+// CHECK: @sb20 = global i20 0, align 4
// OGCG: @sb20 = global i32 0, align 4
unsigned _BitInt(48) ub48;
-// CHECK: @ub48 = dso_local global i48 0, align 8
+// CHECK: @ub48 = global i48 0, align 8
// OGCG: @ub48 = global i64 0, align 8
bool boolfalse = false;
-// CHECK: @boolfalse = dso_local global i8 0, align 1
+// CHECK: @boolfalse = global i8 0, align 1
// OGCG: @boolfalse = global i8 0, align 1
_Float16 f16;
-// CHECK: @f16 = dso_local global half 0xH0000, align 2
+// CHECK: @f16 = global half 0xH0000, align 2
// OGCG: @f16 = global half 0xH0000, align 2
__bf16 bf16;
-// CHECK: @bf16 = dso_local global bfloat 0xR0000, align 2
+// CHECK: @bf16 = global bfloat 0xR0000, align 2
// OGCG: @bf16 = global bfloat 0xR0000, align 2
float f;
-// CHECK: @f = dso_local global float 0.000000e+00, align 4
+// CHECK: @f = global float 0.000000e+00, align 4
// OGCG: @f = global float 0.000000e+00, align 4
double d = 1.25;
-// CHECK: @d = dso_local global double 1.250000e+00, align 8
+// CHECK: @d = global double 1.250000e+00, align 8
// OGCG: @d = global double 1.250000e+00, align 8
long double ld;
-// CHECK: @ld = dso_local global x86_fp80 0xK00000000000000000000, align 16
+// CHECK: @ld = global x86_fp80 0xK00000000000000000000, align 16
// OGCG: @ld = global x86_fp80 0xK00000000000000000000, align 16
__float128 f128;
-// CHECK: @f128 = dso_local global fp128 0xL00000000000000000000000000000000, align 16
+// CHECK: @f128 = global fp128 0xL00000000000000000000000000000000, align 16
// OGCG: @f128 = global fp128 0xL00000000000000000000000000000000, align 16
void *vp;
-// CHECK: @vp = dso_local global ptr null, align 8
+// CHECK: @vp = global ptr null, align 8
// OGCG: @vp = global ptr null, align 8
int *ip = 0;
-// CHECK: @ip = dso_local global ptr null, align 8
+// CHECK: @ip = global ptr null, align 8
// OGCG: @ip = global ptr null, align 8
double *dp;
-// CHECK: @dp = dso_local global ptr null, align 8
+// CHECK: @dp = global ptr null, align 8
// OGCG: @dp = global ptr null, align 8
char **cpp;
-// CHECK: @cpp = dso_local global ptr null, align 8
+// CHECK: @cpp = global ptr null, align 8
// OGCG: @cpp = global ptr null, align 8
void (*fp)();
-// CHECK: @fp = dso_local global ptr null, align 8
+// CHECK: @fp = global ptr null, align 8
// OGCG: @fp = global ptr null, align 8
int (*fpii)(int) = 0;
-// CHECK: @fpii = dso_local global ptr null, align 8
+// CHECK: @fpii = global ptr null, align 8
// OGCG: @fpii = global ptr null, align 8
void (*fpvar)(int, ...);
-// CHECK: @fpvar = dso_local global ptr null, align 8
+// CHECK: @fpvar = global ptr null, align 8
// OGCG: @fpvar = global ptr null, align 8
diff --git a/clang/test/CIR/Lowering/hello.c b/clang/test/CIR/Lowering/hello.c
index 42552f796914a..e462cb58ae269 100644
--- a/clang/test/CIR/Lowering/hello.c
+++ b/clang/test/CIR/Lowering/hello.c
@@ -4,15 +4,12 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
// RUN: FileCheck %s -check-prefix=OGCG --input-file %t.ll
-// Note: The differences between CHECK and OGCG represent incorrect IR lowering
-// with ClangIR enabled and will be fixed in a future patch.
-
int b = 2;
-// CHECK: @b = dso_local global i32 2, align 4
+// CHECK: @b = global i32 2, align 4
// OGCG: @b = global i32 2, align 4
int a;
-// CHECK: @a = dso_local global i32 0, align 4
+// CHECK: @a = global i32 0, align 4
// OGCG: @a = global i32 0, align 4
diff --git a/clang/test/CIR/global-var-linkage.cpp b/clang/test/CIR/global-var-linkage.cpp
index 7256583432736..1c0c1b121427f 100644
--- a/clang/test/CIR/global-var-linkage.cpp
+++ b/clang/test/CIR/global-var-linkage.cpp
@@ -6,27 +6,27 @@
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
// RUN: FileCheck %s -check-prefix=OGCG --input-file %t.ll
-// Note: The differences between CHECK and OGCG represent incorrect IR lowering
-// with ClangIR enabled and will be fixed in a future patch.
-
int aaaa;
// CIR: cir.global external @aaaa
-// LLVM: @aaaa = dso_local global i32 0
+// LLVM: @aaaa = global i32 0
// OGCG: @aaaa = global i32 0
[[gnu::selectany]] int dddd;
// CIR: cir.global weak_odr @dddd
-// LLVM: @dddd = weak_odr dso_local global i32 0
+// 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
// OGCG: @dddd = weak_odr global i32 0, comdat
static int bbbb;
-// CIR: cir.global internal @_ZL4bbbb
+// CIR: cir.global "private" internal @_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 dso_local global i32 0
+// LLVM: @cccc = linkonce_odr global i32 0
// OGCG: @cccc = linkonce_odr global i32 0
// Force the global variables to be emitted
diff --git a/clang/test/CIR/global-var-simple.cpp b/clang/test/CIR/global-var-simple.cpp
index 9a52925303504..4608089058fb4 100644
--- a/clang/test/CIR/global-var-simple.cpp
+++ b/clang/test/CIR/global-var-simple.cpp
@@ -68,7 +68,7 @@ __bf16 bf16;
// CHECK: cir.global external @bf16 = #cir.fp<0.000000e+00> : !cir.bf16
float f;
-// CHECK: cir.global external @f = #cir.fp<0.000000e+00> : !cir.float
+// CHECK: cir.global external @f = #cir.fp<0.000000e+00> : !cir.float
double d = 1.25;
// CHECK: cir.global external @d = #cir.fp<1.250000e+00> : !cir.double
More information about the cfe-commits
mailing list