Skip to content

Commit 5306ed3

Browse files
Apply reviews
1 parent c310c1f commit 5306ed3

File tree

4 files changed

+58
-4
lines changed

4 files changed

+58
-4
lines changed

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,33 @@ def CIR_VisibilityAttr : CIR_EnumAttr<CIR_VisibilityKind, "visibility"> {
460460
def BitfieldInfoAttr : CIR_Attr<"BitfieldInfo", "bitfield_info"> {
461461
let summary = "Represents a bit field info";
462462
let description = [{
463-
Holds the next information about bitfields: name, storage type, a bitfield
464-
size and position in the storage, if the bitfield is signed or not.
463+
Holds the following information about bitfields: name, storage type, size
464+
and position in the storage, and signedness.
465+
Example:
466+
Given the following struct with bitfields:
467+
```c++
468+
typedef struct {
469+
int a : 4;
470+
int b : 27;
471+
int c : 17;
472+
int d : 2;
473+
int e : 15;
474+
} S;
475+
```
476+
477+
The CIR representation of the struct `S` might look like:
478+
```mlir
479+
!rec_S = !cir.record<struct "S" packed padded {!u64i, !u16i,
480+
!cir.array<!u8i x 2>}>
481+
```
482+
And the bitfield info attribute for member `a` would be:
483+
```mlir
484+
#bfi_a = #cir.bitfield_info<name = "a", storage_type = !u64i,
485+
size = 4, offset = 0, is_signed = true>
486+
```
487+
488+
This metadata describes that field `a` is stored in a 64-bit integer,
489+
is 4 bits wide, starts at offset 0, and is signed.
465490
}];
466491
let parameters = (ins "mlir::StringAttr":$name,
467492
"mlir::Type":$storageType,

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,8 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
398398
mlir::Value addr, mlir::Type storageType,
399399
const CIRGenBitFieldInfo &info,
400400
bool isLvalueVolatile, bool useVolatile) {
401-
unsigned int offset = useVolatile ? info.volatileOffset : info.offset;
402401
return create<cir::GetBitfieldOp>(loc, resultType, addr, storageType,
403-
info.name, info.size, offset,
402+
info.name, info.size, info.offset,
404403
info.isSigned, isLvalueVolatile);
405404
}
406405
};

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ LValue CIRGenFunction::emitLValueForBitField(LValue base,
360360
cgm.getTypes().getCIRGenRecordLayout(field->getParent());
361361
const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field);
362362
assert(!cir::MissingFeatures::armComputeVolatileBitfields());
363+
assert(!cir::MissingFeatures::preservedAccessIndexRegion());
363364
unsigned idx = layout.getCIRFieldNo(field);
364365

365366
Address addr = getAddrOfBitFieldStorage(base, field, info.storageType, idx);

clang/test/CIR/CodeGen/bitfields.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ typedef struct {
1313
} A;
1414

1515
// CIR-DAG: !rec_A = !cir.record<struct "A" packed padded {!s8i, !s8i, !s8i, !u16i, !cir.array<!u8i x 3>}>
16+
// CIR-DAG: #bfi_more_bits = #cir.bitfield_info<name = "more_bits", storageType = !u16i, size = 4, offset = 3, isSigned = false>
1617
// LLVM-DAG: %struct.A = type <{ i8, i8, i8, i16, [3 x i8] }>
1718
// OGCG-DAG: %struct.A = type <{ i8, i8, i8, i16, [3 x i8] }>
1819

@@ -105,3 +106,31 @@ int load_field(S* s) {
105106
// OGCG: [[TMP3:%.*]] = shl i64 [[TMP2]], 15
106107
// OGCG: [[TMP4:%.*]] = ashr i64 [[TMP3]], 47
107108
// OGCG: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32
109+
110+
unsigned int load_field_unsigned(A* s) {
111+
return s->more_bits;
112+
}
113+
114+
//CIR: cir.func dso_local @load_field_unsigned
115+
//CIR: [[TMP0:%.*]] = cir.alloca !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>>, ["s", init] {alignment = 8 : i64}
116+
//CIR: [[TMP1:%.*]] = cir.load align(8) [[TMP0]] : !cir.ptr<!cir.ptr<!rec_A>>, !cir.ptr<!rec_A>
117+
//CIR: [[TMP2:%.*]] = cir.get_member [[TMP1]][3] {name = "more_bits"} : !cir.ptr<!rec_A> -> !cir.ptr<!u16i>
118+
//CIR: [[TMP3:%.*]] = cir.get_bitfield(#bfi_more_bits, [[TMP2]] : !cir.ptr<!u16i>) -> !u32i
119+
120+
//LLVM: define dso_local i32 @load_field_unsigned
121+
//LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
122+
//LLVM: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
123+
//LLVM: [[TMP2:%.*]] = getelementptr %struct.A, ptr [[TMP1]], i32 0, i32 3
124+
//LLVM: [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 2
125+
//LLVM: [[TMP4:%.*]] = lshr i16 [[TMP3]], 3
126+
//LLVM: [[TMP5:%.*]] = and i16 [[TMP4]], 15
127+
//LLVM: [[TMP6:%.*]] = zext i16 [[TMP5]] to i32
128+
129+
//OGCG: define dso_local i32 @load_field_unsigned
130+
//OGCG: [[TMP0:%.*]] = alloca ptr, align 8
131+
//OGCG: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
132+
//OGCG: [[TMP2:%.*]] = getelementptr inbounds nuw %struct.A, ptr [[TMP1]], i32 0, i32 3
133+
//OGCG: [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 1
134+
//OGCG: [[TMP4:%.*]] = lshr i16 [[TMP3]], 3
135+
//OGCG: [[TMP5:%.*]] = and i16 [[TMP4]], 15
136+
//OGCG: [[TMP6:%.*]] = zext i16 [[TMP5]] to i32

0 commit comments

Comments
 (0)