@@ -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