[clang] [CIR] Add support for global linkage and visibility (PR #141973)
Andy Kaylor via cfe-commits
cfe-commits at lists.llvm.org
Fri May 30 11:04:55 PDT 2025
https://github.com/andykaylor updated https://github.com/llvm/llvm-project/pull/141973
>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 1/3] [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
>From bbd6992cc4bd8b978a33318da6d7166c64a195f6 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Fri, 30 May 2025 10:29:11 -0700
Subject: [PATCH 2/3] Address review feedback
---
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 13 ++++++-------
clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 +-
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 8 ++++----
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 4 ++--
4 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index bddd7a825c505..ecbced05a5fdd 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -280,17 +280,16 @@ 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
+def CIR_VisibilityKind : I32EnumAttr<"VisibilityKind", "C/C++ visibility", [
+ I32EnumAttrCase<"Default", 1, "default">,
+ I32EnumAttrCase<"Hidden", 2, "hidden">,
+ I32EnumAttrCase<"Protected", 3, "protected">
]> {
+ let genSpecializedAttr = 0;
let cppNamespace = "::cir";
}
-def VisibilityAttr : CIR_Attr<"Visibility", "visibility"> {
+def CIR_VisibilityAttr : CIR_Attr<"Visibility", "visibility"> {
let summary = "Visibility attribute";
let description = [{
Visibility attributes.
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6637ad14091cc..2efc540dbed1f 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1653,7 +1653,7 @@ def GlobalOp : CIR_Op<"global",
// necessary Symbol's interface in terms of linkage instead.
let arguments = (ins SymbolNameAttr:$sym_name,
DefaultValuedAttr<
- VisibilityAttr,
+ CIR_VisibilityAttr,
"VisibilityKind::Default"
>:$global_visibility,
OptionalAttr<StrAttr>:$sym_visibility,
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 0d315aa277140..7e9b98f0f5fde 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -1103,7 +1103,7 @@ static bool shouldAssumeDSOLocal(const CIRGenModule &cgm,
assert(!cir::MissingFeatures::opGlobalDLLImportExport());
const llvm::Triple &tt = cgm.getTriple();
- const auto &cgOpts = cgm.getCodeGenOpts();
+ const CodeGenOptions &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
@@ -1135,7 +1135,7 @@ static bool shouldAssumeDSOLocal(const CIRGenModule &cgm,
return false;
llvm::Reloc::Model rm = cgOpts.RelocationModel;
- const auto &lOpts = cgm.getLangOpts();
+ const LangOptions &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
@@ -1144,8 +1144,8 @@ static bool shouldAssumeDSOLocal(const CIRGenModule &cgm,
// PLT indirection).
if (!(isa<cir::FuncOp>(gv) && gv.canBenefitFromLocalAlias()))
return false;
- return !(cgm.getLangOpts().SemanticInterposition ||
- cgm.getLangOpts().HalfNoSemanticInterposition);
+ return !(lOpts.SemanticInterposition ||
+ lOpts.HalfNoSemanticInterposition);
}
// A definition cannot be preempted from an executable.
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 8f43d2564f472..c8ba4005f00e6 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -966,7 +966,7 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
const bool isConst = false;
assert(!cir::MissingFeatures::addressSpace());
const unsigned addrSpace = 0;
- const auto isDsoLocal = op.getDsolocal();
+ const bool isDsoLocal = op.getDsolocal();
assert(!cir::MissingFeatures::opGlobalThreadLocal());
const bool isThreadLocal = false;
const uint64_t alignment = op.getAlignment().value_or(0);
@@ -1020,7 +1020,7 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
const bool isConst = false;
assert(!cir::MissingFeatures::addressSpace());
const unsigned addrSpace = 0;
- const auto isDsoLocal = op.getDsolocal();
+ const bool isDsoLocal = op.getDsolocal();
assert(!cir::MissingFeatures::opGlobalThreadLocal());
const bool isThreadLocal = false;
const uint64_t alignment = op.getAlignment().value_or(0);
>From edf60eaeacdc1520b03a058e228f7bc31a335bf8 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Fri, 30 May 2025 11:04:38 -0700
Subject: [PATCH 3/3] Fix formatting
---
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 7e9b98f0f5fde..11c3bd4d7be84 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -1144,8 +1144,7 @@ static bool shouldAssumeDSOLocal(const CIRGenModule &cgm,
// PLT indirection).
if (!(isa<cir::FuncOp>(gv) && gv.canBenefitFromLocalAlias()))
return false;
- return !(lOpts.SemanticInterposition ||
- lOpts.HalfNoSemanticInterposition);
+ return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
}
// A definition cannot be preempted from an executable.
More information about the cfe-commits
mailing list