From 14e6bc00f2091799c6dc3b5838365831370e03d4 Mon Sep 17 00:00:00 2001 From: ghehg Date: Tue, 14 Jan 2025 06:00:05 -0800 Subject: [PATCH 1/2] [CIR][CIRGen][VTable] Vfp initialization without ctor --- clang/include/clang/CIR/MissingFeatures.h | 3 +++ clang/lib/CIR/CodeGen/CIRGenExprConst.cpp | 23 ++++++++++++++++++---- clang/test/CIR/CodeGen/vtable-emission.cpp | 16 ++++++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 8f9c5d3eff49..642cce63c08c 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -468,6 +468,9 @@ struct MissingFeatures { static bool mustProgress() { return false; } static bool skipTempCopy() { return false; } + + // https://clang.llvm.org/docs/PointerAuthentication.html + static bool pointerAuthentication() { return false; } }; } // namespace cir diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp index e5fda5a6bb15..936eca98b36d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp @@ -736,12 +736,27 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, const CXXRecordDecl *VTableClass, CharUnits Offset) { const ASTRecordLayout &Layout = CGM.getASTContext().getASTRecordLayout(RD); - if (const CXXRecordDecl *CD = dyn_cast(RD)) { // Add a vtable pointer, if we need one and it hasn't already been added. - if (Layout.hasOwnVFPtr()) - llvm_unreachable("NYI"); - + if (Layout.hasOwnVFPtr()) { + CIRGenBuilderTy &builder = CGM.getBuilder(); + cir::GlobalOp vtable = + CGM.getCXXABI().getAddrOfVTable(VTableClass, CharUnits()); + clang::VTableLayout::AddressPointLocation addressPoint = + CGM.getItaniumVTableContext() + .getVTableLayout(VTableClass) + .getAddressPoint(BaseSubobject(CD, Offset)); + assert(!cir::MissingFeatures::pointerAuthentication()); + mlir::ArrayAttr indices = builder.getArrayAttr({ + builder.getI32IntegerAttr(0), + builder.getI32IntegerAttr(addressPoint.VTableIndex), + builder.getI32IntegerAttr(addressPoint.AddressPointIndex), + }); + cir::GlobalViewAttr vtableInit = + CGM.getBuilder().getGlobalViewAttr(vtable, indices); + if (!AppendBytes(Offset, vtableInit)) + return false; + } // Accumulate and sort bases, in order to visit them in address order, which // may not be the same as declaration order. SmallVector Bases; diff --git a/clang/test/CIR/CodeGen/vtable-emission.cpp b/clang/test/CIR/CodeGen/vtable-emission.cpp index f63a9fe3cd97..6691167488c5 100644 --- a/clang/test/CIR/CodeGen/vtable-emission.cpp +++ b/clang/test/CIR/CodeGen/vtable-emission.cpp @@ -1,15 +1,29 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir // RUN: FileCheck --input-file=%t.cir %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -o - %s \ +// RUN: | opt -S -passes=instcombine,mem2reg,simplifycfg -o %t.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s struct S { virtual void key(); virtual void nonKey() {} -}; +} sobj; void S::key() {} +// CHECK-DAG: !ty_anon_struct1 = !cir.struct x 4>}> +// CHECK-DAG: !ty_anon_struct2 = !cir.struct}> + // The definition of the key function should result in the vtable being emitted. // CHECK: cir.global external @_ZTV1S = #cir.vtable +// LLVM: @_ZTV1S = global { [4 x ptr] } { [4 x ptr] +// LLVM-SAME: [ptr null, ptr @_ZTI1S, ptr @_ZN1S3keyEv, ptr @_ZN1S6nonKeyEv] }, align 8 + +// CHECK: cir.global external @sobj = #cir.const_struct +// CHECK-SAME: <{#cir.global_view<@_ZTV1S, [0 : i32, 0 : i32, 2 : i32]> : +// CHECK-SAME: !cir.ptr}> : !ty_anon_struct2 {alignment = 8 : i64} +// LLVM: @sobj = global { ptr } { ptr getelementptr inbounds +// LLVM-SAME: ({ [4 x ptr] }, ptr @_ZTV1S, i32 0, i32 0, i32 2) }, align 8 // The reference from the vtable should result in nonKey being emitted. // CHECK: cir.func linkonce_odr @_ZN1S6nonKeyEv({{.*}} { From 460ac4856aa81cd704b80fa50ed29d0eb4e44d20 Mon Sep 17 00:00:00 2001 From: ghehg Date: Tue, 14 Jan 2025 13:09:57 -0800 Subject: [PATCH 2/2] get rid of duplicated missing feature --- clang/include/clang/CIR/MissingFeatures.h | 3 --- clang/lib/CIR/CodeGen/CIRGenExprConst.cpp | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 642cce63c08c..8f9c5d3eff49 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -468,9 +468,6 @@ struct MissingFeatures { static bool mustProgress() { return false; } static bool skipTempCopy() { return false; } - - // https://clang.llvm.org/docs/PointerAuthentication.html - static bool pointerAuthentication() { return false; } }; } // namespace cir diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp index 936eca98b36d..b15b7f3aaf2e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp @@ -746,7 +746,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, CGM.getItaniumVTableContext() .getVTableLayout(VTableClass) .getAddressPoint(BaseSubobject(CD, Offset)); - assert(!cir::MissingFeatures::pointerAuthentication()); + assert(!cir::MissingFeatures::ptrAuth()); mlir::ArrayAttr indices = builder.getArrayAttr({ builder.getI32IntegerAttr(0), builder.getI32IntegerAttr(addressPoint.VTableIndex),