Skip to content

Commit 93ef103

Browse files
ivanmurashkolanza
authored andcommitted
[CIR][CodeGen] Support trailing_zeros for constant string literals (llvm#617)
The patch resolves [issue llvm#248](llvm#248). It can be considered a subsequent patch to [llvm#373](llvm#373), where the case of empty strings was processed. The new patch adds processing for non-empty strings that may contain trailing zeros, such as: ``` char big_string[100000] = "123"; ``` That is converted to ``` @big_string = #cir.const_array<"123" : !cir.array<!s8i x 3>, trailing_zeros> : !cir.array<!s8i x 100000> ```
1 parent 5db10e6 commit 93ef103

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,26 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
153153
unsigned size = 0) {
154154
unsigned finalSize = size ? size : str.size();
155155

156+
size_t lastNonZeroPos = str.find_last_not_of('\0');
156157
// If the string is full of null bytes, emit a #cir.zero rather than
157158
// a #cir.const_array.
158-
if (str.count('\0') == str.size()) {
159+
if (lastNonZeroPos == llvm::StringRef::npos) {
159160
auto arrayTy = mlir::cir::ArrayType::get(getContext(), eltTy, finalSize);
160161
return getZeroAttr(arrayTy);
161162
}
162-
163-
auto arrayTy = mlir::cir::ArrayType::get(getContext(), eltTy, finalSize);
164-
return getConstArray(mlir::StringAttr::get(str, arrayTy), arrayTy);
163+
// We will use trailing zeros only if there are more than one zero
164+
// at the end
165+
int trailingZerosNum =
166+
finalSize > lastNonZeroPos + 2 ? finalSize - lastNonZeroPos - 1 : 0;
167+
auto truncatedArrayTy = mlir::cir::ArrayType::get(
168+
getContext(), eltTy, finalSize - trailingZerosNum);
169+
auto fullArrayTy =
170+
mlir::cir::ArrayType::get(getContext(), eltTy, finalSize);
171+
return mlir::cir::ConstArrayAttr::get(
172+
getContext(), fullArrayTy,
173+
mlir::StringAttr::get(str.drop_back(trailingZerosNum),
174+
truncatedArrayTy),
175+
trailingZerosNum);
165176
}
166177

167178
mlir::cir::ConstArrayAttr getConstArray(mlir::Attribute attrs,

clang/test/CIR/CodeGen/globals.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
char string[] = "whatnow";
1010
// CHECK: cir.global external @string = #cir.const_array<"whatnow\00" : !cir.array<!s8i x 8>> : !cir.array<!s8i x 8>
11+
char big_string[100000] = "123";
12+
// CHECK: cir.global external @big_string = #cir.const_array<"123" : !cir.array<!s8i x 3>, trailing_zeros> : !cir.array<!s8i x 100000>
1113
int sint[] = {123, 456, 789};
1214
// CHECK: cir.global external @sint = #cir.const_array<[#cir.int<123> : !s32i, #cir.int<456> : !s32i, #cir.int<789> : !s32i]> : !cir.array<!s32i x 3>
1315
int filler_sint[4] = {1, 2}; // Ensure missing elements are zero-initialized.
@@ -41,7 +43,7 @@ struct {
4143
char y[3];
4244
char z[3];
4345
} nestedString = {"1", "", "\0"};
44-
// CHECK: cir.global external @nestedString = #cir.const_struct<{#cir.const_array<"1\00\00" : !cir.array<!s8i x 3>> : !cir.array<!s8i x 3>, #cir.zero : !cir.array<!s8i x 3>, #cir.zero : !cir.array<!s8i x 3>}>
46+
// CHECK: cir.global external @nestedString = #cir.const_struct<{#cir.const_array<"1" : !cir.array<!s8i x 1>, trailing_zeros> : !cir.array<!s8i x 3>, #cir.zero : !cir.array<!s8i x 3>, #cir.zero : !cir.array<!s8i x 3>}>
4547

4648
struct {
4749
char *name;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3+
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
5+
6+
struct {
7+
char x[10];
8+
char y[10];
9+
char z[10];
10+
} literals = {"1", "", "\00"};
11+
12+
// CIR-LABEL: @literals
13+
// CIR: #cir.const_struct<{
14+
// CIR: #cir.const_array<"1" : !cir.array<!s8i x 1>, trailing_zeros> : !cir.array<!s8i x 10>,
15+
// CIR: #cir.zero : !cir.array<!s8i x 10>,
16+
// CIR: #cir.zero : !cir.array<!s8i x 10>
17+
// CIR: }>
18+
19+
// LLVM-LABEL: @literals
20+
// LLVM: global %struct.anon.1 {
21+
// LLVM: [10 x i8] c"1\00\00\00\00\00\00\00\00\00",
22+
// LLVM: [10 x i8] zeroinitializer,
23+
// LLVM: [10 x i8] zeroinitializer
24+
// LLVM: }

0 commit comments

Comments
 (0)