Skip to content

Commit 143c371

Browse files
authored
[CIR] Upstream zero init for global variables (#133100)
This change adds zero initialization for global variables
1 parent 7eb99b8 commit 143c371

File tree

7 files changed

+92
-67
lines changed

7 files changed

+92
-67
lines changed

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

+24
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,30 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
6767
return create<cir::ConstantOp>(loc, attr.getType(), attr);
6868
}
6969

70+
mlir::TypedAttr getConstNullPtrAttr(mlir::Type t) {
71+
assert(mlir::isa<cir::PointerType>(t) && "expected cir.ptr");
72+
return getConstPtrAttr(t, 0);
73+
}
74+
75+
mlir::TypedAttr getZeroAttr(mlir::Type t) {
76+
return cir::ZeroAttr::get(getContext(), t);
77+
}
78+
79+
mlir::TypedAttr getZeroInitAttr(mlir::Type ty) {
80+
if (mlir::isa<cir::IntType>(ty))
81+
return cir::IntAttr::get(ty, 0);
82+
if (cir::isAnyFloatingPointType(ty))
83+
return cir::FPAttr::getZero(ty);
84+
if (auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
85+
return getZeroAttr(arrTy);
86+
if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty))
87+
return getConstNullPtrAttr(ptrTy);
88+
if (mlir::isa<cir::BoolType>(ty)) {
89+
return getCIRBoolAttr(false);
90+
}
91+
llvm_unreachable("Zero initializer for given type is NYI");
92+
}
93+
7094
cir::ConstantOp getBool(bool state, mlir::Location loc) {
7195
return create<cir::ConstantOp>(loc, getBoolTy(), getCIRBoolAttr(state));
7296
}

clang/lib/CIR/CodeGen/CIRGenModule.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,20 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
140140
// certain constant expressions is implemented for now.
141141
const VarDecl *initDecl;
142142
const Expr *initExpr = vd->getAnyInitializer(initDecl);
143+
mlir::Attribute initializer;
143144
if (initExpr) {
144-
mlir::Attribute initializer;
145145
if (APValue *value = initDecl->evaluateValue()) {
146146
ConstantEmitter emitter(*this);
147147
initializer = emitter.tryEmitPrivateForMemory(*value, astTy);
148148
} else {
149149
errorNYI(initExpr->getSourceRange(), "non-constant initializer");
150150
}
151-
varOp.setInitialValueAttr(initializer);
151+
} else {
152+
initializer = builder.getZeroInitAttr(convertType(astTy));
152153
}
153154

155+
varOp.setInitialValueAttr(initializer);
156+
154157
// Set CIR's linkage type as appropriate.
155158
cir::GlobalLinkageKind linkage =
156159
getCIRLinkageVarDefinition(vd, /*IsConstant=*/false);

clang/test/CIR/CodeGen/array.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - 2>&1 | FileCheck %s
22

33
int a[10];
4-
// CHECK: cir.global external @a : !cir.array<!s32i x 10>
4+
// CHECK: cir.global external @a = #cir.zero : !cir.array<!s32i x 10>
55

66
int aa[10][5];
7-
// CHECK: cir.global external @aa : !cir.array<!cir.array<!s32i x 5> x 10>
7+
// CHECK: cir.global external @aa = #cir.zero : !cir.array<!cir.array<!s32i x 5> x 10>
88

99
extern int b[10];
10-
// CHECK: cir.global external @b : !cir.array<!s32i x 10>
10+
// CHECK: cir.global external @b = #cir.zero : !cir.array<!s32i x 10>
1111

1212
extern int bb[10][5];
13-
// CHECK: cir.global external @bb : !cir.array<!cir.array<!s32i x 5> x 10>
13+
// CHECK: cir.global external @bb = #cir.zero : !cir.array<!cir.array<!s32i x 5> x 10>
1414

1515
int c[10] = {};
1616
// CHECK: cir.global external @c = #cir.zero : !cir.array<!s32i x 10>

clang/test/CIR/Lowering/array.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - 2>&1 | FileCheck %s
22

33
int a[10];
4-
// CHECK: @a = external dso_local global [10 x i32]
4+
// CHECK: @a = dso_local global [10 x i32] zeroinitializer
55

66
int aa[10][5];
7-
// CHECK: @aa = external dso_local global [10 x [5 x i32]]
7+
// CHECK: @aa = dso_local global [10 x [5 x i32]] zeroinitializer
88

99
extern int b[10];
10-
// CHECK: @b = external dso_local global [10 x i32]
10+
// CHECK: @b = dso_local global [10 x i32] zeroinitializer
1111

1212
extern int bb[10][5];
13-
// CHECK: @bb = external dso_local global [10 x [5 x i32]]
13+
// CHECK: @bb = dso_local global [10 x [5 x i32]] zeroinitializer
1414

1515
int c[10] = {};
1616
// CHECK: @c = dso_local global [10 x i32] zeroinitializer
+28-30
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
// Global variables of intergal types
2-
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s
2+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s
33

4-
// Note: Currently unsupported features include default zero-initialization
5-
// and alignment. The fact that "external" is only printed for globals
6-
// without an initializer is a quirk of the LLVM AsmWriter.
4+
// Note: Currently unsupported features include alignment..
75

86
char c;
9-
// CHECK: @c = external dso_local global i8
7+
// CHECK: @c = dso_local global i8 0
108

119
signed char sc;
12-
// CHECK: @sc = external dso_local global i8
10+
// CHECK: @sc = dso_local global i8 0
1311

1412
unsigned char uc;
15-
// CHECK: @uc = external dso_local global i8
13+
// CHECK: @uc = dso_local global i8 0
1614

1715
short ss;
18-
// CHECK: @ss = external dso_local global i16
16+
// CHECK: @ss = dso_local global i16 0
1917

2018
unsigned short us = 100;
2119
// CHECK: @us = dso_local global i16 100
@@ -24,82 +22,82 @@ int si = 42;
2422
// CHECK: @si = dso_local global i32 42
2523

2624
unsigned ui;
27-
// CHECK: @ui = external dso_local global i32
25+
// CHECK: @ui = dso_local global i32 0
2826

2927
long sl;
30-
// CHECK: @sl = external dso_local global i64
28+
// CHECK: @sl = dso_local global i64 0
3129

3230
unsigned long ul;
33-
// CHECK: @ul = external dso_local global i64
31+
// CHECK: @ul = dso_local global i64 0
3432

3533
long long sll;
36-
// CHECK: @sll = external dso_local global i64
34+
// CHECK: @sll = dso_local global i64 0
3735

3836
unsigned long long ull = 123456;
3937
// CHECK: @ull = dso_local global i64 123456
4038

4139
__int128 s128;
42-
// CHECK: @s128 = external dso_local global i128
40+
// CHECK: @s128 = dso_local global i128 0
4341

4442
unsigned __int128 u128;
45-
// CHECK: @u128 = external dso_local global i128
43+
// CHECK: @u128 = dso_local global i128 0
4644

4745
wchar_t wc;
48-
// CHECK: @wc = external dso_local global i32
46+
// CHECK: @wc = dso_local global i32 0
4947

5048
char8_t c8;
51-
// CHECK: @c8 = external dso_local global i8
49+
// CHECK: @c8 = dso_local global i8 0
5250

5351
char16_t c16;
54-
// CHECK: @c16 = external dso_local global i16
52+
// CHECK: @c16 = dso_local global i16 0
5553

5654
char32_t c32;
57-
// CHECK: @c32 = external dso_local global i32
55+
// CHECK: @c32 = dso_local global i32 0
5856

5957
_BitInt(20) sb20;
60-
// CHECK: @sb20 = external dso_local global i20
58+
// CHECK: @sb20 = dso_local global i20 0
6159

6260
unsigned _BitInt(48) ub48;
63-
// CHECK: @ub48 = external dso_local global i48
61+
// CHECK: @ub48 = dso_local global i48 0
6462

6563
bool boolfalse = false;
6664
// CHECK: @boolfalse = dso_local global i8 0
6765

6866
_Float16 f16;
69-
// CHECK: @f16 = external dso_local global half
67+
// CHECK: @f16 = dso_local global half
7068

7169
__bf16 bf16;
72-
// CHECK: @bf16 = external dso_local global bfloat
70+
// CHECK: @bf16 = dso_local global bfloat
7371

7472
float f;
75-
// CHECK: @f = external dso_local global float
73+
// CHECK: @f = dso_local global float 0.000000e+00
7674

7775
double d = 1.25;
7876
// CHECK: @d = dso_local global double 1.250000e+00
7977

8078
long double ld;
81-
// CHECK: @ld = external dso_local global x86_fp80
79+
// CHECK: @ld = dso_local global x86_fp80 0xK00
8280

8381
__float128 f128;
84-
// CHECK: @f128 = external dso_local global fp128
82+
// CHECK: @f128 = dso_local global fp128 0xL00
8583

8684
void *vp;
87-
// CHECK: @vp = external dso_local global ptr{{$}}
85+
// CHECK: @vp = dso_local global ptr null
8886

8987
int *ip = 0;
9088
// CHECK: @ip = dso_local global ptr null
9189

9290
double *dp;
93-
// CHECK: @dp = external dso_local global ptr{{$}}
91+
// CHECK: @dp = dso_local global ptr null
9492

9593
char **cpp;
96-
// CHECK: @cpp = external dso_local global ptr{{$}}
94+
// CHECK: @cpp = dso_local global ptr null
9795

9896
void (*fp)();
99-
// CHECK: @fp = external dso_local global ptr{{$}}
97+
// CHECK: @fp = dso_local global ptr null
10098

10199
int (*fpii)(int) = 0;
102100
// CHECK: @fpii = dso_local global ptr null
103101

104102
void (*fpvar)(int, ...);
105-
// CHECK: @fpvar = external dso_local global ptr{{$}}
103+
// CHECK: @fpvar = dso_local global ptr null

clang/test/CIR/Lowering/hello.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
int a;
55

6-
// CHECK: @a = external dso_local global i32
6+
// CHECK: @a = dso_local global i32 0
77

88
int b = 2;
99

clang/test/CIR/global-var-simple.cpp

+26-26
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s
33

44
char c;
5-
// CHECK: cir.global external @c : !s8i
5+
// CHECK: cir.global external @c = #cir.int<0> : !s8i
66

77
signed char sc;
8-
// CHECK: cir.global external @sc : !s8i
8+
// CHECK: cir.global external @sc = #cir.int<0> : !s8i
99

1010
unsigned char uc;
11-
// CHECK: cir.global external @uc : !u8i
11+
// CHECK: cir.global external @uc = #cir.int<0> : !u8i
1212

1313
short ss;
14-
// CHECK: cir.global external @ss : !s16i
14+
// CHECK: cir.global external @ss = #cir.int<0> : !s16i
1515

1616
unsigned short us = 100;
1717
// CHECK: cir.global external @us = #cir.int<100> : !u16i
@@ -20,82 +20,82 @@ int si = 42;
2020
// CHECK: cir.global external @si = #cir.int<42> : !s32i
2121

2222
unsigned ui;
23-
// CHECK: cir.global external @ui : !u32i
23+
// CHECK: cir.global external @ui = #cir.int<0> : !u32i
2424

2525
long sl;
26-
// CHECK: cir.global external @sl : !s64i
26+
// CHECK: cir.global external @sl = #cir.int<0> : !s64i
2727

2828
unsigned long ul;
29-
// CHECK: cir.global external @ul : !u64i
29+
// CHECK: cir.global external @ul = #cir.int<0> : !u64i
3030

3131
long long sll;
32-
// CHECK: cir.global external @sll : !s64i
32+
// CHECK: cir.global external @sll = #cir.int<0> : !s64i
3333

3434
unsigned long long ull = 123456;
3535
// CHECK: cir.global external @ull = #cir.int<123456> : !u64i
3636

3737
__int128 s128;
38-
// CHECK: cir.global external @s128 : !s128i
38+
// CHECK: cir.global external @s128 = #cir.int<0> : !s128i
3939

4040
unsigned __int128 u128;
41-
// CHECK: cir.global external @u128 : !u128i
41+
// CHECK: cir.global external @u128 = #cir.int<0> : !u128i
4242

4343
wchar_t wc;
44-
// CHECK: cir.global external @wc : !s32i
44+
// CHECK: cir.global external @wc = #cir.int<0> : !s32i
4545

4646
char8_t c8;
47-
// CHECK: cir.global external @c8 : !u8i
47+
// CHECK: cir.global external @c8 = #cir.int<0> : !u8i
4848

4949
char16_t c16;
50-
// CHECK: cir.global external @c16 : !u16i
50+
// CHECK: cir.global external @c16 = #cir.int<0> : !u16i
5151

5252
char32_t c32;
53-
// CHECK: cir.global external @c32 : !u32i
53+
// CHECK: cir.global external @c32 = #cir.int<0> : !u32i
5454

5555
_BitInt(20) sb20;
56-
// CHECK: cir.global external @sb20 : !cir.int<s, 20>
56+
// CHECK: cir.global external @sb20 = #cir.int<0> : !cir.int<s, 20>
5757

5858
unsigned _BitInt(48) ub48;
59-
// CHECK: cir.global external @ub48 : !cir.int<u, 48>
59+
// CHECK: cir.global external @ub48 = #cir.int<0> : !cir.int<u, 48>
6060

6161
bool boolfalse = false;
6262
// CHECK: cir.global external @boolfalse = #false
6363

6464
_Float16 f16;
65-
// CHECK: cir.global external @f16 : !cir.f16
65+
// CHECK: cir.global external @f16 = #cir.fp<0.000000e+00> : !cir.f16
6666

6767
__bf16 bf16;
68-
// CHECK: cir.global external @bf16 : !cir.bf16
68+
// CHECK: cir.global external @bf16 = #cir.fp<0.000000e+00> : !cir.bf16
6969

7070
float f;
71-
// CHECK: cir.global external @f : !cir.float
71+
// CHECK: cir.global external @f = #cir.fp<0.000000e+00> : !cir.float
7272

7373
double d = 1.25;
7474
// CHECK: cir.global external @d = #cir.fp<1.250000e+00> : !cir.double
7575

7676
long double ld;
77-
// CHECK: cir.global external @ld : !cir.long_double<!cir.f80>
77+
// CHECK: cir.global external @ld = #cir.fp<0.000000e+00> : !cir.long_double<!cir.f80>
7878

7979
__float128 f128;
80-
// CHECK: cir.global external @f128 : !cir.f128
80+
// CHECK: cir.global external @f128 = #cir.fp<0.000000e+00> : !cir.f128
8181

8282
void *vp;
83-
// CHECK: cir.global external @vp : !cir.ptr<!void>
83+
// CHECK: cir.global external @vp = #cir.ptr<null> : !cir.ptr<!void>
8484

8585
int *ip = 0;
8686
// CHECK: cir.global external @ip = #cir.ptr<null> : !cir.ptr<!s32i>
8787

8888
double *dp;
89-
// CHECK: cir.global external @dp : !cir.ptr<!cir.double>
89+
// CHECK: cir.global external @dp = #cir.ptr<null> : !cir.ptr<!cir.double>
9090

9191
char **cpp;
92-
// CHECK: cir.global external @cpp : !cir.ptr<!cir.ptr<!s8i>>
92+
// CHECK: cir.global external @cpp = #cir.ptr<null> : !cir.ptr<!cir.ptr<!s8i>>
9393

9494
void (*fp)();
95-
// CHECK: cir.global external @fp : !cir.ptr<!cir.func<()>>
95+
// CHECK: cir.global external @fp = #cir.ptr<null> : !cir.ptr<!cir.func<()>>
9696

9797
int (*fpii)(int) = 0;
9898
// CHECK: cir.global external @fpii = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i) -> !s32i>>
9999

100100
void (*fpvar)(int, ...);
101-
// CHECK: cir.global external @fpvar : !cir.ptr<!cir.func<(!s32i, ...)>>
101+
// CHECK: cir.global external @fpvar = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i, ...)>>

0 commit comments

Comments
 (0)