[clang] [CIR] Upstream computeVolatileBitfields (PR #145414)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 23 14:51:10 PDT 2025
https://github.com/Andres-Salamanca created https://github.com/llvm/llvm-project/pull/145414
This PR upstreams functionality for computing volatile bitfields when the target follows the AAPCS ABI. The implementation matches the one in the incubator, so no tests are included as the feature is not yet fully implemented (NYI).
>From e8023f7eb100d8acc934cfa98094ec9c55037c6d Mon Sep 17 00:00:00 2001
From: Andres Salamanca <andrealebarbaritos at gmail.com>
Date: Mon, 23 Jun 2025 16:39:22 -0500
Subject: [PATCH 1/2] Upstream computeVolatileBitfields
---
clang/include/clang/CIR/MissingFeatures.h | 1 +
.../CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 32 +++++++++++++++++--
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index e0b2959f374f8..d610f9bd91677 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -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; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
index 8dbf1b36a93b2..008384733585b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
@@ -79,6 +79,7 @@ struct CIRRecordLowering final {
/// Inserts padding everywhere it's needed.
void insertPadding();
+ void computeVolatileBitfields();
void accumulateBases(const CXXRecordDecl *cxxRecordDecl);
void accumulateVPtrs();
void accumulateFields();
@@ -86,6 +87,10 @@ struct CIRRecordLowering final {
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);
}
@@ -238,7 +243,7 @@ void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
void CIRRecordLowering::lower() {
if (recordDecl->isUnion()) {
lowerUnion();
- assert(!cir::MissingFeatures::bitfields());
+ computeVolatileBitfields();
return;
}
@@ -252,7 +257,7 @@ void CIRRecordLowering::lower() {
accumulateBases(cxxRecordDecl);
if (members.empty()) {
appendPaddingBytes(size);
- assert(!cir::MissingFeatures::bitfields());
+ computeVolatileBitfields();
return;
}
assert(!cir::MissingFeatures::recordLayoutVirtualBases());
@@ -270,6 +275,7 @@ void CIRRecordLowering::lower() {
calculateZeroInit();
fillOutputFields();
+ computeVolatileBitfields();
}
void CIRRecordLowering::fillOutputFields() {
@@ -711,6 +717,28 @@ 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());
+}
+
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()) {
>From c7107abf9319336332aae6fa2c01391a6e58c2f1 Mon Sep 17 00:00:00 2001
From: Andres Salamanca <andrealebarbaritos at gmail.com>
Date: Mon, 23 Jun 2025 16:49:35 -0500
Subject: [PATCH 2/2] Add error NYI
---
clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
index 008384733585b..a9465059d78da 100644
--- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
@@ -735,8 +735,10 @@ void CIRRecordLowering::computeVolatileBitfields() {
!cirGenTypes.getCGModule().getCodeGenOpts().AAPCSBitfieldWidth)
return;
- for ([[maybe_unused]] auto &I : bitFields)
+ for ([[maybe_unused]] auto &I : bitFields) {
assert(!cir::MissingFeatures::armComputeVolatileBitfields());
+ cirGenTypes.getCGModule().errorNYI("NYI AAPCS bit-fields");
+ }
}
void CIRRecordLowering::accumulateBases(const CXXRecordDecl *cxxRecordDecl) {
More information about the cfe-commits
mailing list