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

Reply via email to