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, ...)>> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits