@@ -67,6 +67,33 @@ getIntrinsicEffects(mlir::Operation *self,
67
67
}
68
68
}
69
69
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
+
70
97
// ===----------------------------------------------------------------------===//
71
98
// DeclareOp
72
99
// ===----------------------------------------------------------------------===//
@@ -1360,23 +1387,12 @@ llvm::LogicalResult hlfir::CShiftOp::verify() {
1360
1387
mlir::Value shift = getShift ();
1361
1388
mlir::Type shiftTy = hlfir::getFortranElementOrSequenceType (shift.getType ());
1362
1389
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" );
1380
1396
1381
1397
if (arrayRank != resultRank)
1382
1398
return emitOpError (" input and output arrays should have the same rank" );
@@ -1444,6 +1460,67 @@ void hlfir::CShiftOp::getEffects(
1444
1460
getIntrinsicEffects (getOperation (), effects);
1445
1461
}
1446
1462
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
+
1447
1524
// ===----------------------------------------------------------------------===//
1448
1525
// AssociateOp
1449
1526
// ===----------------------------------------------------------------------===//
0 commit comments