Author: Erich Keane Date: 2026-03-11T06:26:13-07:00 New Revision: 8a25f9534a4176ff7b514b54952933f7d4d156b4
URL: https://github.com/llvm/llvm-project/commit/8a25f9534a4176ff7b514b54952933f7d4d156b4 DIFF: https://github.com/llvm/llvm-project/commit/8a25f9534a4176ff7b514b54952933f7d4d156b4.diff LOG: [CIR] Implement non-odr use of reference type lowering (#185720) This is used somewhat rarely, but is a pretty simple emission of pointers, and ends up using infrastructure we already have. Additionally, this is the first use of `getNaturalTypeAlignment` that uses the `pointee` argument, so this adds the implementation there, which includes some alignment work for CXXRecordDecls, so this implements that as well. Added: clang/test/CIR/CodeGen/non-odr-use-non-ref.cpp Modified: clang/include/clang/CIR/MissingFeatures.h clang/lib/CIR/CodeGen/CIRGenExpr.cpp clang/lib/CIR/CodeGen/CIRGenModule.cpp clang/lib/CIR/CodeGen/CIRGenModule.h Removed: ################################################################################ diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 17fd3b19638fd..8997e408a2d79 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -206,7 +206,6 @@ struct MissingFeatures { static bool aggValueSlotGC() { return false; } static bool aggValueSlotMayOverlap() { return false; } static bool aggValueSlotVolatile() { return false; } - static bool alignCXXRecordDecl() { return false; } static bool allocToken() { return false; } static bool appleArm64CXXABI() { return false; } static bool appleKext() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 396b66c261727..1f08ba773dfb5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -902,8 +902,17 @@ LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *e) { addr = addr.withElementType(builder, varTy); } } else { - cgm.errorNYI(e->getSourceRange(), - "emitDeclRefLValue: non-odr reference type"); + // Should we be using the alignment of the constant pointer we emitted? + CharUnits alignment = + cgm.getNaturalTypeAlignment(e->getType(), + /*BaseInfo=*/nullptr, + /*forPointeeType=*/true); + // Classic codegen passes TBAA as null-ptr to the above function, so it + // probably needs to deal with that. + assert(!cir::MissingFeatures::opTBAA()); + mlir::Value ptrVal = getBuilder().getConstant( + getLoc(e->getSourceRange()), mlir::cast<mlir::TypedAttr>(val)); + addr = makeNaturalAddressForPointer(ptrVal, ty, alignment); } return makeAddrLValue(addr, ty, AlignmentSource::Decl); } diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 10168792cd730..56c87eac339d0 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -176,7 +176,8 @@ CharUnits CIRGenModule::getClassPointerAlignment(const CXXRecordDecl *rd) { } CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t, - LValueBaseInfo *baseInfo) { + LValueBaseInfo *baseInfo, + bool forPointeeType) { assert(!cir::MissingFeatures::opTBAA()); // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown, but @@ -193,6 +194,8 @@ CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t, } } + bool alignForArray = t->isArrayType(); + // Analyze the base element type, so we don't get confused by incomplete // array types. t = astContext.getBaseElementType(t); @@ -213,10 +216,13 @@ CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t, *baseInfo = LValueBaseInfo(AlignmentSource::Type); CharUnits alignment; + const CXXRecordDecl *rd = nullptr; if (t.getQualifiers().hasUnaligned()) { alignment = CharUnits::One(); + } else if (forPointeeType && !alignForArray && + (rd = t->getAsCXXRecordDecl())) { + alignment = getClassPointerAlignment(rd); } else { - assert(!cir::MissingFeatures::alignCXXRecordDecl()); alignment = astContext.getTypeAlignInChars(t); } diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index d2f7642451b22..bef154955b9b6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -396,7 +396,8 @@ class CIRGenModule : public CIRGenTypeCache { /// FIXME: this could likely be a common helper and not necessarily related /// with codegen. clang::CharUnits getNaturalTypeAlignment(clang::QualType t, - LValueBaseInfo *baseInfo = nullptr); + LValueBaseInfo *baseInfo = nullptr, + bool forPointeeType = false); /// Returns the minimum object size for an object of the given class type /// (or a class derived from it). diff --git a/clang/test/CIR/CodeGen/non-odr-use-non-ref.cpp b/clang/test/CIR/CodeGen/non-odr-use-non-ref.cpp new file mode 100644 index 0000000000000..8777634debca3 --- /dev/null +++ b/clang/test/CIR/CodeGen/non-odr-use-non-ref.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM + +static int a[10]{}; +// CIR: cir.global "private" internal dso_local @_ZL1a = #cir.zero : !cir.array<!s32i x 10> {alignment = 16 : i64} +// LLVM: @_ZL1a = internal global [10 x i32] zeroinitializer, align 16 + +struct NonTrivialDestructor { + ~NonTrivialDestructor(); +}; +struct BiggerNonTrivialDestructor { + int array[12]; + ~BiggerNonTrivialDestructor(); +}; + +void use() { + for (int i : a) {} + // This happens 3x (range + begin + end), but they all use the same code, sox + // only test it 1x. Ensure the alignment is correct. + // CIR: %[[GLOBAL_A:.*]] = cir.const #cir.global_view<@_ZL1a> : !cir.ptr<!cir.array<!s32i x 10>> + // CIR: cir.store align(8) %[[GLOBAL_A]], %{{.*}} : !cir.ptr<!cir.array<!s32i x 10>>, !cir.ptr<!cir.ptr<!cir.array<!s32i x 10>>> + // LLVM: store ptr getelementptr inbounds nuw (i8, ptr @_ZL1a, i64 40), ptr %{{.*}}, align 8 + + // Make sure we get alignment correct here. + NonTrivialDestructor a; + // CIR-DAG: cir.call @_ZN20NonTrivialDestructorD1Ev{{.*}}llvm.align = 1 + // LLVM-DAG: call void @_ZN20NonTrivialDestructorD1Ev(ptr {{.*}}align 1 + BiggerNonTrivialDestructor b; + // CIR-DAG: cir.call @_ZN26BiggerNonTrivialDestructorD1Ev{{.*}}llvm.align = 4 + // LLVM-DAG: call void @_ZN26BiggerNonTrivialDestructorD1Ev(ptr {{.*}}align 4 +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
