Skip to content

Commit

Permalink
[CIR][Lowering] Support lowering of nested string ConstantArrays.
Browse files Browse the repository at this point in the history
  • Loading branch information
yugr committed Aug 24, 2023
1 parent 2fae9b7 commit e501bbc
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 5 deletions.
2 changes: 2 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ class CIRGenBuilderTy : public mlir::OpBuilder {
}

if (const auto arrayVal = attr.dyn_cast<mlir::cir::ConstArrayAttr>()) {
if (arrayVal.getElts().isa<mlir::StringAttr>())
return false;
for (const auto elt : arrayVal.getElts().cast<mlir::ArrayAttr>()) {
if (!isNullValue(elt))
return false;
Expand Down
22 changes: 18 additions & 4 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,26 @@ mlir::Value lowerCirAttrAsValue(mlir::cir::ConstArrayAttr constArr,
mlir::TypeConverter *converter) {
auto llvmTy = converter->convertType(constArr.getType());
mlir::Value result = rewriter.create<mlir::LLVM::UndefOp>(loc, llvmTy);
auto arrayAttr = constArr.getElts().cast<mlir::ArrayAttr>();

// Iteratively lower each constant element of the array.
for (auto [idx, elt] : llvm::enumerate(arrayAttr)) {
mlir::Value init = lowerCirAttrAsValue(elt, loc, rewriter, converter);
result = rewriter.create<mlir::LLVM::InsertValueOp>(loc, result, init, idx);
if (auto arrayAttr = constArr.getElts().dyn_cast<mlir::ArrayAttr>()) {
for (auto [idx, elt] : llvm::enumerate(arrayAttr)) {
mlir::Value init = lowerCirAttrAsValue(elt, loc, rewriter, converter);
result =
rewriter.create<mlir::LLVM::InsertValueOp>(loc, result, init, idx);
}
} else if (auto strAttr = constArr.getElts().dyn_cast<mlir::StringAttr>()) {
auto arrayTy = strAttr.getType().dyn_cast<mlir::cir::ArrayType>();
assert(arrayTy && "String attribute must have an array type");
auto eltTy = arrayTy.getEltType();
for (auto [idx, elt] : llvm::enumerate(strAttr)) {
auto init = rewriter.create<mlir::LLVM::ConstantOp>(
loc, converter->convertType(eltTy), elt);
result =
rewriter.create<mlir::LLVM::InsertValueOp>(loc, result, init, idx);
}
} else {
llvm_unreachable("unexpected ConstArrayAttr elements");
}

return result;
Expand Down
7 changes: 6 additions & 1 deletion clang/test/CIR/CodeGen/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ struct {
int x;
int y[2][2];
} nestedTwoDim = {1, {{2, 3}, {4, 5}}};
// CHECK: cir.global external @nestedTwoDim = #cir.const_struct<{#cir.int<1> : !s32i, #cir.const_array<[#cir.const_array<[#cir.int<2> : !s32i, #cir.int<3> : !s32i]> : !cir.array<!s32i x 2>, #cir.const_array<[#cir.int<4> : !s32i, #cir.int<5> : !s32i]> : !cir.array<!s32i x 2>]> : !cir.array<!cir.array<!s32i x 2> x 2>}> : !ty_22struct2Eanon22
// CHECK: cir.global external @nestedTwoDim = #cir.const_struct<{#cir.int<1> : !s32i, #cir.const_array<[#cir.const_array<[#cir.int<2> : !s32i, #cir.int<3> : !s32i]> : !cir.array<!s32i x 2>, #cir.const_array<[#cir.int<4> : !s32i, #cir.int<5> : !s32i]> : !cir.array<!s32i x 2>]> : !cir.array<!cir.array<!s32i x 2> x 2>}>

struct {
char x[3];
} nestedString = {"1"};
// CHECK: cir.global external @nestedString = #cir.const_struct<{#cir.const_array<"1\00\00" : !cir.array<!s8i x 3>> : !cir.array<!s8i x 3>}>

// TODO: test tentatives with internal linkage.

Expand Down
3 changes: 3 additions & 0 deletions clang/test/CIR/Lowering/globals.cir
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
!u8i = !cir.int<u, 8>
!ty_22struct2EA22 = !cir.struct<"struct.A", !s32i, !cir.array<!cir.array<!s32i x 2> x 2>, #cir.recdecl.ast>
!ty_22struct2EBar22 = !cir.struct<"struct.Bar", !s32i, !s8i, #cir.recdecl.ast>
!ty_22struct2Eanon22 = !cir.struct<"struct.anon", !cir.array<!s8i x 3>, #cir.recdecl.ast>

module {
cir.global external @a = #cir.int<3> : !s32i
Expand Down Expand Up @@ -91,6 +92,8 @@ module {
// LLVM: @twoDim = global [2 x [2 x i32{{\]\] \[\[}}2 x i32] [i32 1, i32 2], [2 x i32] [i32 3, i32 4{{\]\]}}
cir.global external @nestedTwoDim = #cir.const_struct<{#cir.int<1> : !s32i, #cir.const_array<[#cir.const_array<[#cir.int<2> : !s32i, #cir.int<3> : !s32i]> : !cir.array<!s32i x 2>, #cir.const_array<[#cir.int<4> : !s32i, #cir.int<5> : !s32i]> : !cir.array<!s32i x 2>]> : !cir.array<!cir.array<!s32i x 2> x 2>}> : !ty_22struct2EA22
// LLVM: @nestedTwoDim = global %struct.A { i32 1, [2 x [2 x i32{{\]\] \[\[}}2 x i32] [i32 2, i32 3], [2 x i32] [i32 4, i32 5{{\]\]}} }
cir.global external @nestedString = #cir.const_struct<{#cir.const_array<"1\00\00" : !cir.array<!s8i x 3>> : !cir.array<!s8i x 3>}> : !ty_22struct2Eanon22
// LLVM: @nestedString = global %struct.anon { [3 x i8] c"1\00\00" }
cir.func @_Z11get_globalsv() {
%0 = cir.alloca !cir.ptr<!s8i>, cir.ptr <!cir.ptr<!s8i>>, ["s", init] {alignment = 8 : i64}
%1 = cir.alloca !cir.ptr<!u32i>, cir.ptr <!cir.ptr<!u32i>>, ["u", init] {alignment = 8 : i64}
Expand Down

0 comments on commit e501bbc

Please sign in to comment.