Skip to content

Commit 74e4af3

Browse files
authored
[CIR] Add handling for initializing multi-dimension arrays (#1369)
Add an implementation for array new initialization of multidimension arrays. This is able to leverage existing array element initialization with just a few changes to update the pointer types.
1 parent b510e50 commit 74e4af3

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,10 @@ void CIRGenFunction::emitNewArrayInitializer(
10481048
QualType AllocType = E->getAllocatedType();
10491049
if (const ConstantArrayType *CAT = dyn_cast_or_null<ConstantArrayType>(
10501050
AllocType->getAsArrayTypeUnsafe())) {
1051-
llvm_unreachable("NYI");
1051+
ElementTy = convertTypeForMem(AllocType);
1052+
auto CastOp = builder.createPtrBitcast(CurPtr.getPointer(), ElementTy);
1053+
CurPtr = Address(CastOp, ElementTy, CurPtr.getAlignment());
1054+
InitListElements *= getContext().getConstantArrayElementCount(CAT);
10521055
}
10531056

10541057
// Enter a partial-destruction Cleanup if necessary.
@@ -1070,10 +1073,10 @@ void CIRGenFunction::emitNewArrayInitializer(
10701073
AggValueSlot::DoesNotOverlap);
10711074
auto Loc = getLoc(IE->getExprLoc());
10721075
auto CastOp = builder.createPtrBitcast(CurPtr.getPointer(),
1073-
convertTypeForMem(AllocType));
1076+
CurPtr.getElementType());
10741077
auto OffsetOp = builder.getSignedInt(Loc, 1, /*width=*/32);
10751078
auto DataPtr = builder.createPtrStride(Loc, CastOp, OffsetOp);
1076-
CurPtr = Address(DataPtr, CurPtr.getType(),
1079+
CurPtr = Address(DataPtr, CurPtr.getElementType(),
10771080
StartAlign.alignmentAtOffset((++i) * ElementSize));
10781081
}
10791082

clang/test/CIR/CodeGen/new.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,38 @@ void t_new_var_size_nontrivial(size_t n) {
292292
// CHECK: %[[ALL_ONES:.*]] = cir.const #cir.int<18446744073709551615> : !u64i
293293
// CHECK: %[[ALLOC_SIZE:.*]] = cir.select if %[[ANY_OVERFLOW]] then %[[ALL_ONES]] else %[[SIZE]] : (!cir.bool, !u64i, !u64i)
294294
// CHECK: %[[PTR:.*]] = cir.call @_Znam(%[[ALLOC_SIZE]]) : (!u64i)
295+
296+
void t_multidim_init() {
297+
auto *p = new int[2][3] { {1, 2, 3}, {4, 5, 6}};
298+
}
299+
300+
// CHECK: cir.func @_Z15t_multidim_initv()
301+
// CHECK: %[[NUM_ELEMENTS:.*]] = cir.const #cir.int<6> : !u64i
302+
// CHECK: %[[ALLOCATION_SIZE:.*]] = cir.const #cir.int<24> : !u64i
303+
// CHECK: %[[NEW_PTR:.*]] = cir.call @_Znam(%2) : (!u64i) -> !cir.ptr<!void>
304+
// CHECK: %[[ELEMENT_PTR:.*]] = cir.cast(bitcast, %[[NEW_PTR]] : !cir.ptr<!void>), !cir.ptr<!s32i>
305+
// CHECK: %[[ARRAY_ELEM0_PTR:.*]] = cir.cast(bitcast, %[[ELEMENT_PTR]] : !cir.ptr<!s32i>), !cir.ptr<!cir.array<!s32i x 3>>
306+
// CHECK: %[[ELEM_00_PTR:.*]] = cir.cast(array_to_ptrdecay, %[[ARRAY_ELEM0_PTR]] : !cir.ptr<!cir.array<!s32i x 3>>), !cir.ptr<!s32i>
307+
// CHECK: %[[ELEM_00_VAL:.*]] = cir.const #cir.int<1> : !s32i
308+
// CHECK: cir.store %[[ELEM_00_VAL]], %[[ELEM_00_PTR]] : !s32i, !cir.ptr<!s32i>
309+
// CHECK: %[[OFFSET:.*]] = cir.const #cir.int<1> : !s64i
310+
// CHECK: %[[ELEM_01_PTR:.*]] = cir.ptr_stride(%[[ELEM_00_PTR]] : !cir.ptr<!s32i>, %[[OFFSET]] : !s64i), !cir.ptr<!s32i>
311+
// CHECK: %[[ELEM_01_VAL:.*]] = cir.const #cir.int<2> : !s32i
312+
// CHECK: cir.store %[[ELEM_01_VAL]], %[[ELEM_01_PTR]] : !s32i, !cir.ptr<!s32i>
313+
// CHECK: %[[OFFSET1:.*]] = cir.const #cir.int<2> : !s64i
314+
// CHECK: %[[ELEM_02_PTR:.*]] = cir.ptr_stride(%[[ELEM_00_PTR]] : !cir.ptr<!s32i>, %[[OFFSET1]] : !s64i), !cir.ptr<!s32i>
315+
// CHECK: %[[ELEM_02_VAL:.*]] = cir.const #cir.int<3> : !s32i
316+
// CHECK: cir.store %[[ELEM_02_VAL]], %[[ELEM_02_PTR]] : !s32i, !cir.ptr<!s32i>
317+
// CHECK: %[[OFFSET3:.*]] = cir.const #cir.int<1> : !s32i
318+
// CHECK: %[[ARRAY_ELEM1_PTR:.*]] = cir.ptr_stride(%[[ARRAY_ELEM0_PTR]] : !cir.ptr<!cir.array<!s32i x 3>>, %[[OFFSET3]] : !s32i), !cir.ptr<!cir.array<!s32i x 3>>
319+
// CHECK: %[[ELEM_10_PTR:.*]] = cir.cast(array_to_ptrdecay, %[[ARRAY_ELEM1_PTR]] : !cir.ptr<!cir.array<!s32i x 3>>), !cir.ptr<!s32i>
320+
// CHECK: %[[ELEM_10_VAL:.*]] = cir.const #cir.int<4> : !s32i
321+
// CHECK: cir.store %[[ELEM_10_VAL]], %[[ELEM_10_PTR]] : !s32i, !cir.ptr<!s32i>
322+
// CHECK: %[[OFFSET4:.*]] = cir.const #cir.int<1> : !s64i
323+
// CHECK: %[[ELEM_11_PTR:.*]] = cir.ptr_stride(%[[ELEM_10_PTR]] : !cir.ptr<!s32i>, %[[OFFSET4]] : !s64i), !cir.ptr<!s32i>
324+
// CHECK: %[[ELEM_11_VAL:.*]] = cir.const #cir.int<5> : !s32i
325+
// CHECK: cir.store %[[ELEM_11_VAL]], %[[ELEM_11_PTR]] : !s32i, !cir.ptr<!s32i>
326+
// CHECK: %[[OFFSET5:.*]] = cir.const #cir.int<2> : !s64i
327+
// CHECK: %[[ELEM_12_PTR:.*]] = cir.ptr_stride(%[[ELEM_10_PTR]] : !cir.ptr<!s32i>, %21 : !s64i), !cir.ptr<!s32i>
328+
// CHECK: %[[ELEM_12_VAL:.*]] = cir.const #cir.int<6> : !s32i
329+
// CHECK: cir.store %[[ELEM_12_VAL]], %[[ELEM_12_PTR]] : !s32i, !cir.ptr<!s32i>

clang/test/CIR/Lowering/new.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,23 @@ void t_new_constant_size_constructor() {
215215
// LLVM: %[[NEXT_PTR:.*]] = getelementptr %class.E, ptr %[[CUR_ELEM_PTR]], i64 1
216216
// LLVM: store ptr %[[NEXT_PTR]]
217217
// LLVM: br label %[[LOOP_INC_BB]]
218+
219+
void t_multidim_init() {
220+
auto *p = new int[2][3] { {1, 2, 3}, {4, 5, 6}};
221+
}
222+
223+
// LLVM: @_Z15t_multidim_initv()
224+
// LLVM: %[[ALLOC_PTR:.*]] = call ptr @_Znam(i64 24)
225+
// LLVM: %[[ELEM_00_PTR:.*]] = getelementptr i32, ptr %[[ALLOC_PTR]], i32 0
226+
// LLVM: store i32 1, ptr %[[ELEM_00_PTR]], align 4
227+
// LLVM: %[[ELEM_01_PTR:.*]] = getelementptr i32, ptr %[[ELEM_00_PTR]], i64 1
228+
// LLVM: store i32 2, ptr %[[ELEM_01_PTR]], align 4
229+
// LLVM: %[[ELEM_02_PTR:.*]] = getelementptr i32, ptr %[[ELEM_00_PTR]], i64 2
230+
// LLVM: store i32 3, ptr %[[ELEM_02_PTR]], align 4
231+
// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr [3 x i32], ptr %[[ALLOC_PTR]], i64 1
232+
// LLVM: %[[ELEM_10_PTR:.*]] = getelementptr i32, ptr %[[ELEM_1_PTR]], i32 0
233+
// LLVM: store i32 4, ptr %[[ELEM_10_PTR]], align 4
234+
// LLVM: %[[ELEM_11_PTR:.*]] = getelementptr i32, ptr %[[ELEM_10_PTR]], i64 1
235+
// LLVM: store i32 5, ptr %[[ELEM_11_PTR]], align 4
236+
// LLVM: %[[ELEM_12_PTR:.*]] = getelementptr i32, ptr %[[ELEM_10_PTR]], i64 2
237+
// LLVM: store i32 6, ptr %[[ELEM_12_PTR]], align 4

0 commit comments

Comments
 (0)