[clang] 143c371 - [CIR] Upstream zero init for global variables (#133100)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 31 10:41:31 PDT 2025
Author: Amr Hesham
Date: 2025-03-31T19:41:29+02:00
New Revision: 143c37123b93a3dbd0fafd0296516ac1ab2afc36
URL: https://github.com/llvm/llvm-project/commit/143c37123b93a3dbd0fafd0296516ac1ab2afc36
DIFF: https://github.com/llvm/llvm-project/commit/143c37123b93a3dbd0fafd0296516ac1ab2afc36.diff
LOG: [CIR] Upstream zero init for global variables (#133100)
This change adds zero initialization for global variables
Added:
Modified:
clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
clang/lib/CIR/CodeGen/CIRGenModule.cpp
clang/test/CIR/CodeGen/array.cpp
clang/test/CIR/Lowering/array.cpp
clang/test/CIR/Lowering/global-var-simple.cpp
clang/test/CIR/Lowering/hello.c
clang/test/CIR/global-var-simple.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index ac7658276ec37..8b17cb7446afa 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -67,6 +67,30 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return create<cir::ConstantOp>(loc, attr.getType(), attr);
}
+ mlir::TypedAttr getConstNullPtrAttr(mlir::Type t) {
+ assert(mlir::isa<cir::PointerType>(t) && "expected cir.ptr");
+ return getConstPtrAttr(t, 0);
+ }
+
+ mlir::TypedAttr getZeroAttr(mlir::Type t) {
+ return cir::ZeroAttr::get(getContext(), t);
+ }
+
+ mlir::TypedAttr getZeroInitAttr(mlir::Type ty) {
+ if (mlir::isa<cir::IntType>(ty))
+ return cir::IntAttr::get(ty, 0);
+ if (cir::isAnyFloatingPointType(ty))
+ return cir::FPAttr::getZero(ty);
+ if (auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
+ return getZeroAttr(arrTy);
+ if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty))
+ return getConstNullPtrAttr(ptrTy);
+ if (mlir::isa<cir::BoolType>(ty)) {
+ return getCIRBoolAttr(false);
+ }
+ llvm_unreachable("Zero initializer for given type is NYI");
+ }
+
cir::ConstantOp getBool(bool state, mlir::Location loc) {
return create<cir::ConstantOp>(loc, getBoolTy(), getCIRBoolAttr(state));
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 9776a4e09f9e0..2a37d6c7d1888 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -140,17 +140,20 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
// certain constant expressions is implemented for now.
const VarDecl *initDecl;
const Expr *initExpr = vd->getAnyInitializer(initDecl);
+ mlir::Attribute initializer;
if (initExpr) {
- mlir::Attribute initializer;
if (APValue *value = initDecl->evaluateValue()) {
ConstantEmitter emitter(*this);
initializer = emitter.tryEmitPrivateForMemory(*value, astTy);
} else {
errorNYI(initExpr->getSourceRange(), "non-constant initializer");
}
- varOp.setInitialValueAttr(initializer);
+ } else {
+ initializer = builder.getZeroInitAttr(convertType(astTy));
}
+ varOp.setInitialValueAttr(initializer);
+
// Set CIR's linkage type as appropriate.
cir::GlobalLinkageKind linkage =
getCIRLinkageVarDefinition(vd, /*IsConstant=*/false);
diff --git a/clang/test/CIR/CodeGen/array.cpp b/clang/test/CIR/CodeGen/array.cpp
index a59880352e050..1e74275eab058 100644
--- a/clang/test/CIR/CodeGen/array.cpp
+++ b/clang/test/CIR/CodeGen/array.cpp
@@ -1,16 +1,16 @@
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - 2>&1 | FileCheck %s
int a[10];
-// CHECK: cir.global external @a : !cir.array<!s32i x 10>
+// CHECK: cir.global external @a = #cir.zero : !cir.array<!s32i x 10>
int aa[10][5];
-// CHECK: cir.global external @aa : !cir.array<!cir.array<!s32i x 5> x 10>
+// CHECK: cir.global external @aa = #cir.zero : !cir.array<!cir.array<!s32i x 5> x 10>
extern int b[10];
-// CHECK: cir.global external @b : !cir.array<!s32i x 10>
+// CHECK: cir.global external @b = #cir.zero : !cir.array<!s32i x 10>
extern int bb[10][5];
-// CHECK: cir.global external @bb : !cir.array<!cir.array<!s32i x 5> x 10>
+// CHECK: cir.global external @bb = #cir.zero : !cir.array<!cir.array<!s32i x 5> x 10>
int c[10] = {};
// CHECK: cir.global external @c = #cir.zero : !cir.array<!s32i x 10>
diff --git a/clang/test/CIR/Lowering/array.cpp b/clang/test/CIR/Lowering/array.cpp
index 763980b9124a3..4fb996aefe79e 100644
--- a/clang/test/CIR/Lowering/array.cpp
+++ b/clang/test/CIR/Lowering/array.cpp
@@ -1,16 +1,16 @@
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - 2>&1 | FileCheck %s
int a[10];
-// CHECK: @a = external dso_local global [10 x i32]
+// CHECK: @a = dso_local global [10 x i32] zeroinitializer
int aa[10][5];
-// CHECK: @aa = external dso_local global [10 x [5 x i32]]
+// CHECK: @aa = dso_local global [10 x [5 x i32]] zeroinitializer
extern int b[10];
-// CHECK: @b = external dso_local global [10 x i32]
+// CHECK: @b = dso_local global [10 x i32] zeroinitializer
extern int bb[10][5];
-// CHECK: @bb = external dso_local global [10 x [5 x i32]]
+// CHECK: @bb = dso_local global [10 x [5 x i32]] zeroinitializer
int c[10] = {};
// CHECK: @c = dso_local global [10 x i32] zeroinitializer
diff --git a/clang/test/CIR/Lowering/global-var-simple.cpp b/clang/test/CIR/Lowering/global-var-simple.cpp
index ab8c6660a311b..33b418430d478 100644
--- a/clang/test/CIR/Lowering/global-var-simple.cpp
+++ b/clang/test/CIR/Lowering/global-var-simple.cpp
@@ -1,21 +1,19 @@
// Global variables of intergal types
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s
-// Note: Currently unsupported features include default zero-initialization
-// and alignment. The fact that "external" is only printed for globals
-// without an initializer is a quirk of the LLVM AsmWriter.
+// Note: Currently unsupported features include alignment..
char c;
-// CHECK: @c = external dso_local global i8
+// CHECK: @c = dso_local global i8 0
signed char sc;
-// CHECK: @sc = external dso_local global i8
+// CHECK: @sc = dso_local global i8 0
unsigned char uc;
-// CHECK: @uc = external dso_local global i8
+// CHECK: @uc = dso_local global i8 0
short ss;
-// CHECK: @ss = external dso_local global i16
+// CHECK: @ss = dso_local global i16 0
unsigned short us = 100;
// CHECK: @us = dso_local global i16 100
@@ -24,82 +22,82 @@ int si = 42;
// CHECK: @si = dso_local global i32 42
unsigned ui;
-// CHECK: @ui = external dso_local global i32
+// CHECK: @ui = dso_local global i32 0
long sl;
-// CHECK: @sl = external dso_local global i64
+// CHECK: @sl = dso_local global i64 0
unsigned long ul;
-// CHECK: @ul = external dso_local global i64
+// CHECK: @ul = dso_local global i64 0
long long sll;
-// CHECK: @sll = external dso_local global i64
+// CHECK: @sll = dso_local global i64 0
unsigned long long ull = 123456;
// CHECK: @ull = dso_local global i64 123456
__int128 s128;
-// CHECK: @s128 = external dso_local global i128
+// CHECK: @s128 = dso_local global i128 0
unsigned __int128 u128;
-// CHECK: @u128 = external dso_local global i128
+// CHECK: @u128 = dso_local global i128 0
wchar_t wc;
-// CHECK: @wc = external dso_local global i32
+// CHECK: @wc = dso_local global i32 0
char8_t c8;
-// CHECK: @c8 = external dso_local global i8
+// CHECK: @c8 = dso_local global i8 0
char16_t c16;
-// CHECK: @c16 = external dso_local global i16
+// CHECK: @c16 = dso_local global i16 0
char32_t c32;
-// CHECK: @c32 = external dso_local global i32
+// CHECK: @c32 = dso_local global i32 0
_BitInt(20) sb20;
-// CHECK: @sb20 = external dso_local global i20
+// CHECK: @sb20 = dso_local global i20 0
unsigned _BitInt(48) ub48;
-// CHECK: @ub48 = external dso_local global i48
+// CHECK: @ub48 = dso_local global i48 0
bool boolfalse = false;
// CHECK: @boolfalse = dso_local global i8 0
_Float16 f16;
-// CHECK: @f16 = external dso_local global half
+// CHECK: @f16 = dso_local global half
__bf16 bf16;
-// CHECK: @bf16 = external dso_local global bfloat
+// CHECK: @bf16 = dso_local global bfloat
float f;
-// CHECK: @f = external dso_local global float
+// CHECK: @f = dso_local global float 0.000000e+00
double d = 1.25;
// CHECK: @d = dso_local global double 1.250000e+00
long double ld;
-// CHECK: @ld = external dso_local global x86_fp80
+// CHECK: @ld = dso_local global x86_fp80 0xK00
__float128 f128;
-// CHECK: @f128 = external dso_local global fp128
+// CHECK: @f128 = dso_local global fp128 0xL00
void *vp;
-// CHECK: @vp = external dso_local global ptr{{$}}
+// CHECK: @vp = dso_local global ptr null
int *ip = 0;
// CHECK: @ip = dso_local global ptr null
double *dp;
-// CHECK: @dp = external dso_local global ptr{{$}}
+// CHECK: @dp = dso_local global ptr null
char **cpp;
-// CHECK: @cpp = external dso_local global ptr{{$}}
+// CHECK: @cpp = dso_local global ptr null
void (*fp)();
-// CHECK: @fp = external dso_local global ptr{{$}}
+// CHECK: @fp = dso_local global ptr null
int (*fpii)(int) = 0;
// CHECK: @fpii = dso_local global ptr null
void (*fpvar)(int, ...);
-// CHECK: @fpvar = external dso_local global ptr{{$}}
+// CHECK: @fpvar = dso_local global ptr null
diff --git a/clang/test/CIR/Lowering/hello.c b/clang/test/CIR/Lowering/hello.c
index ff78b6e6f6a5e..f45beafdcb533 100644
--- a/clang/test/CIR/Lowering/hello.c
+++ b/clang/test/CIR/Lowering/hello.c
@@ -3,7 +3,7 @@
int a;
-// CHECK: @a = external dso_local global i32
+// CHECK: @a = dso_local global i32 0
int b = 2;
diff --git a/clang/test/CIR/global-var-simple.cpp b/clang/test/CIR/global-var-simple.cpp
index 020ef5f09c650..9a52925303504 100644
--- a/clang/test/CIR/global-var-simple.cpp
+++ b/clang/test/CIR/global-var-simple.cpp
@@ -2,16 +2,16 @@
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s
char c;
-// CHECK: cir.global external @c : !s8i
+// CHECK: cir.global external @c = #cir.int<0> : !s8i
signed char sc;
-// CHECK: cir.global external @sc : !s8i
+// CHECK: cir.global external @sc = #cir.int<0> : !s8i
unsigned char uc;
-// CHECK: cir.global external @uc : !u8i
+// CHECK: cir.global external @uc = #cir.int<0> : !u8i
short ss;
-// CHECK: cir.global external @ss : !s16i
+// CHECK: cir.global external @ss = #cir.int<0> : !s16i
unsigned short us = 100;
// CHECK: cir.global external @us = #cir.int<100> : !u16i
@@ -20,82 +20,82 @@ int si = 42;
// CHECK: cir.global external @si = #cir.int<42> : !s32i
unsigned ui;
-// CHECK: cir.global external @ui : !u32i
+// CHECK: cir.global external @ui = #cir.int<0> : !u32i
long sl;
-// CHECK: cir.global external @sl : !s64i
+// CHECK: cir.global external @sl = #cir.int<0> : !s64i
unsigned long ul;
-// CHECK: cir.global external @ul : !u64i
+// CHECK: cir.global external @ul = #cir.int<0> : !u64i
long long sll;
-// CHECK: cir.global external @sll : !s64i
+// CHECK: cir.global external @sll = #cir.int<0> : !s64i
unsigned long long ull = 123456;
// CHECK: cir.global external @ull = #cir.int<123456> : !u64i
__int128 s128;
-// CHECK: cir.global external @s128 : !s128i
+// CHECK: cir.global external @s128 = #cir.int<0> : !s128i
unsigned __int128 u128;
-// CHECK: cir.global external @u128 : !u128i
+// CHECK: cir.global external @u128 = #cir.int<0> : !u128i
wchar_t wc;
-// CHECK: cir.global external @wc : !s32i
+// CHECK: cir.global external @wc = #cir.int<0> : !s32i
char8_t c8;
-// CHECK: cir.global external @c8 : !u8i
+// CHECK: cir.global external @c8 = #cir.int<0> : !u8i
char16_t c16;
-// CHECK: cir.global external @c16 : !u16i
+// CHECK: cir.global external @c16 = #cir.int<0> : !u16i
char32_t c32;
-// CHECK: cir.global external @c32 : !u32i
+// CHECK: cir.global external @c32 = #cir.int<0> : !u32i
_BitInt(20) sb20;
-// CHECK: cir.global external @sb20 : !cir.int<s, 20>
+// CHECK: cir.global external @sb20 = #cir.int<0> : !cir.int<s, 20>
unsigned _BitInt(48) ub48;
-// CHECK: cir.global external @ub48 : !cir.int<u, 48>
+// CHECK: cir.global external @ub48 = #cir.int<0> : !cir.int<u, 48>
bool boolfalse = false;
// CHECK: cir.global external @boolfalse = #false
_Float16 f16;
-// CHECK: cir.global external @f16 : !cir.f16
+// CHECK: cir.global external @f16 = #cir.fp<0.000000e+00> : !cir.f16
__bf16 bf16;
-// CHECK: cir.global external @bf16 : !cir.bf16
+// CHECK: cir.global external @bf16 = #cir.fp<0.000000e+00> : !cir.bf16
float f;
-// CHECK: cir.global external @f : !cir.float
+// CHECK: cir.global external @f = #cir.fp<0.000000e+00> : !cir.float
double d = 1.25;
// CHECK: cir.global external @d = #cir.fp<1.250000e+00> : !cir.double
long double ld;
-// CHECK: cir.global external @ld : !cir.long_double<!cir.f80>
+// CHECK: cir.global external @ld = #cir.fp<0.000000e+00> : !cir.long_double<!cir.f80>
__float128 f128;
-// CHECK: cir.global external @f128 : !cir.f128
+// CHECK: cir.global external @f128 = #cir.fp<0.000000e+00> : !cir.f128
void *vp;
-// CHECK: cir.global external @vp : !cir.ptr<!void>
+// CHECK: cir.global external @vp = #cir.ptr<null> : !cir.ptr<!void>
int *ip = 0;
// CHECK: cir.global external @ip = #cir.ptr<null> : !cir.ptr<!s32i>
double *dp;
-// CHECK: cir.global external @dp : !cir.ptr<!cir.double>
+// CHECK: cir.global external @dp = #cir.ptr<null> : !cir.ptr<!cir.double>
char **cpp;
-// CHECK: cir.global external @cpp : !cir.ptr<!cir.ptr<!s8i>>
+// CHECK: cir.global external @cpp = #cir.ptr<null> : !cir.ptr<!cir.ptr<!s8i>>
void (*fp)();
-// CHECK: cir.global external @fp : !cir.ptr<!cir.func<()>>
+// CHECK: cir.global external @fp = #cir.ptr<null> : !cir.ptr<!cir.func<()>>
int (*fpii)(int) = 0;
// CHECK: cir.global external @fpii = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i) -> !s32i>>
void (*fpvar)(int, ...);
-// CHECK: cir.global external @fpvar : !cir.ptr<!cir.func<(!s32i, ...)>>
+// CHECK: cir.global external @fpvar = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i, ...)>>
More information about the cfe-commits
mailing list