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

Conversation

Andres-Salamanca
Copy link
Contributor

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).

@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Jun 23, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 23, 2025

@llvm/pr-subscribers-clangir

@llvm/pr-subscribers-clang

Author: None (Andres-Salamanca)

Changes

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).


Full diff: https://github.com/llvm/llvm-project/pull/145414.diff

2 Files Affected:

  • (modified) clang/include/clang/CIR/MissingFeatures.h (+1)
  • (modified) clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp (+32-2)
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..a9465059d78da 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,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()) {

@bcardosolopes bcardosolopes changed the title [CIR] Upstream computeVolatileBitfields [CIR][NFC] Upstream computeVolatileBitfields Jun 23, 2025
Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense not having tests given all paths will lead to NYI, meaning this is more about skeleton. I renamed the PR to include "NFC" since it clarifies the intent

@Andres-Salamanca Andres-Salamanca merged commit 2767ff4 into llvm:main Jun 24, 2025
10 checks passed
DrSergei pushed a commit to DrSergei/llvm-project that referenced this pull request Jun 24, 2025
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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants