Skip to content

[CIR][NFC] Upstream computeVolatileBitfields #145414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ struct MissingFeatures {
static bool builtinCallF128() { return false; }
static bool builtinCallMathErrno() { return false; }
static bool nonFineGrainedBitfields() { return false; }
static bool armComputeVolatileBitfields() { return false; }

// Missing types
static bool dataMemberType() { return false; }
Expand Down
34 changes: 32 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,18 @@ struct CIRRecordLowering final {
/// Inserts padding everywhere it's needed.
void insertPadding();

void computeVolatileBitfields();
void accumulateBases(const CXXRecordDecl *cxxRecordDecl);
void accumulateVPtrs();
void accumulateFields();
RecordDecl::field_iterator
accumulateBitFields(RecordDecl::field_iterator field,
RecordDecl::field_iterator fieldEnd);

bool isAAPCS() const {
return astContext.getTargetInfo().getABI().starts_with("aapcs");
}

CharUnits bitsToCharUnits(uint64_t bitOffset) {
return astContext.toCharUnitsFromBits(bitOffset);
}
Expand Down Expand Up @@ -238,7 +243,7 @@ void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
void CIRRecordLowering::lower() {
if (recordDecl->isUnion()) {
lowerUnion();
assert(!cir::MissingFeatures::bitfields());
computeVolatileBitfields();
return;
}

Expand All @@ -252,7 +257,7 @@ void CIRRecordLowering::lower() {
accumulateBases(cxxRecordDecl);
if (members.empty()) {
appendPaddingBytes(size);
assert(!cir::MissingFeatures::bitfields());
computeVolatileBitfields();
return;
}
assert(!cir::MissingFeatures::recordLayoutVirtualBases());
Expand All @@ -270,6 +275,7 @@ void CIRRecordLowering::lower() {

calculateZeroInit();
fillOutputFields();
computeVolatileBitfields();
}

void CIRRecordLowering::fillOutputFields() {
Expand Down Expand Up @@ -711,6 +717,30 @@ void CIRRecordLowering::lowerUnion() {
packed = true;
}

/// The AAPCS that defines that, when possible, bit-fields should
/// be accessed using containers of the declared type width:
/// When a volatile bit-field is read, and its container does not overlap with
/// any non-bit-field member or any zero length bit-field member, its container
/// must be read exactly once using the access width appropriate to the type of
/// the container. When a volatile bit-field is written, and its container does
/// not overlap with any non-bit-field member or any zero-length bit-field
/// member, its container must be read exactly once and written exactly once
/// using the access width appropriate to the type of the container. The two
/// accesses are not atomic.
///
/// Enforcing the width restriction can be disabled using
/// -fno-aapcs-bitfield-width.
void CIRRecordLowering::computeVolatileBitfields() {
if (!isAAPCS() ||
!cirGenTypes.getCGModule().getCodeGenOpts().AAPCSBitfieldWidth)
return;

for ([[maybe_unused]] auto &I : bitFields) {
assert(!cir::MissingFeatures::armComputeVolatileBitfields());
cirGenTypes.getCGModule().errorNYI("NYI AAPCS bit-fields");
}
}

void CIRRecordLowering::accumulateBases(const CXXRecordDecl *cxxRecordDecl) {
// If we've got a primary virtual base, we need to add it with the bases.
if (astRecordLayout.isPrimaryBaseVirtual()) {
Expand Down
Loading