Author: Erich Keane Date: 2026-03-13T06:28:07-07:00 New Revision: 8238ae27f032e04ca9e566ec31b788394a8377f8
URL: https://github.com/llvm/llvm-project/commit/8238ae27f032e04ca9e566ec31b788394a8377f8 DIFF: https://github.com/llvm/llvm-project/commit/8238ae27f032e04ca9e566ec31b788394a8377f8.diff LOG: [CIR] Implement zero-init-bases lowering (#186230) This showed up in a test suite. A zero-initializer for a whole struct seems completely sensible, as long as the type is zero-initializable. This patch doesn't change the non-zero-init behavior (I am working on a patch to do so, but it is a massive scope), so this is limited to JUST classes with bases. Added: clang/test/CIR/CodeGenCXX/zero_init_bases.cpp Modified: clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 338d64e323391..c5c5847da1d48 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -1644,12 +1644,6 @@ mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &d) { // be a problem for the near future. if (cd->isTrivial() && cd->isDefaultConstructor()) { const auto *cxxrd = ty->castAsCXXRecordDecl(); - if (cxxrd->getNumBases() != 0) { - // There may not be anything additional to do here, but this will - // force us to pause and test this path when it is supported. - cgm.errorNYI("tryEmitPrivateForVarInit: cxx record with bases"); - return {}; - } if (!cgm.getTypes().isZeroInitializable(cxxrd)) { // To handle this case, we really need to go through // emitNullConstant, but we need an attribute, not a value diff --git a/clang/test/CIR/CodeGenCXX/zero_init_bases.cpp b/clang/test/CIR/CodeGenCXX/zero_init_bases.cpp new file mode 100644 index 0000000000000..f21117df21e3a --- /dev/null +++ b/clang/test/CIR/CodeGenCXX/zero_init_bases.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fclangir -emit-cir -fcxx-exceptions -fexceptions -mmlir --mlir-print-ir-before=cir-cxxabi-lowering -o %t.cir 2> %t-before.cir +// RUN: FileCheck %s --input-file=%t-before.cir --check-prefixes=CIR,CIR-BEFORE +// RUN: FileCheck %s --input-file=%t.cir --check-prefixes=CIR,CIR-AFTER +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fclangir -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s --check-prefixes=LLVM +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s --check-prefixes=LLVM + +struct Base1 { + int i, j, k; +}; + +struct Base2 { + float l, m, n; +}; + +struct Inherits : Base1, Base2 { + int o,p,q; +}; + + +struct VirtualInherits : virtual Base1, virtual Base2 { + int o,p,q; +}; + + +// CIR: !rec_Base2 = !cir.record<struct "Base2" {!cir.float, !cir.float, !cir.float}> +// CIR: !rec_Base1 = !cir.record<struct "Base1" {!s32i, !s32i, !s32i}> +// CIR: !rec_Inherits = !cir.record<struct "Inherits" {!rec_Base1, !rec_Base2, !s32i, !s32i, !s32i}> +// CIR: !rec_VirtualInherits = !cir.record<struct "VirtualInherits" packed padded {!cir.vptr, !s32i, !s32i, !s32i, !rec_Base1, !rec_Base2, !cir.array<!u8i x 4>}> +// +// LLVM: %struct.Inherits = type { %struct.Base1, %struct.Base2, i32, i32, i32 } +// LLVM: %struct.Base1 = type { i32, i32, i32 } +// LLVM: %struct.Base2 = type { float, float, float } +// LLVM: %struct.VirtualInherits = type <{ ptr, i32, i32, i32, %struct.Base1, %struct.Base2, [4 x i8] }> +// +Inherits I; +// CIR: cir.global external @I = #cir.zero : !rec_Inherits {alignment = 4 : i64} +// LLVM: @I = global %struct.Inherits zeroinitializer, align 4 + +Inherits I2 {{1,2,3},{1.1, 2.2, 3.3}, 4, 5, 6}; +// CIR: cir.global external @I2 = #cir.const_record<{#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i, #cir.fp<1.100000e+00> : !cir.float, #cir.fp<2.200000e+00> : !cir.float, #cir.fp<3.300000e+00> : !cir.float, #cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i}> : !rec_anon_struct {alignment = 4 : i64} +// LLVM: @I2 = global { i32, i32, i32, float, float, float, i32, i32, i32 } { i32 1, i32 2, i32 3, float {{.*}}, float {{.*}}, float {{.*}}, i32 4, i32 5, i32 6 }, align 4 + +VirtualInherits VI; +// CIR-BEFORE: cir.global external @VI = ctor : !rec_VirtualInherits { +// CIR-BEFORE: %[[GET_GLOB:.*]] = cir.get_global @VI : !cir.ptr<!rec_VirtualInherits> +// CIR-BEFORE: cir.call @_ZN15VirtualInheritsC1Ev(%[[GET_GLOB]]) nothrow : (!cir.ptr<!rec_VirtualInherits> {llvm.align = 8 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}) -> () +// CIR-BEFORE: } {alignment = 8 : i64, ast = #cir.var.decl.ast} +// +// CIR-AFTER: cir.global external @VI = #cir.zero : !rec_VirtualInherits {alignment = 8 : i64, ast = #cir.var.decl.ast} +// CIR-AFTER: cir.func {{.*}}@__cxx_global_var_init() { +// CIR-AFTER: %[[GET_GLOB:.*]] = cir.get_global @VI : !cir.ptr<!rec_VirtualInherits> loc(#loc13) +// CIR-AFTER: cir.call @_ZN15VirtualInheritsC1Ev(%[[GET_GLOB]]) nothrow : (!cir.ptr<!rec_VirtualInherits> {llvm.align = 8 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}) -> () + +// LLVM: @VI = global %struct.VirtualInherits zeroinitializer, align 8 +// LLVM: define internal void @__cxx_global_var_init() +// LLVM: call void @_ZN15VirtualInheritsC1Ev(ptr noundef nonnull align 8 dereferenceable(20) @VI) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
