@@ -1440,96 +1440,148 @@ void hlfir::MatmulTransposeOp::getEffects(
1440
1440
}
1441
1441
1442
1442
// ===----------------------------------------------------------------------===//
1443
- // CShiftOp
1443
+ // Array shifts: CShiftOp/EOShiftOp
1444
1444
// ===----------------------------------------------------------------------===//
1445
1445
1446
- llvm::LogicalResult hlfir::CShiftOp::verify () {
1447
- mlir::Value array = getArray ();
1446
+ template <typename Op>
1447
+ static llvm::LogicalResult verifyArrayShift (Op op) {
1448
+ mlir::Value array = op.getArray ();
1448
1449
fir::SequenceType arrayTy = mlir::cast<fir::SequenceType>(
1449
1450
hlfir::getFortranElementOrSequenceType (array.getType ()));
1450
1451
llvm::ArrayRef<int64_t > inShape = arrayTy.getShape ();
1451
1452
std::size_t arrayRank = inShape.size ();
1452
1453
mlir::Type eleTy = arrayTy.getEleTy ();
1453
- hlfir::ExprType resultTy = mlir::cast<hlfir::ExprType>(getResult ().getType ());
1454
+ hlfir::ExprType resultTy =
1455
+ mlir::cast<hlfir::ExprType>(op.getResult ().getType ());
1454
1456
llvm::ArrayRef<int64_t > resultShape = resultTy.getShape ();
1455
1457
std::size_t resultRank = resultShape.size ();
1456
1458
mlir::Type resultEleTy = resultTy.getEleTy ();
1457
- mlir::Value shift = getShift ();
1459
+ mlir::Value shift = op. getShift ();
1458
1460
mlir::Type shiftTy = hlfir::getFortranElementOrSequenceType (shift.getType ());
1459
1461
1460
- // TODO: turn allowCharacterLenMismatch into true.
1461
- if ( auto match = areMatchingTypes (* this , eleTy, resultEleTy,
1462
- /* allowCharacterLenMismatch=*/ false );
1462
+ if ( auto match = areMatchingTypes (
1463
+ op , eleTy, resultEleTy,
1464
+ /* allowCharacterLenMismatch=*/ !useStrictIntrinsicVerifier );
1463
1465
match.failed ())
1464
- return emitOpError (
1466
+ return op. emitOpError (
1465
1467
" input and output arrays should have the same element type" );
1466
1468
1467
1469
if (arrayRank != resultRank)
1468
- return emitOpError (" input and output arrays should have the same rank" );
1470
+ return op. emitOpError (" input and output arrays should have the same rank" );
1469
1471
1470
1472
constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent ();
1471
1473
for (auto [inDim, resultDim] : llvm::zip (inShape, resultShape))
1472
1474
if (inDim != unknownExtent && resultDim != unknownExtent &&
1473
1475
inDim != resultDim)
1474
- return emitOpError (
1476
+ return op. emitOpError (
1475
1477
" output array's shape conflicts with the input array's shape" );
1476
1478
1477
1479
int64_t dimVal = -1 ;
1478
- if (!getDim ())
1480
+ if (!op. getDim ())
1479
1481
dimVal = 1 ;
1480
- else if (auto dim = fir::getIntIfConstant (getDim ()))
1482
+ else if (auto dim = fir::getIntIfConstant (op. getDim ()))
1481
1483
dimVal = *dim;
1482
1484
1483
1485
// The DIM argument may be statically invalid (e.g. exceed the
1484
1486
// input array rank) in dead code after constant propagation,
1485
1487
// so avoid some checks unless useStrictIntrinsicVerifier is true.
1486
1488
if (useStrictIntrinsicVerifier && dimVal != -1 ) {
1487
1489
if (dimVal < 1 )
1488
- return emitOpError (" DIM must be >= 1" );
1490
+ return op. emitOpError (" DIM must be >= 1" );
1489
1491
if (dimVal > static_cast <int64_t >(arrayRank))
1490
- return emitOpError (" DIM must be <= input array's rank" );
1492
+ return op. emitOpError (" DIM must be <= input array's rank" );
1491
1493
}
1492
1494
1493
- if (auto shiftSeqTy = mlir::dyn_cast<fir::SequenceType>(shiftTy)) {
1494
- // SHIFT is an array. Verify the rank and the shape (if DIM is constant).
1495
- llvm::ArrayRef<int64_t > shiftShape = shiftSeqTy.getShape ();
1496
- std::size_t shiftRank = shiftShape.size ();
1497
- if (shiftRank != arrayRank - 1 )
1498
- return emitOpError (
1499
- " SHIFT's rank must be 1 less than the input array's rank" );
1500
-
1501
- if (useStrictIntrinsicVerifier && dimVal != -1 ) {
1502
- // SHIFT's shape must be [d(1), d(2), ..., d(DIM-1), d(DIM+1), ..., d(n)],
1503
- // where [d(1), d(2), ..., d(n)] is the shape of the ARRAY.
1504
- int64_t arrayDimIdx = 0 ;
1505
- int64_t shiftDimIdx = 0 ;
1506
- for (auto shiftDim : shiftShape) {
1507
- if (arrayDimIdx == dimVal - 1 )
1495
+ // A helper lambda to verify the shape of the array types of
1496
+ // certain operands of the array shift (e.g. the SHIFT and BOUNDARY operands).
1497
+ auto verifyOperandTypeShape = [&](mlir::Type type,
1498
+ llvm::Twine name) -> llvm::LogicalResult {
1499
+ if (auto opndSeqTy = mlir::dyn_cast<fir::SequenceType>(type)) {
1500
+ // The operand is an array. Verify the rank and the shape (if DIM is
1501
+ // constant).
1502
+ llvm::ArrayRef<int64_t > opndShape = opndSeqTy.getShape ();
1503
+ std::size_t opndRank = opndShape.size ();
1504
+ if (opndRank != arrayRank - 1 )
1505
+ return op.emitOpError (
1506
+ name + " 's rank must be 1 less than the input array's rank" );
1507
+
1508
+ if (useStrictIntrinsicVerifier && dimVal != -1 ) {
1509
+ // The operand's shape must be
1510
+ // [d(1), d(2), ..., d(DIM-1), d(DIM+1), ..., d(n)],
1511
+ // where [d(1), d(2), ..., d(n)] is the shape of the ARRAY.
1512
+ int64_t arrayDimIdx = 0 ;
1513
+ int64_t opndDimIdx = 0 ;
1514
+ for (auto opndDim : opndShape) {
1515
+ if (arrayDimIdx == dimVal - 1 )
1516
+ ++arrayDimIdx;
1517
+
1518
+ if (inShape[arrayDimIdx] != unknownExtent &&
1519
+ opndDim != unknownExtent && inShape[arrayDimIdx] != opndDim)
1520
+ return op.emitOpError (" SHAPE(ARRAY)(" +
1521
+ llvm::Twine (arrayDimIdx + 1 ) +
1522
+ " ) must be equal to SHAPE(" + name + " )(" +
1523
+ llvm::Twine (opndDimIdx + 1 ) +
1524
+ " ): " + llvm::Twine (inShape[arrayDimIdx]) +
1525
+ " != " + llvm::Twine (opndDim));
1508
1526
++arrayDimIdx;
1509
-
1510
- if (inShape[arrayDimIdx] != unknownExtent &&
1511
- shiftDim != unknownExtent && inShape[arrayDimIdx] != shiftDim)
1512
- return emitOpError (" SHAPE(ARRAY)(" + llvm::Twine (arrayDimIdx + 1 ) +
1513
- " ) must be equal to SHAPE(SHIFT)(" +
1514
- llvm::Twine (shiftDimIdx + 1 ) +
1515
- " ): " + llvm::Twine (inShape[arrayDimIdx]) +
1516
- " != " + llvm::Twine (shiftDim));
1517
- ++arrayDimIdx;
1518
- ++shiftDimIdx;
1527
+ ++opndDimIdx;
1528
+ }
1519
1529
}
1520
1530
}
1531
+ return mlir::success ();
1532
+ };
1533
+
1534
+ if (failed (verifyOperandTypeShape (shiftTy, " SHIFT" )))
1535
+ return mlir::failure ();
1536
+
1537
+ if constexpr (std::is_same_v<Op, hlfir::EOShiftOp>) {
1538
+ if (mlir::Value boundary = op.getBoundary ()) {
1539
+ mlir::Type boundaryTy =
1540
+ hlfir::getFortranElementOrSequenceType (boundary.getType ());
1541
+ if (auto match = areMatchingTypes (
1542
+ op, eleTy, hlfir::getFortranElementType (boundaryTy),
1543
+ /* allowCharacterLenMismatch=*/ !useStrictIntrinsicVerifier);
1544
+ match.failed ())
1545
+ return op.emitOpError (
1546
+ " ARRAY and BOUNDARY operands must have the same element type" );
1547
+ if (failed (verifyOperandTypeShape (boundaryTy, " BOUNDARY" )))
1548
+ return mlir::failure ();
1549
+ }
1521
1550
}
1522
1551
1523
1552
return mlir::success ();
1524
1553
}
1525
1554
1555
+ // ===----------------------------------------------------------------------===//
1556
+ // CShiftOp
1557
+ // ===----------------------------------------------------------------------===//
1558
+
1559
+ llvm::LogicalResult hlfir::CShiftOp::verify () {
1560
+ return verifyArrayShift (*this );
1561
+ }
1562
+
1526
1563
void hlfir::CShiftOp::getEffects (
1527
1564
llvm::SmallVectorImpl<
1528
1565
mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
1529
1566
&effects) {
1530
1567
getIntrinsicEffects (getOperation (), effects);
1531
1568
}
1532
1569
1570
+ // ===----------------------------------------------------------------------===//
1571
+ // EOShiftOp
1572
+ // ===----------------------------------------------------------------------===//
1573
+
1574
+ llvm::LogicalResult hlfir::EOShiftOp::verify () {
1575
+ return verifyArrayShift (*this );
1576
+ }
1577
+
1578
+ void hlfir::EOShiftOp::getEffects (
1579
+ llvm::SmallVectorImpl<
1580
+ mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
1581
+ &effects) {
1582
+ getIntrinsicEffects (getOperation (), effects);
1583
+ }
1584
+
1533
1585
// ===----------------------------------------------------------------------===//
1534
1586
// ReshapeOp
1535
1587
// ===----------------------------------------------------------------------===//
@@ -1543,7 +1595,8 @@ llvm::LogicalResult hlfir::ReshapeOp::verify() {
1543
1595
hlfir::getFortranElementOrSequenceType (array.getType ()));
1544
1596
if (auto match = areMatchingTypes (
1545
1597
*this , hlfir::getFortranElementType (resultType),
1546
- arrayType.getElementType (), /* allowCharacterLenMismatch=*/ true );
1598
+ arrayType.getElementType (),
1599
+ /* allowCharacterLenMismatch=*/ !useStrictIntrinsicVerifier);
1547
1600
match.failed ())
1548
1601
return emitOpError (" ARRAY and the result must have the same element type" );
1549
1602
if (hlfir::isPolymorphicType (resultType) !=
@@ -1565,9 +1618,9 @@ llvm::LogicalResult hlfir::ReshapeOp::verify() {
1565
1618
if (mlir::Value pad = getPad ()) {
1566
1619
auto padArrayType = mlir::cast<fir::SequenceType>(
1567
1620
hlfir::getFortranElementOrSequenceType (pad.getType ()));
1568
- if (auto match = areMatchingTypes (* this , arrayType. getElementType (),
1569
- padArrayType.getElementType (),
1570
- /* allowCharacterLenMismatch=*/ true );
1621
+ if (auto match = areMatchingTypes (
1622
+ * this , arrayType. getElementType (), padArrayType.getElementType (),
1623
+ /* allowCharacterLenMismatch=*/ !useStrictIntrinsicVerifier );
1571
1624
match.failed ())
1572
1625
return emitOpError (" ARRAY and PAD must be of the same type" );
1573
1626
}
0 commit comments