Skip to content

Commit 4432e1d

Browse files
ghehglanza
authored andcommitted
[CIR][CIRGen] Add comdat support, enabling more dso_local and comdat LLVM tagging (llvm#751)
This PR implements: 1. Add comdat attribute as an optional attribute to CIR GlobalOp and FuncOp, they are of the enum ComdatSelection type because it contains all information we need. The [llvm/include/llvm/IR/Comdat.h](https://github.com/llvm/clangir/blob/4ea2ec38638391b964e88b77f926e0892b350e04/llvm/include/llvm/IR/Comdat.h#L33) has Comdat with selectionKind and its name, add users which are set of pointers to GlobalObjects sharing the same name. The name is always the name of global object (in CIR context, the GlobalOp or FuncOp), so we don't need it. And the user set can always be collected when a transformation looks up symbol table of the module, thus not really necessary. Plus, it's not good for CIR to keep a set of pointers. 2. Thanks to comdat support, and adding call sites of setComdat similar to what was in OG, we are able to implement canBenefitFromLocalAlias as similar as possible to [GlobalValue::canBenefitFromLocalAlias() ](https://github.com/llvm/clangir/blob/4ea2ec38638391b964e88b77f926e0892b350e04/llvm/lib/IR/Globals.cpp#L112) and this enable us to complete dso_local work by correctly setting dso_local for functions. 3. I took back printing of dsolocal attribute of CIR, as I would fix 128+ test cases instead of 36-37 of tests (mostly adding dso_local to function prototype line in LLVM check) in this PR. printing dsolocal attribute is not really necessary as llvm IR would verify it for us. 4. LLVM lowering of Comdat for GlobalOp Things left to next/future PR 1. I'd like to extend setComdat to other parts of CG like Vtable, etc. 2. LLVM lowering of comdat for FuncOp
1 parent 6fab94f commit 4432e1d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+347
-295
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

+4-1
Original file line numberDiff line numberDiff line change
@@ -2082,7 +2082,7 @@ def TLSModel : I32EnumAttr<
20822082
[TLS_GeneralDynamic, TLS_LocalDynamic, TLS_InitialExec, TLS_LocalExec]> {
20832083
let cppNamespace = "::mlir::cir";
20842084
}
2085-
2085+
20862086
def GlobalOp : CIR_Op<"global",
20872087
[DeclareOpInterfaceMethods<RegionBranchOpInterface>,
20882088
DeclareOpInterfaceMethods<CIRGlobalValueInterface>,
@@ -2123,6 +2123,7 @@ def GlobalOp : CIR_Op<"global",
21232123
OptionalAttr<TLSModel>:$tls_model,
21242124
// Note this can also be a FlatSymbolRefAttr
21252125
OptionalAttr<AnyAttr>:$initial_value,
2126+
UnitAttr:$comdat,
21262127
UnitAttr:$constant,
21272128
UnitAttr:$dsolocal,
21282129
OptionalAttr<I64Attr>:$alignment,
@@ -2134,6 +2135,7 @@ def GlobalOp : CIR_Op<"global",
21342135
($sym_visibility^)?
21352136
(`constant` $constant^)?
21362137
$linkage
2138+
(`comdat` $comdat^)?
21372139
($tls_model^)?
21382140
(`dsolocal` $dsolocal^)?
21392141
$sym_name
@@ -2878,6 +2880,7 @@ def FuncOp : CIR_Op<"func", [
28782880
"GlobalLinkageKind::ExternalLinkage">:$linkage,
28792881
ExtraFuncAttr:$extra_attrs,
28802882
OptionalAttr<StrAttr>:$sym_visibility,
2883+
UnitAttr:$comdat,
28812884
OptionalAttr<DictArrayAttr>:$arg_attrs,
28822885
OptionalAttr<DictArrayAttr>:$res_attrs,
28832886
OptionalAttr<FlatSymbolRefAttr>:$aliasee,

clang/include/clang/CIR/Interfaces/CIROpInterfaces.td

+14-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ let cppNamespace = "::mlir::cir" in {
5858
}]
5959
>,
6060
InterfaceMethod<"",
61+
"bool", "isExternalLinkage", (ins), [{}],
62+
/*defaultImplementation=*/[{
63+
return mlir::cir::isExternalLinkage($_op.getLinkage());
64+
}]
65+
>,
66+
InterfaceMethod<"",
6167
"bool", "isDeclarationForLinker", (ins), [{}],
6268
/*defaultImplementation=*/[{
6369
if ($_op.hasAvailableExternallyLinkage())
@@ -66,14 +72,21 @@ let cppNamespace = "::mlir::cir" in {
6672
}]
6773
>,
6874
InterfaceMethod<"",
75+
"bool", "hasComdat", (ins), [{}],
76+
/*defaultImplementation=*/[{
77+
return $_op.getComdat();
78+
}]
79+
>,
80+
InterfaceMethod<"",
6981
"void", "setDSOLocal", (ins "bool":$val), [{}],
7082
/*defaultImplementation=*/[{
7183
$_op.setDsolocal(val);
7284
}]
7385
>,
7486
];
7587
let extraClassDeclaration = [{
76-
bool canBenefitFromLocalAlias() const;
88+
bool hasDefaultVisibility();
89+
bool canBenefitFromLocalAlias();
7790
}];
7891
}
7992

clang/lib/CIR/CodeGen/CIRGenModule.cpp

+9-16
Original file line numberDiff line numberDiff line change
@@ -365,22 +365,12 @@ bool CIRGenModule::MayBeEmittedEagerly(const ValueDecl *Global) {
365365
return true;
366366
}
367367

368-
static bool hasDefaultVisibility(CIRGlobalValueInterface GV) {
369-
// Since we do not support hidden visibility and private visibility,
370-
// we can assume that the default visibility is public or private.
371-
// The way we use private visibility now simply is just treating it
372-
// as either local or private linkage, or just default for declarations
373-
assert(!MissingFeatures::hiddenVisibility());
374-
assert(!MissingFeatures::protectedVisibility());
375-
return GV.isPublic() || GV.isPrivate();
376-
}
377-
378368
static bool shouldAssumeDSOLocal(const CIRGenModule &CGM,
379369
CIRGlobalValueInterface GV) {
380370
if (GV.hasLocalLinkage())
381371
return true;
382372

383-
if (!hasDefaultVisibility(GV) && !GV.hasExternalWeakLinkage()) {
373+
if (!GV.hasDefaultVisibility() && !GV.hasExternalWeakLinkage()) {
384374
return true;
385375
}
386376

@@ -1436,8 +1426,11 @@ generateStringLiteral(mlir::Location loc, mlir::TypedAttr C,
14361426
// TODO(cir)
14371427
assert(!cir::MissingFeatures::threadLocal() && "NYI");
14381428
assert(!cir::MissingFeatures::unnamedAddr() && "NYI");
1439-
assert(!mlir::cir::isWeakForLinker(LT) && "NYI");
1440-
assert(!cir::MissingFeatures::setDSOLocal() && "NYI");
1429+
if (GV.isWeakForLinker()) {
1430+
assert(CGM.supportsCOMDAT() && "Only COFF uses weak string literals");
1431+
GV.setComdat(true);
1432+
}
1433+
CGM.setDSOLocal(static_cast<mlir::Operation *>(GV));
14411434
return GV;
14421435
}
14431436

@@ -2910,10 +2903,10 @@ mlir::cir::GlobalOp CIRGenModule::createOrReplaceCXXRuntimeVariable(
29102903
OldGV->erase();
29112904
}
29122905

2913-
assert(!MissingFeatures::setComdat());
29142906
if (supportsCOMDAT() && mlir::cir::isWeakForLinker(Linkage) &&
2915-
!GV.hasAvailableExternallyLinkage())
2916-
assert(!MissingFeatures::setComdat());
2907+
!GV.hasAvailableExternallyLinkage()) {
2908+
GV.setComdat(true);
2909+
}
29172910

29182911
GV.setAlignmentAttr(getSize(Alignment));
29192912
setDSOLocal(static_cast<mlir::Operation *>(GV));

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -2109,16 +2109,16 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
21092109
if (getNoProto())
21102110
p << "no_proto ";
21112111

2112+
if (getComdat())
2113+
p << "comdat ";
2114+
21122115
if (getLinkage() != GlobalLinkageKind::ExternalLinkage)
21132116
p << stringifyGlobalLinkageKind(getLinkage()) << ' ';
21142117

21152118
auto vis = getVisibility();
21162119
if (vis != mlir::SymbolTable::Visibility::Public)
21172120
p << vis << " ";
21182121

2119-
if (getDsolocal())
2120-
p << "dsolocal ";
2121-
21222122
// Print function name, signature, and control.
21232123
p.printSymbolName(getSymName());
21242124
auto fnType = getFunctionType();
@@ -2148,6 +2148,7 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
21482148
getSymVisibilityAttrName(),
21492149
getArgAttrsAttrName(),
21502150
getResAttrsAttrName(),
2151+
getComdatAttrName(),
21512152
});
21522153

21532154
if (auto aliaseeName = getAliasee()) {

clang/lib/CIR/Interfaces/CIROpInterfaces.cpp

+15-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,21 @@ using namespace mlir::cir;
1717

1818
#include "clang/CIR/MissingFeatures.h"
1919

20-
bool CIRGlobalValueInterface::canBenefitFromLocalAlias() const {
20+
bool CIRGlobalValueInterface::hasDefaultVisibility() {
21+
assert(!::cir::MissingFeatures::hiddenVisibility());
22+
assert(!::cir::MissingFeatures::protectedVisibility());
23+
return isPublic() || isPrivate();
24+
}
25+
26+
bool CIRGlobalValueInterface::canBenefitFromLocalAlias() {
2127
assert(!::cir::MissingFeatures::supportIFuncAttr());
22-
assert(!::cir::MissingFeatures::setComdat());
28+
// hasComdat here should be isDeduplicateComdat, but as far as clang codegen
29+
// is concerned, there is no case for Comdat::NoDeduplicate as all comdat
30+
// would be Comdat::Any or Comdat::Largest (in the case of MS ABI). And CIRGen
31+
// wouldn't even generate Comdat::Largest comdat as it tries to leave ABI
32+
// specifics to LLVM lowering stage, thus here we don't need test Comdat
33+
// selectionKind.
34+
return hasDefaultVisibility() && isExternalLinkage() && !isDeclaration() &&
35+
!hasComdat();
2336
return false;
2437
}

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

+28-5
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@
4646
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
4747
#include "mlir/Target/LLVMIR/Export.h"
4848
#include "mlir/Transforms/DialectConversion.h"
49-
#include "clang/CIR/LoweringHelpers.h"
5049
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
5150
#include "clang/CIR/Dialect/IR/CIRDialect.h"
5251
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
5352
#include "clang/CIR/Dialect/IR/CIRTypes.h"
5453
#include "clang/CIR/Dialect/Passes.h"
54+
#include "clang/CIR/LoweringHelpers.h"
5555
#include "clang/CIR/MissingFeatures.h"
5656
#include "clang/CIR/Passes.h"
5757
#include "llvm/ADT/APInt.h"
@@ -1433,7 +1433,7 @@ class CIRFuncLowering : public mlir::OpConversionPattern<mlir::cir::FuncOp> {
14331433
cast<mlir::cir::ExtraFuncAttributesAttr>(extraAttrsEntry.getValue());
14341434
if (!oldExtraAttrs.getElements().contains(attrKey))
14351435
return;
1436-
1436+
14371437
mlir::NamedAttrList newExtraAttrs;
14381438
for (auto entry : oldExtraAttrs.getElements()) {
14391439
if (entry.getName() == attrKey) {
@@ -1815,13 +1815,35 @@ class CIRGlobalOpLowering
18151815
}
18161816

18171817
// Rewrite op.
1818-
rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
1818+
auto llvmGlobalOp = rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
18191819
op, llvmType, isConst, linkage, symbol, init.value(),
18201820
/*alignment*/ 0, /*addrSpace*/ 0,
18211821
/*dsoLocal*/ false, /*threadLocal*/ (bool)op.getTlsModelAttr(),
18221822
/*comdat*/ mlir::SymbolRefAttr(), attributes);
1823+
auto mod = op->getParentOfType<mlir::ModuleOp>();
1824+
if (op.getComdat())
1825+
addComdat(llvmGlobalOp, comdatOp, rewriter, mod);
18231826
return mlir::success();
18241827
}
1828+
1829+
private:
1830+
mutable mlir::LLVM::ComdatOp comdatOp = nullptr;
1831+
static void addComdat(mlir::LLVM::GlobalOp &op,
1832+
mlir::LLVM::ComdatOp &comdatOp,
1833+
mlir::OpBuilder &builder, mlir::ModuleOp &module) {
1834+
StringRef comdatName("__llvm_comdat_globals");
1835+
if (!comdatOp) {
1836+
builder.setInsertionPointToStart(module.getBody());
1837+
comdatOp =
1838+
builder.create<mlir::LLVM::ComdatOp>(module.getLoc(), comdatName);
1839+
}
1840+
builder.setInsertionPointToStart(&comdatOp.getBody().back());
1841+
auto selectorOp = builder.create<mlir::LLVM::ComdatSelectorOp>(
1842+
comdatOp.getLoc(), op.getSymName(), mlir::LLVM::comdat::Comdat::Any);
1843+
op.setComdatAttr(mlir::SymbolRefAttr::get(
1844+
builder.getContext(), comdatName,
1845+
mlir::FlatSymbolRefAttr::get(selectorOp.getSymNameAttr())));
1846+
}
18251847
};
18261848

18271849
class CIRUnaryOpLowering
@@ -3415,7 +3437,7 @@ class CIRUndefOpLowering
34153437
matchAndRewrite(mlir::cir::UndefOp op, OpAdaptor adaptor,
34163438
mlir::ConversionPatternRewriter &rewriter) const override {
34173439
auto typ = getTypeConverter()->convertType(op.getRes().getType());
3418-
3440+
34193441
rewriter.replaceOpWithNewOp<mlir::LLVM::UndefOp>(op, typ);
34203442
return mlir::success();
34213443
}
@@ -3455,7 +3477,8 @@ void populateCIRToLLVMConversionPatterns(mlir::RewritePatternSet &patterns,
34553477
CIRRintOpLowering, CIRRoundOpLowering, CIRSinOpLowering,
34563478
CIRSqrtOpLowering, CIRTruncOpLowering, CIRCopysignOpLowering,
34573479
CIRFModOpLowering, CIRFMaxOpLowering, CIRFMinOpLowering, CIRPowOpLowering,
3458-
CIRClearCacheOpLowering, CIRUndefOpLowering>(converter, patterns.getContext());
3480+
CIRClearCacheOpLowering, CIRUndefOpLowering>(converter,
3481+
patterns.getContext());
34593482
}
34603483

34613484
namespace {

clang/test/CIR/CodeGen/address-space-conversion.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ using ri1_t = int __attribute__((address_space(1))) &;
1010
using ri2_t = int __attribute__((address_space(2))) &;
1111

1212
// CIR: cir.func @{{.*test_ptr.*}}
13-
// LLVM: define void @{{.*test_ptr.*}}
13+
// LLVM: define dso_local void @{{.*test_ptr.*}}
1414
void test_ptr() {
1515
pi1_t ptr1;
1616
pi2_t ptr2 = (pi2_t)ptr1;
@@ -24,7 +24,7 @@ void test_ptr() {
2424
}
2525

2626
// CIR: cir.func @{{.*test_ref.*}}
27-
// LLVM: define void @{{.*test_ref.*}}
27+
// LLVM: define dso_local void @{{.*test_ref.*}}
2828
void test_ref() {
2929
pi1_t ptr;
3030
ri1_t ref1 = *ptr;
@@ -43,7 +43,7 @@ void test_ref() {
4343
}
4444

4545
// CIR: cir.func @{{.*test_nullptr.*}}
46-
// LLVM: define void @{{.*test_nullptr.*}}
46+
// LLVM: define dso_local void @{{.*test_nullptr.*}}
4747
void test_nullptr() {
4848
constexpr pi1_t null1 = nullptr;
4949
pi2_t ptr = (pi2_t)null1;

clang/test/CIR/CodeGen/address-space.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
55

66
// CIR: cir.func {{@.*foo.*}}(%arg0: !cir.ptr<!s32i, addrspace(target<1>)>
7-
// LLVM: define void @foo(ptr addrspace(1) %0)
7+
// LLVM: define dso_local void @foo(ptr addrspace(1) %0)
88
void foo(int __attribute__((address_space(1))) *arg) {
99
return;
1010
}
1111

1212
// CIR: cir.func {{@.*bar.*}}(%arg0: !cir.ptr<!s32i, addrspace(target<0>)>
13-
// LLVM: define void @bar(ptr %0)
13+
// LLVM: define dso_local void @bar(ptr %0)
1414
void bar(int __attribute__((address_space(0))) *arg) {
1515
return;
1616
}
1717

1818
// CIR: cir.func {{@.*baz.*}}(%arg0: !cir.ptr<!s32i>
19-
// LLVM: define void @baz(ptr %0)
19+
// LLVM: define dso_local void @baz(ptr %0)
2020
void baz(int *arg) {
2121
return;
2222
}

clang/test/CIR/CodeGen/atomic.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ int basic_binop_fetch(int *i) {
2828
// CHECK: %[[VAL:.*]] = cir.load %[[ONE_ADDR]] : !cir.ptr<!s32i>, !s32i
2929
// CHECK: cir.atomic.fetch(add, %[[I]] : !cir.ptr<!s32i>, %[[VAL]] : !s32i, seq_cst) : !s32i
3030

31-
// LLVM: define i32 @_Z17basic_binop_fetchPi
31+
// LLVM: define dso_local i32 @_Z17basic_binop_fetchPi
3232
// LLVM: %[[RMW:.*]] = atomicrmw add ptr {{.*}}, i32 %[[VAL:.*]] seq_cst, align 4
3333
// LLVM: add i32 %[[RMW]], %[[VAL]]
3434

@@ -45,7 +45,7 @@ int other_binop_fetch(int *i) {
4545
// CHECK: cir.atomic.fetch(or, {{.*}}, acquire
4646
// CHECK: cir.atomic.fetch(xor, {{.*}}, release
4747

48-
// LLVM: define i32 @_Z17other_binop_fetchPi
48+
// LLVM: define dso_local i32 @_Z17other_binop_fetchPi
4949
// LLVM: %[[RMW_SUB:.*]] = atomicrmw sub ptr {{.*}} monotonic
5050
// LLVM: sub i32 %[[RMW_SUB]], {{.*}}
5151
// LLVM: %[[RMW_AND:.*]] = atomicrmw and ptr {{.*}} acquire
@@ -62,7 +62,7 @@ int nand_binop_fetch(int *i) {
6262
// CHECK: cir.func @_Z16nand_binop_fetchPi
6363
// CHECK: cir.atomic.fetch(nand, {{.*}}, acq_rel
6464

65-
// LLVM: define i32 @_Z16nand_binop_fetchPi
65+
// LLVM: define dso_local i32 @_Z16nand_binop_fetchPi
6666
// LLVM: %[[RMW_NAND:.*]] = atomicrmw nand ptr {{.*}} acq_rel
6767
// LLVM: %[[AND:.*]] = and i32 %[[RMW_NAND]]
6868
// LLVM: = xor i32 %[[AND]], -1
@@ -76,7 +76,7 @@ int fp_binop_fetch(float *i) {
7676
// CHECK: cir.atomic.fetch(add,
7777
// CHECK: cir.atomic.fetch(sub,
7878

79-
// LLVM: define i32 @_Z14fp_binop_fetchPf
79+
// LLVM: define dso_local i32 @_Z14fp_binop_fetchPf
8080
// LLVM: %[[RMW_FADD:.*]] = atomicrmw fadd ptr
8181
// LLVM: fadd float %[[RMW_FADD]]
8282
// LLVM: %[[RMW_FSUB:.*]] = atomicrmw fsub ptr
@@ -99,7 +99,7 @@ int fetch_binop(int *i) {
9999
// CHECK: cir.atomic.fetch(xor, {{.*}}) fetch_first
100100
// CHECK: cir.atomic.fetch(nand, {{.*}}) fetch_first
101101

102-
// LLVM: define i32 @_Z11fetch_binopPi
102+
// LLVM: define dso_local i32 @_Z11fetch_binopPi
103103
// LLVM: atomicrmw add ptr
104104
// LLVM-NOT: add {{.*}}
105105
// LLVM: atomicrmw sub ptr
@@ -126,7 +126,7 @@ void min_max_fetch(int *i) {
126126
// CHECK: = cir.atomic.fetch(max, {{.*}}) : !s32i
127127
// CHECK: = cir.atomic.fetch(min, {{.*}}) : !s32i
128128

129-
// LLVM: define void @_Z13min_max_fetchPi
129+
// LLVM: define dso_local void @_Z13min_max_fetchPi
130130
// LLVM: atomicrmw max ptr
131131
// LLVM-NOT: icmp {{.*}}
132132
// LLVM: atomicrmw min ptr
@@ -343,7 +343,7 @@ void inc_int(int* a, int b) {
343343
int c = __sync_fetch_and_add(a, b);
344344
}
345345
// CHECK-LABEL: @_Z7inc_int
346-
// CHECK: %[[PTR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
346+
// CHECK: %[[PTR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
347347
// CHECK: %[[VAL:.*]] = cir.load {{.*}} : !cir.ptr<!s32i>, !s32i
348348
// CHECK: %[[RES:.*]] = cir.atomic.fetch(add, %[[PTR]] : !cir.ptr<!s32i>, %[[VAL]] : !s32i, seq_cst) fetch_first : !s32i
349349
// CHECK: cir.store %[[RES]], {{.*}} : !s32i, !cir.ptr<!s32i>
@@ -442,7 +442,7 @@ void cmp_bool_byte(char* p, char x, char u) {
442442
// LLVM: %[[TMP:.*]] = extractvalue { i32, i1 } %[[RES]], 0
443443
// LLVM: store i32 %[[TMP]], ptr {{.*}}
444444
void cmp_val_int(int* p, int x, int u) {
445-
int r = __sync_val_compare_and_swap(p, x, u);
445+
int r = __sync_val_compare_and_swap(p, x, u);
446446
}
447447

448448
// CHECK-LABEL: @_Z12cmp_val_long
@@ -466,7 +466,7 @@ void cmp_val_short(short* p, short x, short u) {
466466
// CHECK-LABEL: @_Z12cmp_val_byte
467467
// CHECK: cir.atomic.cmp_xchg({{.*}} : !cir.ptr<!s8i>, {{.*}} : !s8i, {{.*}} : !s8i, success = seq_cst, failure = seq_cst) : (!s8i, !cir.bool)
468468

469-
// LLVM-LABEL: @_Z12cmp_val_byte
469+
// LLVM-LABEL: @_Z12cmp_val_byte
470470
// LLVM: cmpxchg ptr {{.*}}, i8 {{.*}}, i8 {{.*}} seq_cst seq_cst
471471
void cmp_val_byte(char* p, char x, char u) {
472472
char r = __sync_val_compare_and_swap(p, x, u);

clang/test/CIR/CodeGen/basic.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ int f2(void) { return 3; }
3030
// CIR-NEXT: %2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
3131
// CIR-NEXT: cir.return %2 : !s32i
3232

33-
// LLVM: define i32 @f2()
33+
// LLVM: define dso_local i32 @f2()
3434
// LLVM-NEXT: %1 = alloca i32, i64 1, align 4
3535
// LLVM-NEXT: store i32 3, ptr %1, align 4
3636
// LLVM-NEXT: %2 = load i32, ptr %1, align 4

0 commit comments

Comments
 (0)