Skip to content

Commit be58977

Browse files
bruteforceboylanza
authored andcommitted
[CIR][ABI][AArch64][Lowering] Support unions (#1075)
As the title says, this PR adds support for unions for AArch64 lowering. The idea is basically the same as the [original](https://github.com/llvm/clangir/blob/dbf320e5c3db0410566ae561067c595308870bad/clang/lib/AST/RecordLayoutBuilder.cpp#L2111) codegen, and I added a couple of tests.
1 parent e79d77e commit be58977

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

clang/lib/CIR/Dialect/Transforms/TargetLowering/RecordLayoutBuilder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,9 @@ void ItaniumRecordLayoutBuilder::layoutField(const Type D,
437437

438438
// Reserve space for this field.
439439
if (!IsOverlappingEmptyField) {
440-
// uint64_t EffectiveFieldSizeInBits = Context.toBits(EffectiveFieldSize);
440+
uint64_t EffectiveFieldSizeInBits = Context.toBits(EffectiveFieldSize);
441441
if (IsUnion)
442-
cir_cconv_unreachable("NYI");
442+
setDataSize(std::max(getDataSizeInBits(), EffectiveFieldSizeInBits));
443443
else
444444
setDataSize(FieldOffset + EffectiveFieldSize);
445445

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -fclangir -fclangir-call-conv-lowering -emit-cir-flat -mmlir --mlir-print-ir-after=cir-call-conv-lowering %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll -fclangir-call-conv-lowering
4+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
5+
6+
// CIR: !ty_U = !cir.struct<union "U" {!s32i, !s32i, !s32i}>
7+
// LLVM: %union.U = type { i32 }
8+
typedef union {
9+
int a, b, c;
10+
} U;
11+
12+
// CIR: cir.func @foo(%arg0: !u64i
13+
// CIR: %[[#V0:]] = cir.alloca !ty_U, !cir.ptr<!ty_U>, [""] {alignment = 4 : i64}
14+
// CIR: %[[#V1:]] = cir.cast(integral, %arg0 : !u64i), !u32i
15+
// CIR: %[[#V2:]] = cir.cast(bitcast, %[[#V0]] : !cir.ptr<!ty_U>), !cir.ptr<!u32i>
16+
// CIR: cir.store %[[#V1]], %[[#V2]] : !u32i, !cir.ptr<!u32i>
17+
// CIR: cir.return
18+
19+
// LLVM: void @foo(i64 %[[#V0:]]
20+
// LLVM: %[[#V2:]] = alloca %union.U, i64 1, align 4
21+
// LLVM: %[[#V3:]] = trunc i64 %[[#V0]] to i32
22+
// LLVM: store i32 %[[#V3]], ptr %[[#V2]], align 4
23+
// LLVM: ret void
24+
void foo(U u) {}
25+
26+
// CIR: cir.func no_proto @init() -> !u32i
27+
// CIR: %[[#V0:]] = cir.alloca !ty_U, !cir.ptr<!ty_U>, ["__retval"] {alignment = 4 : i64}
28+
// CIR: %[[#V1:]] = cir.load %[[#V0]] : !cir.ptr<!ty_U>, !ty_U
29+
// CIR: %[[#V2:]] = cir.cast(bitcast, %[[#V0]] : !cir.ptr<!ty_U>), !cir.ptr<!u32i>
30+
// CIR: %[[#V3:]] = cir.load %[[#V2]] : !cir.ptr<!u32i>, !u32i
31+
// CIR: cir.return %[[#V3]] : !u32i
32+
33+
// LLVM: i32 @init()
34+
// LLVM: %[[#V1:]] = alloca %union.U, i64 1, align 4
35+
// LLVM: %[[#V2:]] = load %union.U, ptr %[[#V1]], align 4
36+
// LLVM: %[[#V3:]] = load i32, ptr %[[#V1]], align 4
37+
// LLVM: ret i32 %[[#V3]]
38+
U init() {
39+
U u;
40+
return u;
41+
}

0 commit comments

Comments
 (0)