Skip to content

Commit 9980dbb

Browse files
bruteforceboylanza
authored andcommitted
[CIR][Lowering] Fix lowering for multi dimensional array (llvm#851)
This PR fixes the lowering for multi dimensional arrays. Consider the following code snippet `test.c`: ``` void foo() { char arr[4][1] = {"a", "b", "c", "d"}; } ``` When ran with `bin/clang test.c -Xclang -fclangir -Xclang -emit-llvm -S -o -`, It produces the following error: ``` ~/clangir/llvm/include/llvm/Support/Casting.h:566: decltype(auto) llvm::cast(const From&) [with To = mlir::ArrayAttr; From = mlir::Attribute]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed. ``` The bug can be traced back to `LoweringHelpers.cpp`. It considers the values in the array as integer types, and this causes an error in this case. This PR updates `convertToDenseElementsAttrImpl` when the array contains string attributes. I have also added one more similar test. Note that in the tests I used a **literal match** to avoid matching as regex, so `!dbg` is useful.
1 parent 22bd691 commit 9980dbb

File tree

2 files changed

+45
-10
lines changed

2 files changed

+45
-10
lines changed

clang/lib/CIR/Lowering/LoweringHelpers.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,43 @@ mlir::Type getNestedTypeAndElemQuantity(mlir::Type Ty, unsigned &elemQuantity) {
6161
return nestTy;
6262
}
6363

64+
template <typename StorageTy>
65+
void fillTrailingZeros(mlir::cir::ConstArrayAttr attr,
66+
llvm::SmallVectorImpl<StorageTy> &values) {
67+
auto numTrailingZeros = attr.getTrailingZerosNum();
68+
if (numTrailingZeros) {
69+
auto localArrayTy = mlir::dyn_cast<mlir::cir::ArrayType>(attr.getType());
70+
assert(localArrayTy && "expected !cir.array");
71+
72+
auto nestTy = localArrayTy.getEltType();
73+
if (!mlir::isa<mlir::cir::ArrayType>(nestTy))
74+
values.insert(values.end(), numTrailingZeros,
75+
getZeroInitFromType<StorageTy>(nestTy));
76+
}
77+
}
78+
6479
template <typename AttrTy, typename StorageTy>
6580
void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr,
6681
llvm::SmallVectorImpl<StorageTy> &values) {
82+
if (auto stringAttr = mlir::dyn_cast<mlir::StringAttr>(attr.getElts())) {
83+
if (auto arrayType = mlir::dyn_cast<mlir::cir::ArrayType>(attr.getType())) {
84+
for (auto element : stringAttr) {
85+
auto intAttr = mlir::cir::IntAttr::get(arrayType.getEltType(), element);
86+
values.push_back(mlir::dyn_cast<AttrTy>(intAttr).getValue());
87+
}
88+
return;
89+
}
90+
}
91+
6792
auto arrayAttr = mlir::cast<mlir::ArrayAttr>(attr.getElts());
6893
for (auto eltAttr : arrayAttr) {
6994
if (auto valueAttr = mlir::dyn_cast<AttrTy>(eltAttr)) {
7095
values.push_back(valueAttr.getValue());
7196
} else if (auto subArrayAttr =
7297
mlir::dyn_cast<mlir::cir::ConstArrayAttr>(eltAttr)) {
7398
convertToDenseElementsAttrImpl<AttrTy>(subArrayAttr, values);
99+
if (mlir::dyn_cast<mlir::StringAttr>(subArrayAttr.getElts()))
100+
fillTrailingZeros(subArrayAttr, values);
74101
} else if (auto zeroAttr = mlir::dyn_cast<mlir::cir::ZeroAttr>(eltAttr)) {
75102
unsigned numStoredZeros = 0;
76103
auto nestTy =
@@ -84,16 +111,7 @@ void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr,
84111

85112
// Only fill in trailing zeros at the local cir.array level where the element
86113
// type isn't another array (for the mult-dim case).
87-
auto numTrailingZeros = attr.getTrailingZerosNum();
88-
if (numTrailingZeros) {
89-
auto localArrayTy = mlir::dyn_cast<mlir::cir::ArrayType>(attr.getType());
90-
assert(localArrayTy && "expected !cir.array");
91-
92-
auto nestTy = localArrayTy.getEltType();
93-
if (!mlir::isa<mlir::cir::ArrayType>(nestTy))
94-
values.insert(values.end(), numTrailingZeros,
95-
getZeroInitFromType<StorageTy>(nestTy));
96-
}
114+
fillTrailingZeros(attr, values);
97115
}
98116

99117
template <typename AttrTy, typename StorageTy>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
22
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
33

4+
// LLVM: charInit1.ar = internal global [4 x [4 x i8]] {{.*}}4 x i8] c"aa\00\00", [4 x i8] c"aa\00\00", [4 x i8] c"aa\00\00", [4 x i8] c"aa\00\00"], align 16
5+
char charInit1() {
6+
static char ar[][4] = {"aa", "aa", "aa", "aa"};
7+
return ar[0][0];
8+
}
9+
410
// LLVM: define dso_local void @zeroInit
511
// LLVM: [[RES:%.*]] = alloca [3 x i32], i64 1
612
// LLVM: store [3 x i32] zeroinitializer, ptr [[RES]]
713
void zeroInit() {
814
int a[3] = {0, 0, 0};
915
}
1016

17+
// LLVM: %1 = alloca [4 x [1 x i8]], i64 1, align 1
18+
// LLVM: store [4 x [1 x i8]] {{.*}}1 x i8] c"a", [1 x i8] c"b", [1 x i8] c"c", [1 x i8] c"d"], ptr %1, align 1
19+
void charInit2() {
20+
char arr[4][1] = {"a", "b", "c", "d"};
21+
}
22+
23+
// LLVM: %1 = alloca [4 x [2 x i8]], i64 1, align 1
24+
// LLVM: store [4 x [2 x i8]] {{.*}}2 x i8] c"ab", [2 x i8] c"cd", [2 x i8] c"ef", [2 x i8] c"gh"], ptr %1, align 1
25+
void charInit3() {
26+
char arr[4][2] = {"ab", "cd", "ef", "gh"};
27+
}

0 commit comments

Comments
 (0)