@@ -67,6 +67,33 @@ getIntrinsicEffects(mlir::Operation *self,
6767 }
6868}
6969
70+ // / Verification helper for checking if two types are the same.
71+ // / Set \p allowCharacterLenMismatch to true, if character types
72+ // / of different known lengths should be treated as the same.
73+ template <typename Op>
74+ static llvm::LogicalResult areMatchingTypes (Op &op, mlir::Type type1,
75+ mlir::Type type2,
76+ bool allowCharacterLenMismatch) {
77+ if (auto charType1 = mlir::dyn_cast<fir::CharacterType>(type1))
78+ if (auto charType2 = mlir::dyn_cast<fir::CharacterType>(type2)) {
79+ // Character kinds must match.
80+ if (charType1.getFKind () != charType2.getFKind ())
81+ return op.emitOpError (" character KIND mismatch" );
82+
83+ // Constant propagation can result in mismatching lengths
84+ // in the dead code, but we should not fail on this.
85+ if (!allowCharacterLenMismatch)
86+ if (charType1.getLen () != fir::CharacterType::unknownLen () &&
87+ charType2.getLen () != fir::CharacterType::unknownLen () &&
88+ charType1.getLen () != charType2.getLen ())
89+ return op.emitOpError (" character LEN mismatch" );
90+
91+ return mlir::success ();
92+ }
93+
94+ return type1 == type2 ? mlir::success () : mlir::failure ();
95+ }
96+
7097// ===----------------------------------------------------------------------===//
7198// DeclareOp
7299// ===----------------------------------------------------------------------===//
@@ -1360,23 +1387,12 @@ llvm::LogicalResult hlfir::CShiftOp::verify() {
13601387 mlir::Value shift = getShift ();
13611388 mlir::Type shiftTy = hlfir::getFortranElementOrSequenceType (shift.getType ());
13621389
1363- if (eleTy != resultEleTy) {
1364- if (mlir::isa<fir::CharacterType>(eleTy) &&
1365- mlir::isa<fir::CharacterType>(resultEleTy)) {
1366- auto eleCharTy = mlir::cast<fir::CharacterType>(eleTy);
1367- auto resultCharTy = mlir::cast<fir::CharacterType>(resultEleTy);
1368- if (eleCharTy.getFKind () != resultCharTy.getFKind ())
1369- return emitOpError (" kind mismatch between input and output arrays" );
1370- if (eleCharTy.getLen () != fir::CharacterType::unknownLen () &&
1371- resultCharTy.getLen () != fir::CharacterType::unknownLen () &&
1372- eleCharTy.getLen () != resultCharTy.getLen ())
1373- return emitOpError (
1374- " character LEN mismatch between input and output arrays" );
1375- } else {
1376- return emitOpError (
1377- " input and output arrays should have the same element type" );
1378- }
1379- }
1390+ // TODO: turn allowCharacterLenMismatch into true.
1391+ if (auto match = areMatchingTypes (*this , eleTy, resultEleTy,
1392+ /* allowCharacterLenMismatch=*/ false );
1393+ match.failed ())
1394+ return emitOpError (
1395+ " input and output arrays should have the same element type" );
13801396
13811397 if (arrayRank != resultRank)
13821398 return emitOpError (" input and output arrays should have the same rank" );
@@ -1444,6 +1460,67 @@ void hlfir::CShiftOp::getEffects(
14441460 getIntrinsicEffects (getOperation (), effects);
14451461}
14461462
1463+ // ===----------------------------------------------------------------------===//
1464+ // ReshapeOp
1465+ // ===----------------------------------------------------------------------===//
1466+
1467+ llvm::LogicalResult hlfir::ReshapeOp::verify () {
1468+ auto results = getOperation ()->getResultTypes ();
1469+ assert (results.size () == 1 );
1470+ hlfir::ExprType resultType = mlir::cast<hlfir::ExprType>(results[0 ]);
1471+ mlir::Value array = getArray ();
1472+ auto arrayType = mlir::cast<fir::SequenceType>(
1473+ hlfir::getFortranElementOrSequenceType (array.getType ()));
1474+ if (auto match = areMatchingTypes (
1475+ *this , hlfir::getFortranElementType (resultType),
1476+ arrayType.getElementType (), /* allowCharacterLenMismatch=*/ true );
1477+ match.failed ())
1478+ return emitOpError (" ARRAY and the result must have the same element type" );
1479+ if (hlfir::isPolymorphicType (resultType) !=
1480+ hlfir::isPolymorphicType (array.getType ()))
1481+ return emitOpError (" ARRAY must be polymorphic iff result is polymorphic" );
1482+
1483+ mlir::Value shape = getShape ();
1484+ auto shapeArrayType = mlir::cast<fir::SequenceType>(
1485+ hlfir::getFortranElementOrSequenceType (shape.getType ()));
1486+ if (shapeArrayType.getDimension () != 1 )
1487+ return emitOpError (" SHAPE must be an array of rank 1" );
1488+ if (!mlir::isa<mlir::IntegerType>(shapeArrayType.getElementType ()))
1489+ return emitOpError (" SHAPE must be an integer array" );
1490+ if (shapeArrayType.hasDynamicExtents ())
1491+ return emitOpError (" SHAPE must have known size" );
1492+ if (shapeArrayType.getConstantArraySize () != resultType.getRank ())
1493+ return emitOpError (" SHAPE's extent must match the result rank" );
1494+
1495+ if (mlir::Value pad = getPad ()) {
1496+ auto padArrayType = mlir::cast<fir::SequenceType>(
1497+ hlfir::getFortranElementOrSequenceType (pad.getType ()));
1498+ if (auto match = areMatchingTypes (*this , arrayType.getElementType (),
1499+ padArrayType.getElementType (),
1500+ /* allowCharacterLenMismatch=*/ true );
1501+ match.failed ())
1502+ return emitOpError (" ARRAY and PAD must be of the same type" );
1503+ }
1504+
1505+ if (mlir::Value order = getOrder ()) {
1506+ auto orderArrayType = mlir::cast<fir::SequenceType>(
1507+ hlfir::getFortranElementOrSequenceType (order.getType ()));
1508+ if (orderArrayType.getDimension () != 1 )
1509+ return emitOpError (" ORDER must be an array of rank 1" );
1510+ if (!mlir::isa<mlir::IntegerType>(orderArrayType.getElementType ()))
1511+ return emitOpError (" ORDER must be an integer array" );
1512+ }
1513+
1514+ return mlir::success ();
1515+ }
1516+
1517+ void hlfir::ReshapeOp::getEffects (
1518+ llvm::SmallVectorImpl<
1519+ mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
1520+ &effects) {
1521+ getIntrinsicEffects (getOperation (), effects);
1522+ }
1523+
14471524// ===----------------------------------------------------------------------===//
14481525// AssociateOp
14491526// ===----------------------------------------------------------------------===//
0 commit comments