Skip to content

Commit 3d19e87

Browse files
gitoleglanza
authored andcommitted
[CIR][Lowering] Support lowering of const arrays of structs (llvm#370)
This PR fixes CIR lowering for the next case. ``` void foo() { struct { int a; int b; } a[1] = {{0,1}}; } ``` Note, we don't create attribute here and lower such const arrays as values.
1 parent fa60989 commit 3d19e87

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,24 +1047,21 @@ class CIRConstantLowering
10471047
// then memcopyied into the stack (as done in Clang).
10481048
else if (auto arrTy = op.getType().dyn_cast<mlir::cir::ArrayType>()) {
10491049
// Fetch operation constant array initializer.
1050-
if (auto constArr = op.getValue().dyn_cast<mlir::cir::ConstArrayAttr>()) {
1051-
// Lower constant array initializer.
1052-
auto denseAttr = lowerConstArrayAttr(constArr, typeConverter);
1053-
if (!denseAttr.has_value()) {
1054-
op.emitError()
1055-
<< "unsupported lowering for #cir.const_array with element type "
1056-
<< arrTy.getEltType();
1057-
return mlir::failure();
1058-
}
10591050

1051+
auto constArr = op.getValue().dyn_cast<mlir::cir::ConstArrayAttr>();
1052+
if (!constArr && !isa<mlir::cir::ZeroAttr>(op.getValue()))
1053+
return op.emitError() << "array does not have a constant initializer";
1054+
1055+
std::optional<mlir::Attribute> denseAttr;
1056+
if (constArr &&
1057+
(denseAttr = lowerConstArrayAttr(constArr, typeConverter))) {
10601058
attr = denseAttr.value();
1061-
} else if (auto zero = op.getValue().dyn_cast<mlir::cir::ZeroAttr>()) {
1062-
auto initVal = lowerCirAttrAsValue(op, zero, rewriter, typeConverter);
1059+
} else {
1060+
auto initVal =
1061+
lowerCirAttrAsValue(op, op.getValue(), rewriter, typeConverter);
10631062
rewriter.replaceAllUsesWith(op, initVal);
10641063
rewriter.eraseOp(op);
10651064
return mlir::success();
1066-
} else {
1067-
return op.emitError() << "array does not have a constant initializer";
10681065
}
10691066
} else if (const auto structAttr =
10701067
op.getValue().dyn_cast<mlir::cir::ConstStructAttr>()) {

clang/test/CIR/Lowering/const.cir

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
!s32i = !cir.int<s, 32>
55
!s8i = !cir.int<s, 8>
6+
!ty_22anon2E122 = !cir.struct<struct "anon.1" {!cir.int<s, 32>, !cir.int<s, 32>} #cir.record.decl.ast>
7+
68
module {
79
cir.func @testConstArrInit() {
810
%0 = cir.const(#cir.const_array<"string\00" : !cir.array<!s8i x 7>> : !cir.array<!s8i x 7>) : !cir.array<!s8i x 7>
@@ -15,4 +17,24 @@ module {
1517
// CHECK: cir.llvmir.zeroinit : !llvm.array<3 x i32>
1618
cir.return
1719
}
20+
21+
cir.func @testConstArrayOfStructs() {
22+
%0 = cir.alloca !cir.array<!ty_22anon2E122 x 1>, cir.ptr <!cir.array<!ty_22anon2E122 x 1>>, ["a"] {alignment = 4 : i64}
23+
%1 = cir.const(#cir.const_array<[#cir.const_struct<{#cir.int<0> : !s32i, #cir.int<1> : !s32i}> : !ty_22anon2E122]> : !cir.array<!ty_22anon2E122 x 1>) : !cir.array<!ty_22anon2E122 x 1>
24+
cir.store %1, %0 : !cir.array<!ty_22anon2E122 x 1>, cir.ptr <!cir.array<!ty_22anon2E122 x 1>>
25+
cir.return
26+
}
27+
// CHECK: llvm.func @testConstArrayOfStructs()
28+
// CHECK: %0 = llvm.mlir.constant(1 : index) : i64
29+
// CHECK: %1 = llvm.alloca %0 x !llvm.array<1 x struct<"struct.anon.1", (i32, i32)>> {alignment = 4 : i64} : (i64) -> !llvm.ptr
30+
// CHECK: %2 = llvm.mlir.undef : !llvm.array<1 x struct<"struct.anon.1", (i32, i32)>>
31+
// CHECK: %3 = llvm.mlir.undef : !llvm.struct<"struct.anon.1", (i32, i32)>
32+
// CHECK: %4 = llvm.mlir.constant(0 : i32) : i32
33+
// CHECK: %5 = llvm.insertvalue %4, %3[0] : !llvm.struct<"struct.anon.1", (i32, i32)>
34+
// CHECK: %6 = llvm.mlir.constant(1 : i32) : i32
35+
// CHECK: %7 = llvm.insertvalue %6, %5[1] : !llvm.struct<"struct.anon.1", (i32, i32)>
36+
// CHECK: %8 = llvm.insertvalue %7, %2[0] : !llvm.array<1 x struct<"struct.anon.1", (i32, i32)>>
37+
// CHECK: llvm.store %8, %1 : !llvm.array<1 x struct<"struct.anon.1", (i32, i32)>>, !llvm.ptr
38+
// CHECK: llvm.return
39+
1840
}

0 commit comments

Comments
 (0)