diff --git a/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.cpp b/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.cpp --- a/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.cpp +++ b/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.cpp @@ -214,20 +214,20 @@ /// within that pattern. DenseMap patternToAnswer; - /// Returns true if this predicate is ordered before `other`, based on the - /// cost model. - bool operator<(const OrderedPredicate &other) const { + /// Returns true if this predicate is ordered before `rhs`, based on the cost + /// model. + bool operator<(const OrderedPredicate &rhs) const { // Sort by: - // * first and secondary order sums + // * higher first and secondary order sums // * lower depth - // * position dependency - // * predicate dependency. - auto *otherPos = other.position; - return std::make_tuple(other.primary, other.secondary, - otherPos->getIndex().size(), otherPos->getKind(), - other.question->getKind()) > - std::make_tuple(primary, secondary, position->getIndex().size(), - position->getKind(), question->getKind()); + // * lower position dependency + // * lower predicate dependency + auto *rhsPos = rhs.position; + return std::make_tuple(primary, secondary, rhsPos->getIndex().size(), + rhsPos->getKind(), rhs.question->getKind()) > + std::make_tuple(rhs.primary, rhs.secondary, + position->getIndex().size(), position->getKind(), + question->getKind()); } }; diff --git a/mlir/test/Conversion/PDLToPDLInterp/pdl-to-pdl-interp-matcher.mlir b/mlir/test/Conversion/PDLToPDLInterp/pdl-to-pdl-interp-matcher.mlir --- a/mlir/test/Conversion/PDLToPDLInterp/pdl-to-pdl-interp-matcher.mlir +++ b/mlir/test/Conversion/PDLToPDLInterp/pdl-to-pdl-interp-matcher.mlir @@ -143,3 +143,31 @@ pdl.rewrite %root with "rewriter" } } + +// ----- + +// CHECK-LABEL: module @predicate_ordering +module @predicate_ordering { + // Check that the result is checked for null first, before applying the + // constraint. The null check is prevalent in both patterns, so should be + // prioritized first. + + // CHECK: func @matcher(%[[ROOT:.*]]: !pdl.operation) + // CHECK: %[[RESULT:.*]] = pdl_interp.get_result 0 of %[[ROOT]] + // CHECK-NEXT: pdl_interp.is_not_null %[[RESULT]] + // CHECK: %[[RESULT_TYPE:.*]] = pdl_interp.get_value_type of %[[RESULT]] + // CHECK: pdl_interp.apply_constraint "typeConstraint" [](%[[RESULT_TYPE]] + + pdl.pattern : benefit(1) { + %resultType = pdl.type + pdl.apply_constraint "typeConstraint"[](%resultType : !pdl.type) + %root, %result = pdl.operation -> %resultType + pdl.rewrite %root with "rewriter" + } + + pdl.pattern : benefit(1) { + %resultType = pdl.type + %apply, %applyRes = pdl.operation -> %resultType + pdl.rewrite %apply with "rewriter" + } +}