[clang] 8a25f95 - [CIR] Implement non-odr use of reference type lowering (#185720)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 11 06:26:17 PDT 2026
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
+}
More information about the cfe-commits
mailing list