Skip to content

Commit 08190e5

Browse files
authored
[CIR] Fix dso_local and comdat handling for global vars (#142214)
This change adds extra processing of global variable definitions to correctly set the dso_local and comdat attributes.
1 parent 7bf5862 commit 08190e5

File tree

9 files changed

+191
-32
lines changed

9 files changed

+191
-32
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,18 @@ struct MissingFeatures {
3434
static bool opGlobalThreadLocal() { return false; }
3535
static bool opGlobalConstant() { return false; }
3636
static bool opGlobalWeakRef() { return false; }
37-
static bool opGlobalLinkage() { return false; }
3837
static bool opGlobalUnnamedAddr() { return false; }
3938
static bool opGlobalSection() { return false; }
4039
static bool opGlobalVisibility() { return false; }
4140
static bool opGlobalDLLImportExport() { return false; }
4241
static bool opGlobalPartition() { return false; }
42+
static bool opGlobalUsedOrCompilerUsed() { return false; }
4343

4444
static bool supportIFuncAttr() { return false; }
4545
static bool supportVisibility() { return false; }
4646
static bool hiddenVisibility() { return false; }
4747
static bool protectedVisibility() { return false; }
48+
static bool defaultVisibility() { return false; }
4849

4950
// Load/store attributes
5051
static bool opLoadStoreThreadLocal() { return false; }
@@ -77,6 +78,9 @@ struct MissingFeatures {
7778
static bool opFuncLinkage() { return false; }
7879
static bool opFuncVisibility() { return false; }
7980
static bool opFuncNoProto() { return false; }
81+
static bool opFuncCPUAndFeaturesAttributes() { return false; }
82+
static bool opFuncSection() { return false; }
83+
static bool opFuncSetComdat() { return false; }
8084

8185
// CallOp handling
8286
static bool opCallBuiltinFunc() { return false; }
@@ -136,7 +140,6 @@ struct MissingFeatures {
136140
// Misc
137141
static bool cxxABI() { return false; }
138142
static bool cirgenABIInfo() { return false; }
139-
static bool cirgenTargetInfo() { return false; }
140143
static bool abiArgInfo() { return false; }
141144
static bool tryEmitAsConstant() { return false; }
142145
static bool constructABIArgDirectExtend() { return false; }
@@ -199,6 +202,7 @@ struct MissingFeatures {
199202
static bool cleanupsToDeactivate() { return false; }
200203
static bool stackBase() { return false; }
201204
static bool deferredDecls() { return false; }
205+
static bool setTargetAttributes() { return false; }
202206

203207
// Missing types
204208
static bool dataMemberType() { return false; }

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,36 @@ cir::GlobalOp CIRGenModule::createGlobalOp(CIRGenModule &cgm,
317317
return g;
318318
}
319319

320+
void CIRGenModule::setCommonAttributes(GlobalDecl gd, mlir::Operation *gv) {
321+
const Decl *d = gd.getDecl();
322+
if (isa_and_nonnull<NamedDecl>(d))
323+
setGVProperties(gv, dyn_cast<NamedDecl>(d));
324+
assert(!cir::MissingFeatures::defaultVisibility());
325+
assert(!cir::MissingFeatures::opGlobalUsedOrCompilerUsed());
326+
}
327+
328+
void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
329+
setCommonAttributes(gd, op);
330+
331+
assert(!cir::MissingFeatures::opGlobalUsedOrCompilerUsed());
332+
assert(!cir::MissingFeatures::opGlobalSection());
333+
assert(!cir::MissingFeatures::opFuncCPUAndFeaturesAttributes());
334+
assert(!cir::MissingFeatures::opFuncSection());
335+
336+
assert(!cir::MissingFeatures::setTargetAttributes());
337+
}
338+
339+
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd) {
340+
// Set linkage and visibility in case we never see a definition.
341+
LinkageInfo lv = nd->getLinkageAndVisibility();
342+
// Don't set internal linkage on declarations.
343+
// "extern_weak" is overloaded in LLVM; we probably should have
344+
// separate linkage types for this.
345+
if (isExternallyVisible(lv.getLinkage()) &&
346+
(nd->hasAttr<WeakAttr>() || nd->isWeakImported()))
347+
gv.setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
348+
}
349+
320350
/// If the specified mangled name is not in the module,
321351
/// create and return an mlir GlobalOp with the specified type (TODO(cir):
322352
/// address space).
@@ -387,7 +417,8 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
387417

388418
gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
389419
assert(!cir::MissingFeatures::opGlobalConstant());
390-
assert(!cir::MissingFeatures::opGlobalLinkage());
420+
421+
setLinkageForGV(gv, d);
391422

392423
if (d->getTLSKind())
393424
errorNYI(d->getSourceRange(), "thread local global variable");
@@ -555,8 +586,6 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
555586
errorNYI(vd->getSourceRange(), "annotate global variable");
556587
}
557588

558-
assert(!cir::MissingFeatures::opGlobalLinkage());
559-
560589
if (langOpts.CUDA) {
561590
errorNYI(vd->getSourceRange(), "CUDA global variable");
562591
}
@@ -577,6 +606,12 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
577606
assert(!cir::MissingFeatures::opGlobalDLLImportExport());
578607
if (linkage == cir::GlobalLinkageKind::CommonLinkage)
579608
errorNYI(initExpr->getSourceRange(), "common linkage");
609+
610+
setNonAliasAttributes(vd, gv);
611+
612+
assert(!cir::MissingFeatures::opGlobalThreadLocal());
613+
614+
maybeSetTrivialComdat(*vd, gv);
580615
}
581616

582617
void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd,
@@ -668,6 +703,15 @@ static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d) {
668703
llvm_unreachable("No such linkage");
669704
}
670705

706+
void CIRGenModule::maybeSetTrivialComdat(const Decl &d, mlir::Operation *op) {
707+
if (!shouldBeInCOMDAT(*this, d))
708+
return;
709+
if (auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op))
710+
globalOp.setComdat(true);
711+
712+
assert(!cir::MissingFeatures::opFuncSetComdat());
713+
}
714+
671715
// TODO(CIR): this could be a common method between LLVM codegen.
672716
static bool isVarDeclStrongDefinition(const ASTContext &astContext,
673717
CIRGenModule &cgm, const VarDecl *vd,
@@ -830,10 +874,10 @@ CIRGenModule::getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant) {
830874
return getCIRLinkageForDeclarator(vd, linkage, isConstant);
831875
}
832876

833-
static cir::GlobalOp generateStringLiteral(mlir::Location loc,
834-
mlir::TypedAttr c, CIRGenModule &cgm,
835-
StringRef globalName,
836-
CharUnits alignment) {
877+
static cir::GlobalOp
878+
generateStringLiteral(mlir::Location loc, mlir::TypedAttr c,
879+
cir::GlobalLinkageKind lt, CIRGenModule &cgm,
880+
StringRef globalName, CharUnits alignment) {
837881
assert(!cir::MissingFeatures::addressSpace());
838882

839883
// Create a global variable for this string
@@ -843,7 +887,8 @@ static cir::GlobalOp generateStringLiteral(mlir::Location loc,
843887

844888
// Set up extra information and add to the module
845889
gv.setAlignmentAttr(cgm.getSize(alignment));
846-
assert(!cir::MissingFeatures::opGlobalLinkage());
890+
gv.setLinkageAttr(
891+
cir::GlobalLinkageKindAttr::get(cgm.getBuilder().getContext(), lt));
847892
assert(!cir::MissingFeatures::opGlobalThreadLocal());
848893
assert(!cir::MissingFeatures::opGlobalUnnamedAddr());
849894
CIRGenModule::setInitializer(gv, c);
@@ -907,7 +952,8 @@ cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
907952
mlir::Location loc = getLoc(s->getSourceRange());
908953
auto typedC = llvm::cast<mlir::TypedAttr>(c);
909954
cir::GlobalOp gv =
910-
generateStringLiteral(loc, typedC, *this, uniqueName, alignment);
955+
generateStringLiteral(loc, typedC, cir::GlobalLinkageKind::PrivateLinkage,
956+
*this, uniqueName, alignment);
911957
setDSOLocal(static_cast<mlir::Operation *>(gv));
912958

913959
assert(!cir::MissingFeatures::sanitizers());

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ class CIRGenModule : public CIRGenTypeCache {
149149
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s,
150150
llvm::StringRef name = ".str");
151151

152+
/// Set attributes which are common to any form of a global definition (alias,
153+
/// Objective-C method, function, global variable).
154+
///
155+
/// NOTE: This should only be called for definitions.
156+
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op);
157+
152158
const TargetCIRGenInfo &getTargetCIRGenInfo();
153159

154160
/// Helpers to convert the presumed location of Clang's SourceLocation to an
@@ -209,6 +215,7 @@ class CIRGenModule : public CIRGenTypeCache {
209215
void emitTentativeDefinition(const VarDecl *d);
210216

211217
bool supportsCOMDAT() const;
218+
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op);
212219

213220
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value);
214221

@@ -285,6 +292,8 @@ class CIRGenModule : public CIRGenTypeCache {
285292
// An ordered map of canonical GlobalDecls to their mangled names.
286293
llvm::MapVector<clang::GlobalDecl, llvm::StringRef> mangledDeclNames;
287294
llvm::StringMap<clang::GlobalDecl, llvm::BumpPtrAllocator> manglings;
295+
296+
void setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op);
288297
};
289298
} // namespace CIRGen
290299

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -969,13 +969,13 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
969969
const uint64_t alignment = op.getAlignment().value_or(0);
970970
const mlir::LLVM::Linkage linkage = convertLinkage(op.getLinkage());
971971
const StringRef symbol = op.getSymName();
972+
mlir::SymbolRefAttr comdatAttr = getComdatAttr(op, rewriter);
972973

973974
SmallVector<mlir::NamedAttribute> attributes;
974975
mlir::LLVM::GlobalOp newGlobalOp =
975976
rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
976977
op, llvmType, isConst, linkage, symbol, nullptr, alignment, addrSpace,
977-
isDsoLocal, isThreadLocal,
978-
/*comdat=*/mlir::SymbolRefAttr(), attributes);
978+
isDsoLocal, isThreadLocal, comdatAttr, attributes);
979979
newGlobalOp.getRegion().emplaceBlock();
980980
rewriter.setInsertionPointToEnd(newGlobalOp.getInitializerBlock());
981981
}
@@ -1024,6 +1024,7 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
10241024
const mlir::LLVM::Linkage linkage = convertLinkage(op.getLinkage());
10251025
const StringRef symbol = op.getSymName();
10261026
SmallVector<mlir::NamedAttribute> attributes;
1027+
mlir::SymbolRefAttr comdatAttr = getComdatAttr(op, rewriter);
10271028

10281029
if (init.has_value()) {
10291030
if (mlir::isa<cir::FPAttr, cir::IntAttr, cir::BoolAttr>(init.value())) {
@@ -1054,12 +1055,33 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
10541055
// Rewrite op.
10551056
rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
10561057
op, llvmType, isConst, linkage, symbol, init.value_or(mlir::Attribute()),
1057-
alignment, addrSpace, isDsoLocal, isThreadLocal,
1058-
/*comdat=*/mlir::SymbolRefAttr(), attributes);
1059-
1058+
alignment, addrSpace, isDsoLocal, isThreadLocal, comdatAttr, attributes);
10601059
return mlir::success();
10611060
}
10621061

1062+
mlir::SymbolRefAttr
1063+
CIRToLLVMGlobalOpLowering::getComdatAttr(cir::GlobalOp &op,
1064+
mlir::OpBuilder &builder) const {
1065+
if (!op.getComdat())
1066+
return mlir::SymbolRefAttr{};
1067+
1068+
mlir::ModuleOp module = op->getParentOfType<mlir::ModuleOp>();
1069+
mlir::OpBuilder::InsertionGuard guard(builder);
1070+
StringRef comdatName("__llvm_comdat_globals");
1071+
if (!comdatOp) {
1072+
builder.setInsertionPointToStart(module.getBody());
1073+
comdatOp =
1074+
builder.create<mlir::LLVM::ComdatOp>(module.getLoc(), comdatName);
1075+
}
1076+
1077+
builder.setInsertionPointToStart(&comdatOp.getBody().back());
1078+
auto selectorOp = builder.create<mlir::LLVM::ComdatSelectorOp>(
1079+
comdatOp.getLoc(), op.getSymName(), mlir::LLVM::comdat::Comdat::Any);
1080+
return mlir::SymbolRefAttr::get(
1081+
builder.getContext(), comdatName,
1082+
mlir::FlatSymbolRefAttr::get(selectorOp.getSymNameAttr()));
1083+
}
1084+
10631085
mlir::LogicalResult CIRToLLVMSwitchFlatOpLowering::matchAndRewrite(
10641086
cir::SwitchFlatOp op, OpAdaptor adaptor,
10651087
mlir::ConversionPatternRewriter &rewriter) const {

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define CLANG_CIR_LOWERTOLLVM_H
1414

1515
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
16+
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
1617
#include "mlir/Transforms/DialectConversion.h"
1718
#include "clang/CIR/Dialect/IR/CIRDialect.h"
1819

@@ -192,6 +193,10 @@ class CIRToLLVMGlobalOpLowering
192193

193194
void setupRegionInitializedLLVMGlobalOp(
194195
cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const;
196+
197+
mutable mlir::LLVM::ComdatOp comdatOp = nullptr;
198+
mlir::SymbolRefAttr getComdatAttr(cir::GlobalOp &op,
199+
mlir::OpBuilder &builder) const;
195200
};
196201

197202
class CIRToLLVMUnaryOpLowering

clang/test/CIR/CodeGen/dso-local.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// This test is copied from clang/test/CodeGen/dso-local-executable.c with
2+
// unsupported targets, thread_local variables, and function checks removed.
3+
4+
// These are here so we find this test when grepping for missing features.
5+
// cir::MissingFeatures::opGlobalThreadLocal()
6+
// cir::MissingFeatures::opFuncDsoLocal()
7+
8+
/// Static relocation model defaults to -fdirect-access-external-data and sets
9+
/// dso_local on most global objects.
10+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -mrelocation-model static %s -o - | FileCheck --check-prefix=STATIC %s
11+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -mrelocation-model static -fdirect-access-external-data %s -o - | FileCheck --check-prefix=STATIC %s
12+
// STATIC: @baz = dso_local global i32 42
13+
// STATIC-NEXT: @import_var = external dso_local global i32
14+
// STATIC-NEXT: @weak_bar = extern_weak dso_local global i32
15+
// STATIC-NEXT: @bar = external dso_local global i32
16+
17+
/// If -fno-direct-access-external-data is set, drop dso_local from global variable
18+
/// declarations.
19+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -mrelocation-model static -fno-direct-access-external-data %s -o - | FileCheck --check-prefix=STATIC-INDIRECT %s
20+
// STATIC-INDIRECT: @baz = dso_local global i32 42
21+
// STATIC-INDIRECT-NEXT: @import_var = external global i32
22+
// STATIC-INDIRECT-NEXT: @weak_bar = extern_weak global i32
23+
// STATIC-INDIRECT-NEXT: @bar = external global i32
24+
25+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -pic-level 1 -pic-is-pie %s -o - | FileCheck --check-prefix=PIE %s
26+
// PIE: @baz = dso_local global i32 42
27+
// PIE-NEXT: @import_var = external global i32
28+
// PIE-NEXT: @weak_bar = extern_weak global i32
29+
// PIE-NEXT: @bar = external global i32
30+
31+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -pic-level 1 -pic-is-pie -fdirect-access-external-data %s -o - | FileCheck --check-prefix=PIE-DIRECT %s
32+
// PIE-DIRECT: @baz = dso_local global i32 42
33+
// PIE-DIRECT-NEXT: @import_var = external dso_local global i32
34+
// PIE-DIRECT-NEXT: @weak_bar = extern_weak global i32
35+
// PIE-DIRECT-NEXT: @bar = external dso_local global i32
36+
37+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -mrelocation-model static -fno-plt %s -o - | FileCheck --check-prefix=NOPLT %s
38+
// NOPLT: @baz = dso_local global i32 42
39+
// NOPLT-NEXT: @import_var = external dso_local global i32
40+
// NOPLT-NEXT: @weak_bar = extern_weak dso_local global i32
41+
// NOPLT-NEXT: @bar = external dso_local global i32
42+
43+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -fno-plt -pic-level 1 -pic-is-pie -fdirect-access-external-data %s -o - | FileCheck --check-prefix=PIE-DIRECT-NOPLT %s
44+
// PIE-DIRECT-NOPLT: @baz = dso_local global i32 42
45+
// PIE-DIRECT-NOPLT-NEXT: @import_var = external dso_local global i32
46+
// PIE-DIRECT-NOPLT-NEXT: @weak_bar = extern_weak global i32
47+
// PIE-DIRECT-NOPLT-NEXT: @bar = external dso_local global i32
48+
49+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -pic-level 1 -pic-is-pie -fno-plt %s -o - | FileCheck --check-prefix=PIE-NO-PLT %s
50+
// RUN: %clang_cc1 -triple powerpc64le -fclangir -emit-llvm -mrelocation-model static %s -o - | FileCheck --check-prefix=PIE-NO-PLT %s
51+
// PIE-NO-PLT: @baz = dso_local global i32 42
52+
// PIE-NO-PLT-NEXT: @import_var = external global i32
53+
// PIE-NO-PLT-NEXT: @weak_bar = extern_weak global i32
54+
// PIE-NO-PLT-NEXT: @bar = external global i32
55+
56+
/// -fdirect-access-external-data is currently ignored for -fPIC.
57+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -pic-level 2 %s -o - | FileCheck --check-prefix=SHARED %s
58+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -pic-level 2 -fdirect-access-external-data %s -o - | FileCheck --check-prefix=SHARED %s
59+
// SHARED-DAG: @bar = external global i32
60+
// SHARED-DAG: @weak_bar = extern_weak global i32
61+
// SHARED-DAG: @baz ={{.*}} global i32 42
62+
63+
int baz = 42;
64+
__attribute__((dllimport)) extern int import_var;
65+
__attribute__((weak)) extern int weak_bar;
66+
extern int bar;
67+
68+
int *use_import(void) {
69+
return &import_var;
70+
}
71+
72+
int *zed(void) {
73+
if (baz)
74+
return &weak_bar;
75+
return &bar;
76+
}

clang/test/CIR/CodeGen/namespace.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace test {
2020
}
2121
}
2222

23-
// CHECK-DAG: cir.global "private" internal @_ZN12_GLOBAL__N_12g1E = #cir.int<1> : !s32i
23+
// CHECK-DAG: cir.global "private" internal dsolocal @_ZN12_GLOBAL__N_12g1E = #cir.int<1> : !s32i
2424
// CHECK-DAG: cir.global external @_ZN4test2g2E = #cir.int<2> : !s32i
2525
// CHECK-DAG: cir.global external @_ZN4test5test22g3E = #cir.int<3> : !s32i
2626
// CHECK-DAG: cir.func @_ZN12_GLOBAL__N_12f1Ev()

clang/test/CIR/CodeGen/string-literals.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-llvm %s -o %t.ll
66
// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
77

8-
// CIR: cir.global "private" external @[[STR1_GLOBAL:.*]] = #cir.const_array<"1\00" : !cir.array<!s8i x 2>> : !cir.array<!s8i x 2>
9-
// CIR: cir.global "private" external @[[STR2_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 1>
10-
// CIR: cir.global "private" external @[[STR3_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 2>
8+
// CIR: cir.global "private" cir_private dsolocal @[[STR1_GLOBAL:.*]] = #cir.const_array<"1\00" : !cir.array<!s8i x 2>> : !cir.array<!s8i x 2>
9+
// CIR: cir.global "private" cir_private dsolocal @[[STR2_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 1>
10+
// CIR: cir.global "private" cir_private dsolocal @[[STR3_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 2>
1111

12-
// LLVM: @[[STR1_GLOBAL:.*]] = global [2 x i8] c"1\00"
13-
// LLVM: @[[STR2_GLOBAL:.*]] = global [1 x i8] zeroinitializer
14-
// LLVM: @[[STR3_GLOBAL:.*]] = global [2 x i8] zeroinitializer
12+
// LLVM: @[[STR1_GLOBAL:.*]] = private global [2 x i8] c"1\00"
13+
// LLVM: @[[STR2_GLOBAL:.*]] = private global [1 x i8] zeroinitializer
14+
// LLVM: @[[STR3_GLOBAL:.*]] = private global [2 x i8] zeroinitializer
1515

1616
// OGCG: @[[STR1_GLOBAL:.*]] = private unnamed_addr constant [2 x i8] c"1\00"
1717
// OGCG: @[[STR2_GLOBAL:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer

0 commit comments

Comments
 (0)