Skip to content

Commit 8a25f95

Browse files
authored
[CIR] Implement non-odr use of reference type lowering (llvm#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.
1 parent 1ea11e4 commit 8a25f95

5 files changed

Lines changed: 56 additions & 6 deletions

File tree

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ struct MissingFeatures {
206206
static bool aggValueSlotGC() { return false; }
207207
static bool aggValueSlotMayOverlap() { return false; }
208208
static bool aggValueSlotVolatile() { return false; }
209-
static bool alignCXXRecordDecl() { return false; }
210209
static bool allocToken() { return false; }
211210
static bool appleArm64CXXABI() { return false; }
212211
static bool appleKext() { return false; }

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -902,8 +902,17 @@ LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *e) {
902902
addr = addr.withElementType(builder, varTy);
903903
}
904904
} else {
905-
cgm.errorNYI(e->getSourceRange(),
906-
"emitDeclRefLValue: non-odr reference type");
905+
// Should we be using the alignment of the constant pointer we emitted?
906+
CharUnits alignment =
907+
cgm.getNaturalTypeAlignment(e->getType(),
908+
/*BaseInfo=*/nullptr,
909+
/*forPointeeType=*/true);
910+
// Classic codegen passes TBAA as null-ptr to the above function, so it
911+
// probably needs to deal with that.
912+
assert(!cir::MissingFeatures::opTBAA());
913+
mlir::Value ptrVal = getBuilder().getConstant(
914+
getLoc(e->getSourceRange()), mlir::cast<mlir::TypedAttr>(val));
915+
addr = makeNaturalAddressForPointer(ptrVal, ty, alignment);
907916
}
908917
return makeAddrLValue(addr, ty, AlignmentSource::Decl);
909918
}

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ CharUnits CIRGenModule::getClassPointerAlignment(const CXXRecordDecl *rd) {
176176
}
177177

178178
CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t,
179-
LValueBaseInfo *baseInfo) {
179+
LValueBaseInfo *baseInfo,
180+
bool forPointeeType) {
180181
assert(!cir::MissingFeatures::opTBAA());
181182

182183
// FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown, but
@@ -193,6 +194,8 @@ CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t,
193194
}
194195
}
195196

197+
bool alignForArray = t->isArrayType();
198+
196199
// Analyze the base element type, so we don't get confused by incomplete
197200
// array types.
198201
t = astContext.getBaseElementType(t);
@@ -213,10 +216,13 @@ CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t,
213216
*baseInfo = LValueBaseInfo(AlignmentSource::Type);
214217

215218
CharUnits alignment;
219+
const CXXRecordDecl *rd = nullptr;
216220
if (t.getQualifiers().hasUnaligned()) {
217221
alignment = CharUnits::One();
222+
} else if (forPointeeType && !alignForArray &&
223+
(rd = t->getAsCXXRecordDecl())) {
224+
alignment = getClassPointerAlignment(rd);
218225
} else {
219-
assert(!cir::MissingFeatures::alignCXXRecordDecl());
220226
alignment = astContext.getTypeAlignInChars(t);
221227
}
222228

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,8 @@ class CIRGenModule : public CIRGenTypeCache {
396396
/// FIXME: this could likely be a common helper and not necessarily related
397397
/// with codegen.
398398
clang::CharUnits getNaturalTypeAlignment(clang::QualType t,
399-
LValueBaseInfo *baseInfo = nullptr);
399+
LValueBaseInfo *baseInfo = nullptr,
400+
bool forPointeeType = false);
400401

401402
/// Returns the minimum object size for an object of the given class type
402403
/// (or a class derived from it).
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
5+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
7+
8+
static int a[10]{};
9+
// CIR: cir.global "private" internal dso_local @_ZL1a = #cir.zero : !cir.array<!s32i x 10> {alignment = 16 : i64}
10+
// LLVM: @_ZL1a = internal global [10 x i32] zeroinitializer, align 16
11+
12+
struct NonTrivialDestructor {
13+
~NonTrivialDestructor();
14+
};
15+
struct BiggerNonTrivialDestructor {
16+
int array[12];
17+
~BiggerNonTrivialDestructor();
18+
};
19+
20+
void use() {
21+
for (int i : a) {}
22+
// This happens 3x (range + begin + end), but they all use the same code, sox
23+
// only test it 1x. Ensure the alignment is correct.
24+
// CIR: %[[GLOBAL_A:.*]] = cir.const #cir.global_view<@_ZL1a> : !cir.ptr<!cir.array<!s32i x 10>>
25+
// CIR: cir.store align(8) %[[GLOBAL_A]], %{{.*}} : !cir.ptr<!cir.array<!s32i x 10>>, !cir.ptr<!cir.ptr<!cir.array<!s32i x 10>>>
26+
// LLVM: store ptr getelementptr inbounds nuw (i8, ptr @_ZL1a, i64 40), ptr %{{.*}}, align 8
27+
28+
// Make sure we get alignment correct here.
29+
NonTrivialDestructor a;
30+
// CIR-DAG: cir.call @_ZN20NonTrivialDestructorD1Ev{{.*}}llvm.align = 1
31+
// LLVM-DAG: call void @_ZN20NonTrivialDestructorD1Ev(ptr {{.*}}align 1
32+
BiggerNonTrivialDestructor b;
33+
// CIR-DAG: cir.call @_ZN26BiggerNonTrivialDestructorD1Ev{{.*}}llvm.align = 4
34+
// LLVM-DAG: call void @_ZN26BiggerNonTrivialDestructorD1Ev(ptr {{.*}}align 4
35+
}

0 commit comments

Comments
 (0)