@@ -1333,27 +1333,30 @@ void LoweringPreparePass::lowerDynamicCastOp(DynamicCastOp op) {
13331333
13341334static void lowerArrayDtorCtorIntoLoop (CIRBaseBuilderTy &builder,
13351335 mlir::Operation *op, mlir::Type eltTy,
1336- mlir::Value arrayAddr,
1337- uint64_t arrayLen ) {
1336+ mlir::Value arrayAddr, uint64_t arrayLen,
1337+ bool isCtor ) {
13381338 // Generate loop to call into ctor/dtor for every element.
13391339 auto loc = op->getLoc ();
13401340
13411341 // TODO: instead of fixed integer size, create alias for PtrDiffTy and unify
13421342 // with CIRGen stuff.
13431343 auto ptrDiffTy =
13441344 cir::IntType::get (builder.getContext (), 64 , /* signed=*/ false );
1345- auto numArrayElementsConst = builder.create <cir::ConstantOp>(
1346- loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, arrayLen));
1345+ uint64_t endOffset = isCtor ? arrayLen : arrayLen - 1 ;
1346+ mlir::Value endOffsetVal = builder.create <cir::ConstantOp>(
1347+ loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, endOffset));
13471348
13481349 auto begin = builder.create <cir::CastOp>(
13491350 loc, eltTy, cir::CastKind::array_to_ptrdecay, arrayAddr);
1350- mlir::Value end = builder.create <cir::PtrStrideOp>(loc, eltTy, begin,
1351- numArrayElementsConst);
1351+ mlir::Value end =
1352+ builder.create <cir::PtrStrideOp>(loc, eltTy, begin, endOffsetVal);
1353+ mlir::Value start = isCtor ? begin : end;
1354+ mlir::Value stop = isCtor ? end : begin;
13521355
13531356 auto tmpAddr = builder.createAlloca (
13541357 loc, /* addr type*/ builder.getPointerTo (eltTy),
13551358 /* var type*/ eltTy, " __array_idx" , clang::CharUnits::One ());
1356- builder.createStore (loc, begin , tmpAddr);
1359+ builder.createStore (loc, start , tmpAddr);
13571360
13581361 auto loop = builder.createDoWhile (
13591362 loc,
@@ -1362,7 +1365,7 @@ static void lowerArrayDtorCtorIntoLoop(CIRBaseBuilderTy &builder,
13621365 auto currentElement = b.create <cir::LoadOp>(loc, eltTy, tmpAddr);
13631366 mlir::Type boolTy = cir::BoolType::get (b.getContext ());
13641367 auto cmp = builder.create <cir::CmpOp>(loc, boolTy, cir::CmpOpKind::ne,
1365- currentElement, end );
1368+ currentElement, stop );
13661369 builder.createCondition (cmp);
13671370 },
13681371 /* bodyBuilder=*/
@@ -1373,15 +1376,20 @@ static void lowerArrayDtorCtorIntoLoop(CIRBaseBuilderTy &builder,
13731376 op->walk ([&](CallOp c) { ctorCall = c; });
13741377 assert (ctorCall && " expected ctor call" );
13751378
1376- auto one = builder.create <cir::ConstantOp>(
1377- loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, 1 ));
1379+ cir::ConstantOp stride;
1380+ if (isCtor)
1381+ stride = builder.create <cir::ConstantOp>(
1382+ loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, 1 ));
1383+ else
1384+ stride = builder.create <cir::ConstantOp>(
1385+ loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, -1 ));
13781386
1379- ctorCall->moveAfter (one );
1387+ ctorCall->moveBefore (stride );
13801388 ctorCall->setOperand (0 , currentElement);
13811389
13821390 // Advance pointer and store them to temporary variable
1383- auto nextElement =
1384- builder. create <cir::PtrStrideOp>( loc, eltTy, currentElement, one );
1391+ auto nextElement = builder. create <cir::PtrStrideOp>(
1392+ loc, eltTy, currentElement, stride );
13851393 builder.createStore (loc, nextElement, tmpAddr);
13861394 builder.createYield (loc);
13871395 });
@@ -1397,7 +1405,7 @@ void LoweringPreparePass::lowerArrayDtor(ArrayDtor op) {
13971405 auto eltTy = op->getRegion (0 ).getArgument (0 ).getType ();
13981406 auto arrayLen =
13991407 mlir::cast<cir::ArrayType>(op.getAddr ().getType ().getPointee ()).getSize ();
1400- lowerArrayDtorCtorIntoLoop (builder, op, eltTy, op.getAddr (), arrayLen);
1408+ lowerArrayDtorCtorIntoLoop (builder, op, eltTy, op.getAddr (), arrayLen, false );
14011409}
14021410
14031411static std::string getGlobalVarNameForConstString (cir::StoreOp op,
@@ -1460,7 +1468,7 @@ void LoweringPreparePass::lowerArrayCtor(ArrayCtor op) {
14601468 auto eltTy = op->getRegion (0 ).getArgument (0 ).getType ();
14611469 auto arrayLen =
14621470 mlir::cast<cir::ArrayType>(op.getAddr ().getType ().getPointee ()).getSize ();
1463- lowerArrayDtorCtorIntoLoop (builder, op, eltTy, op.getAddr (), arrayLen);
1471+ lowerArrayDtorCtorIntoLoop (builder, op, eltTy, op.getAddr (), arrayLen, true );
14641472}
14651473
14661474void LoweringPreparePass::lowerStdFindOp (StdFindOp op) {
0 commit comments