[clang] [CIR] Record how far a bit-field's declared types extend on x86_64 (PR #220069)
@@ -79,6 +79,35 @@ struct CIRRecordLowering final {
cir::ArrayType::get(cirGenTypes.convertTypeForMem(field->getType()),
0),
cir::RecordMemberKind::BitField);
}
+
+ /// An access unit can be narrower than the types its bit-fields were
+ /// declared with. In `struct { int a : 4; int b : 11; int c : 17; }` all
+ /// three share one 4-byte unit, but `c` is declared `int`, so the declared
+ /// data runs 15 bits past the unit:
+ ///
+ /// |-a-|b-|---c|
+ /// |- 4-byte unit -|--- extent ---|
+ /// |-- c declared as int --|
+ /// 0 4 15 32 47 bits
adams381 wrote:
That example explains the concept but not the motivation. Consider this example
```c
typedef struct { long long x : 32; } Wide;
typedef struct { int x : 32; } __attribute__((aligned(8))) Narrow;
```
`Wide` needs: `i64`
`Narrow` needs: `i32`
Currently we generate
```mlir
!rec_Narrow = !cir.struct<"Narrow" {bitfield !u32i, pad !cir.array}>
!rec_Wide = !cir.struct<"Wide" {bitfield !u32i, bitfield
!cir.array x 0>, pad !cir.array}>
```
Without the extent member, the two types are identical.
https://github.com/llvm/llvm-project/pull/220069
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Record how far a bit-field's declared types extend on x86_64 (PR #220069)
https://github.com/andykaylor edited https://github.com/llvm/llvm-project/pull/220069 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Record how far a bit-field's declared types extend on x86_64 (PR #220069)
@@ -79,6 +79,35 @@ struct CIRRecordLowering final {
cir::ArrayType::get(cirGenTypes.convertTypeForMem(field->getType()),
0),
cir::RecordMemberKind::BitField);
}
+
+ /// An access unit can be narrower than the types its bit-fields were
+ /// declared with. In `struct { int a : 4; int b : 11; int c : 17; }` all
+ /// three share one 4-byte unit, but `c` is declared `int`, so the declared
+ /// data runs 15 bits past the unit:
+ ///
+ /// |-a-|b-|---c|
+ /// |- 4-byte unit -|--- extent ---|
+ /// |-- c declared as int --|
+ /// 0 4 15 32 47 bits
andykaylor wrote:
I don't understand this example. Since a, b, and c, all fit within a single
32-bit integer, there is no need for c to extend beyond the 32 bits. Why are we
recording anything here?
https://github.com/llvm/llvm-project/pull/220069
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Record how far a bit-field's declared types extend on x86_64 (PR #220069)
https://github.com/andykaylor commented:
I really hate the fact that we're inserting something in the IR that survives
lowering to LLVM IR just as a hint to the calling convention lowering pass.
I'm going to experiment with introducing a new type to describe a bitfield. So
`struct S { unsigned a : 2; unsigned b : 5; unsigned c : 1; };`
would be represented in CIR like:
`!rec_S { data !cir.bitfield, data !cir.bitfield, data
!cir.bitfield };`
I think this would solve both the extent problem and the zero-length bitfield
problem. It could also allow us to get rid of `#cir.bitfield_info`.
https://github.com/llvm/llvm-project/pull/220069
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Record how far a bit-field's declared types extend on x86_64 (PR #220069)
@@ -79,6 +79,25 @@ struct CIRRecordLowering final {
cir::ArrayType::get(cirGenTypes.convertTypeForMem(field->getType()),
0),
cir::RecordMemberKind::BitField);
}
+
+ /// An access unit can be narrower than the types its bit-fields were
+ /// declared with, so the unit's extent does not say how far the declared
+ /// data runs. This member carries the difference: the declared extent ends
+ /// \p excessInBits past \p offset. It holds no storage, taking the same
+ /// zero-length-array shape as a zero-width bit-field so the record layout
+ /// walks skip it.
erichkeane wrote:
Can we get a quick example here? I'm still not getting th is.
https://github.com/llvm/llvm-project/pull/220069
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Record how far a bit-field's declared types extend on x86_64 (PR #220069)
@@ -572,21 +572,27 @@ void UnionType::complete(ArrayRef members, bool
packed,
mlir::Type
UnionType::getUnionStorageType(const mlir::DataLayout &dataLayout) const {
- return getUnionStorageType(dataLayout, getMembers());
+ return getUnionStorageType(dataLayout, getMembers(), getMemberKinds());
}
-mlir::Type UnionType::getUnionStorageType(const mlir::DataLayout &dataLayout,
- llvm::ArrayRef members) {
- if (members.empty())
-return {};
- return *std::max_element(
- members.begin(), members.end(), [&](mlir::Type lhs, mlir::Type rhs) {
-return dataLayout.getTypeABIAlignment(lhs) <
- dataLayout.getTypeABIAlignment(rhs) ||
- (dataLayout.getTypeABIAlignment(lhs) ==
-dataLayout.getTypeABIAlignment(rhs) &&
-dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs));
- });
+mlir::Type
+UnionType::getUnionStorageType(const mlir::DataLayout &dataLayout,
+ llvm::ArrayRef members,
+ llvm::ArrayRef kinds) {
+ // A member occupying no storage cannot be the storage.
+ mlir::Type storage;
+ for (auto [memberTy, kind] : llvm::zip_equal(members, kinds)) {
+if (isZeroWidthBitField(memberTy, kind))
erichkeane wrote:
I'd suggest just doing this with a filter iterator. This loop is actually
quite touch to read in a way that max_element did well.
So just extract the `isZeroWidthBitField` into a filter-range.
https://github.com/llvm/llvm-project/pull/220069
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Record how far a bit-field's declared types extend on x86_64 (PR #220069)
https://github.com/adams381 edited https://github.com/llvm/llvm-project/pull/220069 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Record how far a bit-field's declared types extend on x86_64 (PR #220069)
https://github.com/adams381 edited https://github.com/llvm/llvm-project/pull/220069 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
