Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only test case I could find that reaches this requires OpenCL and AMDGCN support, but I think the code is straightforward enough to go in ahead of a test case.

}

setNonAliasAttributes(vd, gv);

Expand Down Expand Up @@ -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
Expand Down
103 changes: 103 additions & 0 deletions clang/test/CIR/CodeGen/no-common.c
Original file line number Diff line number Diff line change
@@ -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