2323#include " mlir/IR/OpImplementation.h"
2424#include " llvm/ADT/APInt.h"
2525#include " llvm/ADT/TypeSwitch.h"
26+ #include " llvm/Support/CommandLine.h"
2627#include < iterator>
2728#include < mlir/Interfaces/SideEffectInterfaces.h>
2829#include < optional>
2930#include < tuple>
3031
32+ static llvm::cl::opt<bool > useStrictIntrinsicVerifier (
33+ " strict-intrinsic-verifier" , llvm::cl::init(false ),
34+ llvm::cl::desc(" use stricter verifier for HLFIR intrinsic operations" ));
35+
3136// / generic implementation of the memory side effects interface for hlfir
3237// / transformational intrinsic operations
3338static void
@@ -498,7 +503,7 @@ verifyLogicalReductionOp(LogicalReductionOp reductionOp) {
498503 mlir::Type resultType = results[0 ];
499504 if (mlir::isa<fir::LogicalType>(resultType)) {
500505 // Result is of the same type as MASK
501- if (resultType != logicalTy)
506+ if (( resultType != logicalTy) && useStrictIntrinsicVerifier )
502507 return reductionOp->emitOpError (
503508 " result must have the same element type as MASK argument" );
504509
@@ -509,7 +514,7 @@ verifyLogicalReductionOp(LogicalReductionOp reductionOp) {
509514 if (!resultExpr.isArray ())
510515 return reductionOp->emitOpError (" result must be an array" );
511516
512- if (resultExpr.getEleTy () != logicalTy)
517+ if (( resultExpr.getEleTy () != logicalTy) && useStrictIntrinsicVerifier )
513518 return reductionOp->emitOpError (
514519 " result must have the same element type as MASK argument" );
515520
@@ -585,7 +590,7 @@ mlir::LogicalResult hlfir::CountOp::verify() {
585590 if (resultShape.size () != (maskShape.size () - 1 ))
586591 return emitOpError (" result rank must be one less than MASK" );
587592 } else {
588- return emitOpError (" result must be of numerical scalar type" );
593+ return emitOpError (" result must be of numerical array type" );
589594 }
590595 } else if (!hlfir::isFortranScalarNumericalType (resultType)) {
591596 return emitOpError (" result must be of numerical scalar type" );
@@ -682,15 +687,18 @@ verifyArrayAndMaskForReductionOp(NumericalReductionOp reductionOp) {
682687 if (!maskShape.empty ()) {
683688 if (maskShape.size () != arrayShape.size ())
684689 return reductionOp->emitWarning (" MASK must be conformable to ARRAY" );
685- static_assert (fir::SequenceType::getUnknownExtent () ==
686- hlfir::ExprType::getUnknownExtent ());
687- constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent ();
688- for (std::size_t i = 0 ; i < arrayShape.size (); ++i) {
689- int64_t arrayExtent = arrayShape[i];
690- int64_t maskExtent = maskShape[i];
691- if ((arrayExtent != maskExtent) && (arrayExtent != unknownExtent) &&
692- (maskExtent != unknownExtent))
693- return reductionOp->emitWarning (" MASK must be conformable to ARRAY" );
690+ if (useStrictIntrinsicVerifier) {
691+ static_assert (fir::SequenceType::getUnknownExtent () ==
692+ hlfir::ExprType::getUnknownExtent ());
693+ constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent ();
694+ for (std::size_t i = 0 ; i < arrayShape.size (); ++i) {
695+ int64_t arrayExtent = arrayShape[i];
696+ int64_t maskExtent = maskShape[i];
697+ if ((arrayExtent != maskExtent) && (arrayExtent != unknownExtent) &&
698+ (maskExtent != unknownExtent))
699+ return reductionOp->emitWarning (
700+ " MASK must be conformable to ARRAY" );
701+ }
694702 }
695703 }
696704 }
@@ -719,7 +727,7 @@ verifyNumericalReductionOp(NumericalReductionOp reductionOp) {
719727 mlir::Type resultType = results[0 ];
720728 if (hlfir::isFortranScalarNumericalType (resultType)) {
721729 // Result is of the same type as ARRAY
722- if (resultType != numTy)
730+ if (( resultType != numTy) && useStrictIntrinsicVerifier )
723731 return reductionOp->emitOpError (
724732 " result must have the same element type as ARRAY argument" );
725733
@@ -729,7 +737,7 @@ verifyNumericalReductionOp(NumericalReductionOp reductionOp) {
729737 if (!resultExpr.isArray ())
730738 return reductionOp->emitOpError (" result must be an array" );
731739
732- if (resultExpr.getEleTy () != numTy)
740+ if (( resultExpr.getEleTy () != numTy) && useStrictIntrinsicVerifier )
733741 return reductionOp->emitOpError (
734742 " result must have the same element type as ARRAY argument" );
735743
@@ -792,7 +800,7 @@ verifyCharacterReductionOp(CharacterReductionOp reductionOp) {
792800 " result must be character" );
793801
794802 // Result is of the same type as ARRAY
795- if (resultType != numTy)
803+ if (( resultType != numTy) && useStrictIntrinsicVerifier )
796804 return reductionOp->emitOpError (
797805 " result must have the same element type as ARRAY argument" );
798806
@@ -823,9 +831,8 @@ mlir::LogicalResult hlfir::MaxvalOp::verify() {
823831 auto resultExpr = mlir::dyn_cast<hlfir::ExprType>(results[0 ]);
824832 if (resultExpr && mlir::isa<fir::CharacterType>(resultExpr.getEleTy ())) {
825833 return verifyCharacterReductionOp<hlfir::MaxvalOp *>(this );
826- } else {
827- return verifyNumericalReductionOp<hlfir::MaxvalOp *>(this );
828834 }
835+ return verifyNumericalReductionOp<hlfir::MaxvalOp *>(this );
829836}
830837
831838void hlfir::MaxvalOp::getEffects (
@@ -848,9 +855,8 @@ mlir::LogicalResult hlfir::MinvalOp::verify() {
848855 auto resultExpr = mlir::dyn_cast<hlfir::ExprType>(results[0 ]);
849856 if (resultExpr && mlir::isa<fir::CharacterType>(resultExpr.getEleTy ())) {
850857 return verifyCharacterReductionOp<hlfir::MinvalOp *>(this );
851- } else {
852- return verifyNumericalReductionOp<hlfir::MinvalOp *>(this );
853858 }
859+ return verifyNumericalReductionOp<hlfir::MinvalOp *>(this );
854860}
855861
856862void hlfir::MinvalOp::getEffects (
@@ -1007,17 +1013,19 @@ mlir::LogicalResult hlfir::DotProductOp::verify() {
10071013
10081014 constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent ();
10091015 if ((lhsSize != unknownExtent) && (rhsSize != unknownExtent) &&
1010- (lhsSize != rhsSize))
1016+ (lhsSize != rhsSize) && useStrictIntrinsicVerifier )
10111017 return emitOpError (" both arrays must have the same size" );
10121018
1013- if (mlir::isa<fir::LogicalType>(lhsEleTy) !=
1014- mlir::isa<fir::LogicalType>(rhsEleTy))
1015- return emitOpError (" if one array is logical, so should the other be" );
1019+ if (useStrictIntrinsicVerifier) {
1020+ if (mlir::isa<fir::LogicalType>(lhsEleTy) !=
1021+ mlir::isa<fir::LogicalType>(rhsEleTy))
1022+ return emitOpError (" if one array is logical, so should the other be" );
10161023
1017- if (mlir::isa<fir::LogicalType>(lhsEleTy) !=
1018- mlir::isa<fir::LogicalType>(resultTy))
1019- return emitOpError (" the result type should be a logical only if the "
1020- " argument types are logical" );
1024+ if (mlir::isa<fir::LogicalType>(lhsEleTy) !=
1025+ mlir::isa<fir::LogicalType>(resultTy))
1026+ return emitOpError (" the result type should be a logical only if the "
1027+ " argument types are logical" );
1028+ }
10211029
10221030 if (!hlfir::isFortranScalarNumericalType (resultTy) &&
10231031 !mlir::isa<fir::LogicalType>(resultTy))
@@ -1067,6 +1075,9 @@ mlir::LogicalResult hlfir::MatmulOp::verify() {
10671075 mlir::isa<fir::LogicalType>(rhsEleTy))
10681076 return emitOpError (" if one array is logical, so should the other be" );
10691077
1078+ if (!useStrictIntrinsicVerifier)
1079+ return mlir::success ();
1080+
10701081 int64_t lastLhsDim = lhsShape[lhsRank - 1 ];
10711082 int64_t firstRhsDim = rhsShape[0 ];
10721083 constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent ();
@@ -1179,6 +1190,9 @@ mlir::LogicalResult hlfir::TransposeOp::verify() {
11791190 if (rank != 2 || resultRank != 2 )
11801191 return emitOpError (" input and output arrays should have rank 2" );
11811192
1193+ if (!useStrictIntrinsicVerifier)
1194+ return mlir::success ();
1195+
11821196 constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent ();
11831197 if ((inShape[0 ] != resultShape[1 ]) && (inShape[0 ] != unknownExtent))
11841198 return emitOpError (" output shape does not match input array" );
@@ -1226,6 +1240,9 @@ mlir::LogicalResult hlfir::MatmulTransposeOp::verify() {
12261240 if ((lhsRank != 2 ) || ((rhsRank != 1 ) && (rhsRank != 2 )))
12271241 return emitOpError (" array must have either rank 1 or rank 2" );
12281242
1243+ if (!useStrictIntrinsicVerifier)
1244+ return mlir::success ();
1245+
12291246 if (mlir::isa<fir::LogicalType>(lhsEleTy) !=
12301247 mlir::isa<fir::LogicalType>(rhsEleTy))
12311248 return emitOpError (" if one array is logical, so should the other be" );
0 commit comments