Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ef47da5

Browse files
566hubsmeenai
authored andcommittedOct 9, 2024
[CIR][CIRGen] Achieve union's bitfields additionally. (llvm#742)
Achieve union's bitfields additionally.
1 parent 40bd592 commit ef47da5

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed
 

‎clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,6 @@ void CIRRecordLowering::lower(bool nonVirtualBaseType) {
271271

272272
CharUnits Size = nonVirtualBaseType ? astRecordLayout.getNonVirtualSize()
273273
: astRecordLayout.getSize();
274-
if (recordDecl->isUnion()) {
275-
llvm_unreachable("NYI");
276-
// lowerUnion();
277-
// computeVolatileBitfields();
278-
return;
279-
}
280274
accumulateFields();
281275

282276
// RD implies C++
@@ -316,13 +310,20 @@ void CIRRecordLowering::lowerUnion() {
316310
// type would work fine and be simpler but would be different than what we've
317311
// been doing and cause lit tests to change.
318312
for (const auto *Field : recordDecl->fields()) {
313+
314+
mlir::Type FieldType = nullptr;
319315
if (Field->isBitField()) {
320316
if (Field->isZeroLengthBitField(astContext))
321317
continue;
322-
llvm_unreachable("NYI");
318+
319+
FieldType = getBitfieldStorageType(Field->getBitWidthValue(astContext));
320+
321+
setBitFieldInfo(Field, CharUnits::Zero(), FieldType);
322+
} else {
323+
FieldType = getStorageType(Field);
323324
}
324325
fields[Field->getCanonicalDecl()] = 0;
325-
auto FieldType = getStorageType(Field);
326+
// auto FieldType = getStorageType(Field);
326327
// Compute zero-initializable status.
327328
// This union might not be zero initialized: it may contain a pointer to
328329
// data member which might have some exotic initialization sequence.
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
4+
void main() {
5+
union demo {
6+
int x;
7+
int y : 4;
8+
int z : 8;
9+
};
10+
union demo d;
11+
d.x = 1;
12+
d.y = 2;
13+
d.z = 0;
14+
}
15+
16+
// CHECK: !ty_22demo22 = !cir.struct<union "demo" {!s32i, !u8i, !u8i}>
17+
// CHECK: #bfi_y = #cir.bitfield_info<name = "y", storage_type = !u8i, size = 4, offset = 0, is_signed = true>
18+
// CHECK: #bfi_z = #cir.bitfield_info<name = "z", storage_type = !u8i, size = 8, offset = 0, is_signed = true>
19+
20+
// cir.func no_proto @main() extra(#fn_attr) {
21+
// %0 = cir.alloca !ty_22demo22, !cir.ptr<!ty_22demo22>, ["d"] {alignment = 4 : i64}
22+
// %1 = cir.const #cir.int<1> : !s32i
23+
// %2 = cir.get_member %0[0] {name = "x"} : !cir.ptr<!ty_22demo22> -> !cir.ptr<!s32i>
24+
// cir.store %1, %2 : !s32i, !cir.ptr<!s32i>
25+
// %3 = cir.const #cir.int<2> : !s32i
26+
// %4 = cir.cast(bitcast, %0 : !cir.ptr<!ty_22demo22>), !cir.ptr<!u8i>
27+
// %5 = cir.set_bitfield(#bfi_y, %4 : !cir.ptr<!u8i>, %3 : !s32i) -> !s32i
28+
// %6 = cir.const #cir.int<0> : !s32i loc(#loc10)
29+
// %7 = cir.cast(bitcast, %0 : !cir.ptr<!ty_22demo22>), !cir.ptr<!u8i>
30+
// %8 = cir.set_bitfield(#bfi_z, %7 : !cir.ptr<!u8i>, %6 : !s32i) -> !s32i
31+
// cir.return
32+
// }

0 commit comments

Comments
 (0)
Please sign in to comment.