@@ -1341,6 +1341,108 @@ 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+ if (mlir::isa<fir::CharacterType>(eleTy) &&
1364+ mlir::isa<fir::CharacterType>(resultEleTy)) {
1365+ auto eleCharTy = mlir::cast<fir::CharacterType>(eleTy);
1366+ auto resultCharTy = mlir::cast<fir::CharacterType>(resultEleTy);
1367+ if (eleCharTy.getFKind () != resultCharTy.getFKind ())
1368+ return emitOpError (" kind mismatch between input and output arrays" );
1369+ if (eleCharTy.getLen () != fir::CharacterType::unknownLen () &&
1370+ resultCharTy.getLen () != fir::CharacterType::unknownLen () &&
1371+ eleCharTy.getLen () != resultCharTy.getLen ())
1372+ return emitOpError (
1373+ " character LEN mismatch between input and output arrays" );
1374+ } else {
1375+ return emitOpError (
1376+ " input and output arrays should have the same element type" );
1377+ }
1378+ }
1379+
1380+ if (arrayRank != resultRank)
1381+ return emitOpError (" input and output arrays should have the same rank" );
1382+
1383+ constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent ();
1384+ for (auto [inDim, resultDim] : llvm::zip (inShape, resultShape))
1385+ if (inDim != unknownExtent && resultDim != unknownExtent &&
1386+ inDim != resultDim)
1387+ return emitOpError (
1388+ " output array's shape conflicts with the input array's shape" );
1389+
1390+ int64_t dimVal = -1 ;
1391+ if (!getDim ())
1392+ dimVal = 1 ;
1393+ else if (auto dim = fir::getIntIfConstant (getDim ()))
1394+ dimVal = *dim;
1395+
1396+ // The DIM argument may be statically invalid (e.g. exceed the
1397+ // input array rank) in dead code after constant propagation,
1398+ // so avoid some checks unless useStrictIntrinsicVerifier is true.
1399+ if (useStrictIntrinsicVerifier && dimVal != -1 ) {
1400+ if (dimVal < 1 )
1401+ return emitOpError (" DIM must be >= 1" );
1402+ if (dimVal > static_cast <int64_t >(arrayRank))
1403+ return emitOpError (" DIM must be <= input array's rank" );
1404+ }
1405+
1406+ if (auto shiftSeqTy = mlir::dyn_cast<fir::SequenceType>(shiftTy)) {
1407+ // SHIFT is an array. Verify the rank and the shape (if DIM is constant).
1408+ llvm::ArrayRef<int64_t > shiftShape = shiftSeqTy.getShape ();
1409+ std::size_t shiftRank = shiftShape.size ();
1410+ if (shiftRank != arrayRank - 1 )
1411+ return emitOpError (
1412+ " SHIFT's rank must be 1 less than the input array's rank" );
1413+
1414+ if (useStrictIntrinsicVerifier && dimVal != -1 ) {
1415+ // SHIFT's shape must be [d(1), d(2), ..., d(DIM-1), d(DIM+1), ..., d(n)],
1416+ // where [d(1), d(2), ..., d(n)] is the shape of the ARRAY.
1417+ int64_t arrayDimIdx = 0 ;
1418+ int64_t shiftDimIdx = 0 ;
1419+ for (auto shiftDim : shiftShape) {
1420+ if (arrayDimIdx == dimVal - 1 )
1421+ ++arrayDimIdx;
1422+
1423+ if (inShape[arrayDimIdx] != unknownExtent &&
1424+ shiftDim != unknownExtent && inShape[arrayDimIdx] != shiftDim)
1425+ return emitOpError (" SHAPE(ARRAY)(" + llvm::Twine (arrayDimIdx + 1 ) +
1426+ " ) must be equal to SHAPE(SHIFT)(" +
1427+ llvm::Twine (shiftDimIdx + 1 ) +
1428+ " ): " + llvm::Twine (inShape[arrayDimIdx]) +
1429+ " != " + llvm::Twine (shiftDim));
1430+ ++arrayDimIdx;
1431+ ++shiftDimIdx;
1432+ }
1433+ }
1434+ }
1435+
1436+ return mlir::success ();
1437+ }
1438+
1439+ void hlfir::CShiftOp::getEffects (
1440+ llvm::SmallVectorImpl<
1441+ mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
1442+ &effects) {
1443+ getIntrinsicEffects (getOperation (), effects);
1444+ }
1445+
13441446// ===----------------------------------------------------------------------===//
13451447// AssociateOp
13461448// ===----------------------------------------------------------------------===//
0 commit comments