@@ -1341,6 +1341,91 @@ void hlfir::MatmulTransposeOp::getEffects(
13411341 getIntrinsicEffects (getOperation (), effects);
13421342}
13431343
1344+ // ===----------------------------------------------------------------------===//
1345+ // CShiftOp
1346+ // ===----------------------------------------------------------------------===//
1347+
1348+ llvm::LogicalResult hlfir::CShiftOp::verify () {
1349+ mlir::Value array = getArray ();
1350+ fir::SequenceType arrayTy = mlir::cast<fir::SequenceType>(
1351+ hlfir::getFortranElementOrSequenceType (array.getType ()));
1352+ llvm::ArrayRef<int64_t > inShape = arrayTy.getShape ();
1353+ std::size_t arrayRank = inShape.size ();
1354+ mlir::Type eleTy = arrayTy.getEleTy ();
1355+ hlfir::ExprType resultTy = mlir::cast<hlfir::ExprType>(getResult ().getType ());
1356+ llvm::ArrayRef<int64_t > resultShape = resultTy.getShape ();
1357+ std::size_t resultRank = resultShape.size ();
1358+ mlir::Type resultEleTy = resultTy.getEleTy ();
1359+ mlir::Value shift = getShift ();
1360+ mlir::Type shiftTy = hlfir::getFortranElementOrSequenceType (shift.getType ());
1361+
1362+ if (eleTy != resultEleTy)
1363+ return emitOpError (
1364+ " input and output arrays should have the same element type" );
1365+
1366+ if (arrayRank != resultRank)
1367+ return emitOpError (" input and output arrays should have the same rank" );
1368+
1369+ constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent ();
1370+ for (auto [inDim, resultDim] : llvm::zip (inShape, resultShape))
1371+ if (inDim != unknownExtent && resultDim != unknownExtent &&
1372+ inDim != resultDim)
1373+ return emitOpError (
1374+ " output array's shape conflicts with the input array's shape" );
1375+
1376+ int64_t dimVal = -1 ;
1377+ if (!getDim ())
1378+ dimVal = 1 ;
1379+ else if (auto dim = fir::getIntIfConstant (getDim ()))
1380+ dimVal = *dim;
1381+
1382+ if (dimVal != -1 ) {
1383+ if (dimVal < 1 )
1384+ return emitOpError (" DIM must be >= 1" );
1385+ if (dimVal > static_cast <int64_t >(arrayRank))
1386+ return emitOpError (" DIM must be <= input array's rank" );
1387+ }
1388+
1389+ if (auto shiftSeqTy = mlir::dyn_cast<fir::SequenceType>(shiftTy)) {
1390+ // SHIFT is an array. Verify the rank and the shape (if DIM is constant).
1391+ llvm::ArrayRef<int64_t > shiftShape = shiftSeqTy.getShape ();
1392+ std::size_t shiftRank = shiftShape.size ();
1393+ if (shiftRank != arrayRank - 1 )
1394+ return emitOpError (
1395+ " SHIFT's rank must be 1 less than the input array's rank" );
1396+
1397+ if (dimVal != -1 ) {
1398+ // SHIFT's shape must be [d(1), d(2), ..., d(DIM-1), d(DIM+1), ..., d(n)],
1399+ // where [d(1), d(2), ..., d(n)] is the shape of the ARRAY.
1400+ int64_t arrayDimIdx = 0 ;
1401+ int64_t shiftDimIdx = 0 ;
1402+ for (auto shiftDim : shiftShape) {
1403+ if (arrayDimIdx == dimVal - 1 )
1404+ ++arrayDimIdx;
1405+
1406+ if (inShape[arrayDimIdx] != unknownExtent &&
1407+ shiftDim != unknownExtent && inShape[arrayDimIdx] != shiftDim)
1408+ return emitOpError (" SHAPE(ARRAY)(" + llvm::Twine (arrayDimIdx + 1 ) +
1409+ " ) must be equal to SHAPE(SHIFT)(" +
1410+ llvm::Twine (shiftDimIdx + 1 ) +
1411+ " ): " + llvm::Twine (inShape[arrayDimIdx]) +
1412+ " != " + llvm::Twine (shiftDim));
1413+ ++arrayDimIdx;
1414+ ++shiftDimIdx;
1415+ }
1416+ }
1417+ }
1418+
1419+ return mlir::success ();
1420+ }
1421+
1422+ void hlfir::CShiftOp::getEffects (
1423+ llvm::SmallVectorImpl<
1424+ mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
1425+ &effects) {
1426+ getIntrinsicEffects (getOperation (), effects);
1427+ }
1428+
13441429// ===----------------------------------------------------------------------===//
13451430// AssociateOp
13461431// ===----------------------------------------------------------------------===//
0 commit comments