[clang] [CIR] Get Lvalue for bit-field (PR #145971)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 26 14:01:59 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: None (Andres-Salamanca)
<details>
<summary>Changes</summary>
This PR adds support for retrieving a bitfield member. It obtains the member in which the bitfield is packed but does not emit the load operation, as the address will be computed later using the get_bitfield operation.
---
Full diff: https://github.com/llvm/llvm-project/pull/145971.diff
5 Files Affected:
- (modified) clang/include/clang/CIR/MissingFeatures.h (+1)
- (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+43-4)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+4)
- (modified) clang/lib/CIR/CodeGen/CIRGenValue.h (+19)
- (modified) clang/test/CIR/CodeGen/bitfields.c (+8)
``````````diff
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 9e8944d1114b8..e136d73daac89 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -200,6 +200,7 @@ struct MissingFeatures {
static bool fastMathFlags() { return false; }
static bool fpConstraints() { return false; }
static bool generateDebugInfo() { return false; }
+ static bool getBitfieldOp() { return false; }
static bool hip() { return false; }
static bool implicitConstructorArgs() { return false; }
static bool incrementProfileCounter() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 5c6604d784156..a3d24e92c701a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -326,13 +326,47 @@ mlir::Value CIRGenFunction::emitStoreThroughBitfieldLValue(RValue src,
return {};
}
+Address CIRGenFunction::getAddrOfBitFieldStorage(LValue base,
+ const FieldDecl *field,
+ mlir::Type fieldType,
+ unsigned index) {
+ if (index == 0)
+ return base.getAddress();
+ mlir::Location loc = getLoc(field->getLocation());
+ cir::PointerType fieldPtr = cir::PointerType::get(fieldType);
+ cir::GetMemberOp sea = getBuilder().createGetMember(
+ loc, fieldPtr, base.getPointer(), field->getName(), index);
+ return Address(sea, CharUnits::One());
+}
+
+LValue CIRGenFunction::emitLValueForBitField(LValue base,
+ const FieldDecl *field) {
+ LValueBaseInfo baseInfo = base.getBaseInfo();
+ const CIRGenRecordLayout &layout =
+ cgm.getTypes().getCIRGenRecordLayout(field->getParent());
+ const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field);
+ assert(!cir::MissingFeatures::armComputeVolatileBitfields());
+ unsigned idx = layout.getCIRFieldNo(field);
+
+ Address addr = getAddrOfBitFieldStorage(base, field, info.storageType, idx);
+
+ mlir::Location loc = getLoc(field->getLocation());
+ if (addr.getElementType() != info.storageType)
+ addr = builder.createElementBitCast(loc, addr, info.storageType);
+
+ QualType fieldType =
+ field->getType().withCVRQualifiers(base.getVRQualifiers());
+ // TODO(cir): Support TBAA for bit fields.
+ assert(!cir::MissingFeatures::opTBAA());
+ LValueBaseInfo fieldBaseInfo(baseInfo.getAlignmentSource());
+ return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo);
+}
+
LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
LValueBaseInfo baseInfo = base.getBaseInfo();
- if (field->isBitField()) {
- cgm.errorNYI(field->getSourceRange(), "emitLValueForField: bitfield");
- return LValue();
- }
+ if (field->isBitField())
+ return emitLValueForBitField(base, field);
QualType fieldType = field->getType();
const RecordDecl *rec = field->getParent();
@@ -460,6 +494,11 @@ RValue CIRGenFunction::emitLoadOfLValue(LValue lv, SourceLocation loc) {
assert(!lv.getType()->isFunctionType());
assert(!(lv.getType()->isConstantMatrixType()) && "not implemented");
+ if (lv.isBitField()) {
+ assert(!cir::MissingFeatures::getBitfieldOp());
+ return RValue::getIgnored();
+ }
+
if (lv.isSimple())
return RValue::get(emitLoadOfScalar(lv, loc));
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 2e54243f18cff..5139bc8249b3d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -550,6 +550,9 @@ class CIRGenFunction : public CIRGenTypeCache {
return it->second;
}
+ Address getAddrOfBitFieldStorage(LValue base, const clang::FieldDecl *field,
+ mlir::Type fieldType, unsigned index);
+
/// Load the value for 'this'. This function is only valid while generating
/// code for an C++ member function.
/// FIXME(cir): this should return a mlir::Value!
@@ -964,6 +967,7 @@ class CIRGenFunction : public CIRGenTypeCache {
/// of the expression.
/// FIXME: document this function better.
LValue emitLValue(const clang::Expr *e);
+ LValue emitLValueForBitField(LValue base, const FieldDecl *field);
LValue emitLValueForField(LValue base, const clang::FieldDecl *field);
/// Like emitLValueForField, excpet that if the Field is a reference, this
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h b/clang/lib/CIR/CodeGen/CIRGenValue.h
index a5a457ddafa9c..2d6bdb921c9fa 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -19,6 +19,7 @@
#include "clang/AST/CharUnits.h"
#include "clang/AST/Type.h"
+#include "CIRGenRecordLayout.h"
#include "mlir/IR/Value.h"
#include "clang/CIR/MissingFeatures.h"
@@ -162,6 +163,7 @@ class LValue {
mlir::Value vectorIdx; // Index for vector subscript
mlir::Type elementType;
LValueBaseInfo baseInfo;
+ const CIRGenBitFieldInfo *bitFieldInfo{nullptr};
void initialize(clang::QualType type, clang::Qualifiers quals,
clang::CharUnits alignment, LValueBaseInfo baseInfo) {
@@ -245,6 +247,23 @@ class LValue {
r.initialize(t, t.getQualifiers(), vecAddress.getAlignment(), baseInfo);
return r;
}
+
+ /// Create a new object to represent a bit-field access.
+ ///
+ /// \param Addr - The base address of the bit-field sequence this
+ /// bit-field refers to.
+ /// \param Info - The information describing how to perform the bit-field
+ /// access.
+ static LValue makeBitfield(Address addr, const CIRGenBitFieldInfo &info,
+ clang::QualType type, LValueBaseInfo baseInfo) {
+ LValue r;
+ r.lvType = BitField;
+ r.v = addr.getPointer();
+ r.elementType = addr.getElementType();
+ r.bitFieldInfo = &info;
+ r.initialize(type, type.getQualifiers(), addr.getAlignment(), baseInfo);
+ return r;
+ }
};
/// An aggregate value slot.
diff --git a/clang/test/CIR/CodeGen/bitfields.c b/clang/test/CIR/CodeGen/bitfields.c
index ff5c6bc1787b4..4cc1fc69ecc5a 100644
--- a/clang/test/CIR/CodeGen/bitfields.c
+++ b/clang/test/CIR/CodeGen/bitfields.c
@@ -76,3 +76,11 @@ void def() {
T t;
U u;
}
+
+// CIR: cir.func {{.*@load_field}}
+// CIR: [[TMP0:%.*]] = cir.alloca !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>, ["s", init]
+// CIR: [[TMP1:%.*]] = cir.load{{.*}} [[TMP0]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
+// CIR: [[TMP2:%.*]] = cir.get_member %2[1] {name = "e"} : !cir.ptr<!rec_S> -> !cir.ptr<!u16i>
+int load_field(S* s) {
+ return s->e;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/145971
More information about the cfe-commits
mailing list