Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//

#include "clang/AST/CharUnits.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
#include "clang/CIR/MissingFeatures.h"
#include <CIRGenCXXABI.h>
Expand Down Expand Up @@ -876,6 +877,7 @@ void CIRGenFunction::emitNewArrayInitializer(
unsigned InitListElements = 0;

const Expr *Init = E->getInitializer();
Address EndOfInit = Address::invalid();
QualType::DestructionKind DtorKind = ElementType.isDestructedType();
CleanupDeactivationScope deactivation(*this);

Expand All @@ -898,7 +900,13 @@ void CIRGenFunction::emitNewArrayInitializer(
// Subtract out the size of any elements we've already initialized.
auto RemainingSize = AllocSizeWithoutCookie;
if (InitListElements) {
llvm_unreachable("NYI");
// We know this can't overflow; we check this when doing the allocation.
unsigned InitializedSize =
getContext().getTypeSizeInChars(ElementType).getQuantity() *
InitListElements;
auto InitSizeOp =
builder.getConstInt(Loc, RemainingSize.getType(), InitializedSize);
RemainingSize = builder.createSub(RemainingSize, InitSizeOp);
}

// Create the memset.
Expand Down Expand Up @@ -946,8 +954,24 @@ void CIRGenFunction::emitNewArrayInitializer(
}

CharUnits StartAlign = CurPtr.getAlignment();
unsigned i = 0;
for (const Expr *IE : InitExprs) {
llvm_unreachable("NYI");
if (EndOfInit.isValid()) {
// This will involve DTor handling.
llvm_unreachable("NYI");
}
// FIXME: If the last initializer is an incomplete initializer list for
// an array, and we have an array filler, we can fold together the two
// initialization loops.
StoreAnyExprIntoOneUnit(*this, IE, IE->getType(), CurPtr,
AggValueSlot::DoesNotOverlap);
auto Loc = getLoc(IE->getExprLoc());
auto CastOp = builder.createPtrBitcast(CurPtr.getPointer(),
convertTypeForMem(AllocType));
auto OffsetOp = builder.getSignedInt(Loc, 1, /*width=*/32);
auto DataPtr = builder.createPtrStride(Loc, CastOp, OffsetOp);
CurPtr = Address(DataPtr, CurPtr.getType(),
StartAlign.alignmentAtOffset((++i) * ElementSize));
}

// The remaining elements are filled with the array filler expression.
Expand Down
28 changes: 28 additions & 0 deletions clang/test/CIR/CodeGen/new.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,31 @@ void t_constant_size_memset_init() {
// CHECK: %[[#ZERO:]] = cir.const #cir.int<0> : !u8i
// CHECK: %[[#ZERO_I32:]] = cir.cast(integral, %[[#ZERO]] : !u8i), !s32i
// CHECK: cir.libc.memset %[[#ALLOCATION_SIZE]] bytes from %[[#VOID_PTR]] set to %[[#ZERO_I32]] : !cir.ptr<!void>, !s32i, !u64i

void t_constant_size_partial_init() {
auto p = new int[16] { 1, 2, 3 };
}

// CHECK: cir.func @_Z28t_constant_size_partial_initv()
// CHECK: %[[#NUM_ELEMENTS:]] = cir.const #cir.int<16> : !u64i
// CHECK: %[[#ALLOCATION_SIZE:]] = cir.const #cir.int<64> : !u64i
// CHECK: %[[#ALLOC_PTR:]] = cir.call @_Znam(%[[#ALLOCATION_SIZE]]) : (!u64i) -> !cir.ptr<!void>
// CHECK: %[[#ELEM_0_PTR:]] = cir.cast(bitcast, %[[#ALLOC_PTR]] : !cir.ptr<!void>), !cir.ptr<!s32i>
// CHECK: %[[#CONST_ONE:]] = cir.const #cir.int<1> : !s32i
// CHECK: cir.store %[[#CONST_ONE]], %[[#ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>
// CHECK: %[[#OFFSET:]] = cir.const #cir.int<1> : !s32i
// CHECK: %[[#ELEM_1_PTR:]] = cir.ptr_stride(%[[#ELEM_0_PTR]] : !cir.ptr<!s32i>, %[[#OFFSET]] : !s32i), !cir.ptr<!s32i>
// CHECK: %[[#CONST_TWO:]] = cir.const #cir.int<2> : !s32i
// CHECK: cir.store %[[#CONST_TWO]], %[[#ELEM_1_PTR]] : !s32i, !cir.ptr<!s32i>
// CHECK: %[[#OFFSET1:]] = cir.const #cir.int<1> : !s32i
// CHECK: %[[#ELEM_2_PTR:]] = cir.ptr_stride(%[[#ELEM_1_PTR]] : !cir.ptr<!s32i>, %[[#OFFSET1]] : !s32i), !cir.ptr<!s32i>
// CHECK: %[[#CONST_THREE:]] = cir.const #cir.int<3> : !s32i
// CHECK: cir.store %[[#CONST_THREE]], %[[#ELEM_2_PTR]] : !s32i, !cir.ptr<!s32i>
// CHECK: %[[#OFFSET2:]] = cir.const #cir.int<1> : !s32i
// CHECK: %[[#ELEM_3_PTR:]] = cir.ptr_stride(%[[#ELEM_2_PTR]] : !cir.ptr<!s32i>, %[[#OFFSET2]] : !s32i), !cir.ptr<!s32i>
// CHECK: %[[#INIT_SIZE:]] = cir.const #cir.int<12> : !u64i
// CHECK: %[[#REMAINING_SIZE:]] = cir.binop(sub, %[[#ALLOCATION_SIZE]], %[[#INIT_SIZE]]) : !u64i
// CHECK: %[[#VOID_PTR:]] = cir.cast(bitcast, %[[#ELEM_3_PTR]] : !cir.ptr<!s32i>), !cir.ptr<!void>
// CHECK: %[[#ZERO:]] = cir.const #cir.int<0> : !u8i
// CHECK: %[[#ZERO_I32:]] = cir.cast(integral, %[[#ZERO]] : !u8i), !s32i
// CHECK: cir.libc.memset %[[#REMAINING_SIZE]] bytes from %[[#VOID_PTR]] set to %[[#ZERO_I32]] : !cir.ptr<!void>, !s32i, !u64i
16 changes: 16 additions & 0 deletions clang/test/CIR/Lowering/new.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,19 @@ void t_constant_size_memset_init() {
// LLVM: %[[ADDR:.*]] = call ptr @_Znam(i64 64)
// LLVM: call void @llvm.memset.p0.i64(ptr %[[ADDR]], i8 0, i64 64, i1 false)
// LLVM: store ptr %[[ADDR]], ptr %[[ALLOCA]], align 8

void t_constant_size_partial_init() {
auto p = new int[16] { 1, 2, 3 };
}

// LLVM: @_Z28t_constant_size_partial_initv()
// LLVM: %[[ALLOCA:.*]] = alloca ptr, i64 1, align 8
// LLVM: %[[ADDR:.*]] = call ptr @_Znam(i64 64)
// LLVM: store i32 1, ptr %[[ADDR]], align 4
// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr i32, ptr %[[ADDR]], i64 1
// LLVM: store i32 2, ptr %[[ELEM_1_PTR]], align 4
// LLVM: %[[ELEM_2_PTR:.*]] = getelementptr i32, ptr %[[ELEM_1_PTR]], i64 1
// LLVM: store i32 3, ptr %[[ELEM_2_PTR]], align 4
// LLVM: %[[ELEM_3_PTR:.*]] = getelementptr i32, ptr %[[ELEM_2_PTR]], i64 1
// LLVM: call void @llvm.memset.p0.i64(ptr %[[ELEM_3_PTR]], i8 0, i64 52, i1 false)
// LLVM: store ptr %[[ADDR]], ptr %[[ALLOCA]], align 8