@@ -433,6 +433,7 @@ void AggExprEmitter::buildArrayInit(Address DestPtr, mlir::cir::ArrayType AType,
433
433
434
434
QualType elementType =
435
435
CGF.getContext().getAsArrayType(ArrayQTy)->getElementType();
436
+ QualType elementPtrType = CGF.getContext().getPointerType(elementType);
436
437
437
438
auto cirElementType = CGF.convertType(elementType);
438
439
auto cirElementPtrType = mlir::cir::PointerType::get(
@@ -498,7 +499,73 @@ void AggExprEmitter::buildArrayInit(Address DestPtr, mlir::cir::ArrayType AType,
498
499
if (NumInitElements != NumArrayElements &&
499
500
!(Dest.isZeroed() && hasTrivialFiller &&
500
501
CGF.getTypes().isZeroInitializable(elementType))) {
501
- llvm_unreachable("zero-initialization of arrays NIY");
502
+
503
+ // Use an actual loop. This is basically
504
+ // do { *array++ = filler; } while (array != end);
505
+
506
+ auto &builder = CGF.getBuilder();
507
+
508
+ // Advance to the start of the rest of the array.
509
+ if (NumInitElements) {
510
+ auto one =
511
+ builder.getConstInt(loc, CGF.PtrDiffTy.cast<mlir::cir::IntType>(), 1);
512
+ element = builder.create<mlir::cir::PtrStrideOp>(loc, cirElementPtrType,
513
+ element, one);
514
+
515
+ assert(!endOfInit.isValid() && "destructed types NIY");
516
+ }
517
+
518
+ // Allocate the temporary variable
519
+ // to store the pointer to first unitialized element
520
+ auto tmpAddr = CGF.CreateTempAlloca(
521
+ cirElementPtrType, CGF.getPointerAlign(), loc, "arrayinit.temp");
522
+ LValue tmpLV = CGF.makeAddrLValue(tmpAddr, elementPtrType);
523
+ CGF.buildStoreThroughLValue(RValue::get(element), tmpLV);
524
+
525
+ // Compute the end of array
526
+ auto numArrayElementsConst = builder.getConstInt(
527
+ loc, CGF.PtrDiffTy.cast<mlir::cir::IntType>(), NumArrayElements);
528
+ mlir::Value end = builder.create<mlir::cir::PtrStrideOp>(
529
+ loc, cirElementPtrType, begin, numArrayElementsConst);
530
+
531
+ builder.createDoWhile(
532
+ loc,
533
+ /*condBuilder=*/
534
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
535
+ auto currentElement = builder.createLoad(loc, tmpAddr);
536
+ mlir::Type boolTy = CGF.getCIRType(CGF.getContext().BoolTy);
537
+ auto cmp = builder.create<mlir::cir::CmpOp>(
538
+ loc, boolTy, mlir::cir::CmpOpKind::ne, currentElement, end);
539
+ builder.createCondition(cmp);
540
+ },
541
+ /*bodyBuilder=*/
542
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
543
+ auto currentElement = builder.createLoad(loc, tmpAddr);
544
+
545
+ if (UnimplementedFeature::cleanups())
546
+ llvm_unreachable("NYI");
547
+
548
+ // Emit the actual filler expression.
549
+ LValue elementLV = CGF.makeAddrLValue(
550
+ Address(currentElement, cirElementType, elementAlign),
551
+ elementType);
552
+ if (ArrayFiller)
553
+ buildInitializationToLValue(ArrayFiller, elementLV);
554
+ else
555
+ buildNullInitializationToLValue(loc, elementLV);
556
+
557
+ // Tell the EH cleanup that we finished with the last element.
558
+ assert(!endOfInit.isValid() && "destructed types NIY");
559
+
560
+ // Advance pointer and store them to temporary variable
561
+ auto one = builder.getConstInt(
562
+ loc, CGF.PtrDiffTy.cast<mlir::cir::IntType>(), 1);
563
+ auto nextElement = builder.create<mlir::cir::PtrStrideOp>(
564
+ loc, cirElementPtrType, currentElement, one);
565
+ CGF.buildStoreThroughLValue(RValue::get(nextElement), tmpLV);
566
+
567
+ builder.createYield(loc);
568
+ });
502
569
}
503
570
504
571
// Leave the partial-array cleanup if we entered one.
0 commit comments