Author: Andy Kaylor Date: 2025-11-18T14:51:23-08:00 New Revision: 3e499e9427e006a4204d1cb5b6eebe957844e06e
URL: https://github.com/llvm/llvm-project/commit/3e499e9427e006a4204d1cb5b6eebe957844e06e DIFF: https://github.com/llvm/llvm-project/commit/3e499e9427e006a4204d1cb5b6eebe957844e06e.diff LOG: [CIR] Add support for common linkage (#168613) Add support for marking global variables with common linkage. Added: clang/test/CIR/CodeGen/no-common.c Modified: clang/lib/CIR/CodeGen/CIRGenModule.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 4a82ea3121b60..b8e51f87d4045 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -883,8 +883,17 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd, // 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"); + if (linkage == cir::GlobalLinkageKind::CommonLinkage) { + // common vars aren't constant even if declared const. + gv.setConstant(false); + // Tentative definition of global variables may be initialized with + // non-zero null pointers. In this case they should have weak linkage + // since common linkage must have zero initializer and must not have + // explicit section therefore cannot have non-zero initial value. + std::optional<mlir::Attribute> initializer = gv.getInitialValue(); + if (initializer && !getBuilder().isNullValue(*initializer)) + gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage); + } setNonAliasAttributes(vd, gv); @@ -1238,10 +1247,8 @@ cir::GlobalLinkageKind CIRGenModule::getCIRLinkageForDeclarator( // linkage. if (!getLangOpts().CPlusPlus && isa<VarDecl>(dd) && !isVarDeclStrongDefinition(astContext, *this, cast<VarDecl>(dd), - getCodeGenOpts().NoCommon)) { - errorNYI(dd->getBeginLoc(), "common linkage", dd->getDeclKindName()); + getCodeGenOpts().NoCommon)) return cir::GlobalLinkageKind::CommonLinkage; - } // selectany symbols are externally visible, so use weak instead of // linkonce. MSVC optimizes away references to const selectany globals, so diff --git a/clang/test/CIR/CodeGen/no-common.c b/clang/test/CIR/CodeGen/no-common.c new file mode 100644 index 0000000000000..ce4c5fc0b3a33 --- /dev/null +++ b/clang/test/CIR/CodeGen/no-common.c @@ -0,0 +1,103 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -emit-cir -o %t-default.cir +// RUN: FileCheck --input-file=%t-default.cir %s -check-prefix=CIR-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fno-common -emit-cir -o %t-no-common.cir +// RUN: FileCheck --input-file=%t-no-common.cir %s -check-prefix=CIR-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fcommon -emit-cir -o %t-common.cir +// RUN: FileCheck --input-file=%t-common.cir %s -check-prefix=CIR-COMMON + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -emit-llvm -o %t-default-cir.ll +// RUN: FileCheck --input-file=%t-default-cir.ll %s -check-prefix=LLVM-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fno-common -emit-llvm -o %t-no-common-cir.ll +// RUN: FileCheck --input-file=%t-no-common-cir.ll %s -check-prefix=LLVM-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fcommon -emit-llvm -o %t-common-cir.ll +// RUN: FileCheck --input-file=%t-common-cir.ll %s -check-prefix=LLVM-COMMON + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o %t-default.ll +// RUN: FileCheck --input-file=%t-default.ll %s -check-prefix=OGCG-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -fno-common -emit-llvm -o %t-no-common.ll +// RUN: FileCheck --input-file=%t-no-common.ll %s -check-prefix=OGCG-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -fcommon -emit-llvm -o %t-common.ll +// RUN: FileCheck --input-file=%t-common.ll %s -check-prefix=OGCG-COMMON + +const int a = 42; +// CIR-DEFAULT: cir.global constant external @a = #cir.int<42> +// LLVM-DEFAULT: @a = constant i32 42 +// OGCG-DEFAULT: @a = constant i32 42 + +// CIR-COMMON: cir.global constant external @a +// LLVM-COMMON: @a = constant i32 42 +// OGCG-COMMON: @a = constant i32 42 + +const int b __attribute__((common)) = 42; +// CIR-DEFAULT: cir.global constant external @b = #cir.int<42> +// LLVM-DEFAULT: @b = constant i32 42 +// OGCG-DEFAULT: @b = constant i32 42 + +// CIR-COMMON: cir.global constant external @b = #cir.int<42> +// LLVM-COMMON: @b = constant i32 42 +// OGCG-COMMON: @b = constant i32 42 + +const int c __attribute__((nocommon)) = 42; +// CIR-DEFAULT: cir.global constant external @c = #cir.int<42> +// LLVM-DEFAULT: @c = constant i32 42 +// OGCG-DEFAULT: @c = constant i32 42 + +// CIR-COMMON: cir.global constant external @c = #cir.int<42> +// LLVM-COMMON: @c = constant i32 42 +// OGCG-COMMON: @c = constant i32 42 + +int d = 11; +// CIR-DEFAULT: cir.global external @d = #cir.int<11> +// LLVM-DEFAULT: @d = global i32 11 +// OGCG-DEFAULT: @d = global i32 11 + +// CIR-COMMON: cir.global external @d = #cir.int<11> +// LLVM-COMMON: @d = global i32 11 +// OGCG-COMMON: @d = global i32 11 + +int e; +// CIR-DEFAULT: cir.global external @e = #cir.int<0> +// LLVM-DEFAULT: @e = global i32 0 +// OGCG-DEFAULT: @e = global i32 0 + +// CIR-COMMON: cir.global common @e = #cir.int<0> +// LLVM-COMMON: @e = common global i32 0 +// OGCG-COMMON: @e = common global i32 0 + + +int f __attribute__((common)); +// CIR-DEFAULT: cir.global common @f = #cir.int<0> +// LLVM-DEFAULT: @f = common global i32 0 +// OGCG-DEFAULT: @f = common global i32 0 + +// CIR-COMMON: cir.global common @f +// LLVM-COMMON: @f = common global i32 0 +// OGCG-COMMON: @f = common global i32 0 + +int g __attribute__((nocommon)); +// CIR-DEFAULT: cir.global external @g = #cir.int<0> +// LLVM-DEFAULT: @g = global i32 +// OGCG-DEFAULT: @g = global i32 0 + +// CIR-COMMON: cir.global external @g = #cir.int<0> +// LLVM-COMMON: @g = global i32 0 +// OGCG-COMMON: @g = global i32 0 + +const int h; +// CIR-DEFAULT: cir.global constant external @h = #cir.int<0> +// LLVM-DEFAULT: @h = constant i32 +// OGCG-DEFAULT: @h = constant i32 0 + +// CIR-COMMON: cir.global common @h = #cir.int<0> +// LLVM-COMMON: @h = common global i32 0 +// OGCG-COMMON: @h = common global i32 0 + +typedef void* (*fn_t)(long a, long b, char *f, int c); +fn_t ABC __attribute__ ((nocommon)); +// CIR-DEFAULT: cir.global external @ABC = #cir.ptr<null> +// LLVM-DEFAULT: @ABC = global ptr null +// OGCG-DEFAULT: @ABC = global ptr null + +// CIR-COMMON: cir.global external @ABC = #cir.ptr<null> +// LLVM-COMMON: @ABC = global ptr null +// OGCG-COMMON: @ABC = global ptr null _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
