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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits