[Mlir-commits] [mlir] 2a3878e - [mlir] DialectConversion: fix OperationLegalizer::isIllegal result when legality callback returns None

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Nov 15 03:56:08 PST 2021


Author: Butygin
Date: 2021-11-15T14:53:06+03:00
New Revision: 2a3878ea164462caf0b37c46767242b77b66736f

URL: https://github.com/llvm/llvm-project/commit/2a3878ea164462caf0b37c46767242b77b66736f
DIFF: https://github.com/llvm/llvm-project/commit/2a3878ea164462caf0b37c46767242b77b66736f.diff

LOG: [mlir] DialectConversion: fix OperationLegalizer::isIllegal result when legality callback returns None

OperationLegalizer::isIllegal returns false if operation legality wasn't
registered by user and we expect same behaviour when dynamic legality
callback return None, but instead true was returned.

Differential Revision: https://reviews.llvm.org/D113267

Added: 
    

Modified: 
    mlir/include/mlir/Transforms/DialectConversion.h
    mlir/lib/Transforms/Utils/DialectConversion.cpp
    mlir/unittests/Transforms/DialectConversion.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Transforms/DialectConversion.h b/mlir/include/mlir/Transforms/DialectConversion.h
index 849d5427ed7c..2953a5d43c9a 100644
--- a/mlir/include/mlir/Transforms/DialectConversion.h
+++ b/mlir/include/mlir/Transforms/DialectConversion.h
@@ -793,9 +793,19 @@ class ConversionTarget {
 
   /// If the given operation instance is legal on this target, a structure
   /// containing legality information is returned. If the operation is not
-  /// legal, None is returned.
+  /// legal, None is returned. Also returns None is operation legality wasn't
+  /// registered by user or dynamic legality callbacks returned None.
+  ///
+  /// Note: Legality is actually a 4-state: Legal(recursive=true),
+  /// Legal(recursive=false), Illegal or Unknown, where Unknown is treated
+  /// either as Legal or Illegal depending on context.
   Optional<LegalOpDetails> isLegal(Operation *op) const;
 
+  /// Returns true is operation instance is illegal on this target. Returns
+  /// false if operation is legal, operation legality wasn't registered by user
+  /// or dynamic legality callbacks returned None.
+  bool isIllegal(Operation *op) const;
+
 private:
   /// Set the dynamic legality callback for the given operation.
   void setLegalityCallback(OperationName name,

diff  --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp
index cea4b2aaf80b..cc83ab353b06 100644
--- a/mlir/lib/Transforms/Utils/DialectConversion.cpp
+++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp
@@ -1816,14 +1816,7 @@ OperationLegalizer::OperationLegalizer(ConversionTarget &targetInfo,
 }
 
 bool OperationLegalizer::isIllegal(Operation *op) const {
-  // Check if the target explicitly marked this operation as illegal.
-  if (auto info = target.getOpAction(op->getName())) {
-    if (*info == LegalizationAction::Dynamic)
-      return !target.isLegal(op);
-    return *info == LegalizationAction::Illegal;
-  }
-
-  return false;
+  return target.isIllegal(op);
 }
 
 LogicalResult
@@ -3137,6 +3130,22 @@ auto ConversionTarget::isLegal(Operation *op) const
   return legalityDetails;
 }
 
+bool ConversionTarget::isIllegal(Operation *op) const {
+  Optional<LegalizationInfo> info = getOpInfo(op->getName());
+  if (!info)
+    return false;
+
+  if (info->action == LegalizationAction::Dynamic) {
+    Optional<bool> result = info->legalityFn(op);
+    if (!result)
+      return false;
+
+    return !(*result);
+  }
+
+  return info->action == LegalizationAction::Illegal;
+}
+
 static ConversionTarget::DynamicLegalityCallbackFn composeLegalityCallbacks(
     ConversionTarget::DynamicLegalityCallbackFn oldCallback,
     ConversionTarget::DynamicLegalityCallbackFn newCallback) {

diff  --git a/mlir/unittests/Transforms/DialectConversion.cpp b/mlir/unittests/Transforms/DialectConversion.cpp
index d3e7ff6909e4..13ce43160f4e 100644
--- a/mlir/unittests/Transforms/DialectConversion.cpp
+++ b/mlir/unittests/Transforms/DialectConversion.cpp
@@ -44,6 +44,9 @@ TEST(DialectConversionTest, DynamicallyLegalOpCallbackOrder) {
   EXPECT_TRUE(target.isLegal(op));
   EXPECT_EQ(2, callbackCalled1);
   EXPECT_EQ(1, callbackCalled2);
+  EXPECT_FALSE(target.isIllegal(op));
+  EXPECT_EQ(4, callbackCalled1);
+  EXPECT_EQ(3, callbackCalled2);
   op->destroy();
 }
 
@@ -61,6 +64,8 @@ TEST(DialectConversionTest, DynamicallyLegalOpCallbackSkip) {
   auto *op = createOp(&context);
   EXPECT_FALSE(target.isLegal(op));
   EXPECT_EQ(1, callbackCalled);
+  EXPECT_FALSE(target.isIllegal(op));
+  EXPECT_EQ(2, callbackCalled);
   op->destroy();
 }
 
@@ -85,6 +90,43 @@ TEST(DialectConversionTest, DynamicallyLegalUnknownOpCallbackOrder) {
   EXPECT_TRUE(target.isLegal(op));
   EXPECT_EQ(2, callbackCalled1);
   EXPECT_EQ(1, callbackCalled2);
+  EXPECT_FALSE(target.isIllegal(op));
+  EXPECT_EQ(4, callbackCalled1);
+  EXPECT_EQ(3, callbackCalled2);
+  op->destroy();
+}
+
+TEST(DialectConversionTest, DynamicallyLegalReturnNone) {
+  MLIRContext context;
+  ConversionTarget target(context);
+
+  target.addDynamicallyLegalOp<DummyOp>(
+      [&](Operation *) -> Optional<bool> { return llvm::None; });
+
+  auto *op = createOp(&context);
+  EXPECT_FALSE(target.isLegal(op));
+  EXPECT_FALSE(target.isIllegal(op));
+
+  EXPECT_TRUE(succeeded(applyPartialConversion(op, target, {})));
+  EXPECT_TRUE(failed(applyFullConversion(op, target, {})));
+
+  op->destroy();
+}
+
+TEST(DialectConversionTest, DynamicallyLegalUnknownReturnNone) {
+  MLIRContext context;
+  ConversionTarget target(context);
+
+  target.markUnknownOpDynamicallyLegal(
+      [&](Operation *) -> Optional<bool> { return llvm::None; });
+
+  auto *op = createOp(&context);
+  EXPECT_FALSE(target.isLegal(op));
+  EXPECT_FALSE(target.isIllegal(op));
+
+  EXPECT_TRUE(succeeded(applyPartialConversion(op, target, {})));
+  EXPECT_TRUE(failed(applyFullConversion(op, target, {})));
+
   op->destroy();
 }
 } // namespace


        


More information about the Mlir-commits mailing list