diff --git a/mlir/lib/Pass/IRPrinting.cpp b/mlir/lib/Pass/IRPrinting.cpp --- a/mlir/lib/Pass/IRPrinting.cpp +++ b/mlir/lib/Pass/IRPrinting.cpp @@ -170,8 +170,7 @@ config->printAfterIfEnabled(pass, op, [&](raw_ostream &out) { out << formatv("// -----// IR Dump After {0} Failed", pass->getName()); - printIR(op, config->shouldPrintAtModuleScope(), out, - OpPrintingFlags().printGenericOpForm()); + printIR(op, config->shouldPrintAtModuleScope(), out, OpPrintingFlags()); out << "\n\n"; }); } diff --git a/mlir/test/Pass/invalid-ir-print-after-failure.mlir b/mlir/test/Pass/invalid-ir-print-after-failure.mlir new file mode 100644 --- /dev/null +++ b/mlir/test/Pass/invalid-ir-print-after-failure.mlir @@ -0,0 +1,12 @@ +// RUN: not mlir-opt %s -pass-pipeline='func.func(test-pass-create-invalid-ir{emit-invalid-ir=true signal-pass-failure=true})' -mlir-print-ir-after-failure 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID +// RUN: not mlir-opt %s -pass-pipeline='func.func(test-pass-create-invalid-ir{emit-invalid-ir=true signal-pass-failure=false})' -mlir-print-ir-after-failure 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID +// RUN: not mlir-opt %s -pass-pipeline='func.func(test-pass-create-invalid-ir{emit-invalid-ir=false signal-pass-failure=true})' -mlir-print-ir-after-failure 2>&1 | FileCheck %s --check-prefix=CHECK-VALID +// RUN: mlir-opt %s -pass-pipeline='func.func(test-pass-create-invalid-ir{emit-invalid-ir=false signal-pass-failure=false})' -mlir-print-ir-after-failure 2>&1 | FileCheck %s --check-prefix=CHECK-VALID + +// Test whether we print generically or not on pass failure, depending on whether there is invalid IR or not. + +// CHECK-VALID: func @TestCreateInvalidCallInPass +// CHECK-INVALID: "func.func" +func @TestCreateInvalidCallInPass() { + return +} diff --git a/mlir/test/Pass/ir-printing.mlir b/mlir/test/Pass/ir-printing.mlir --- a/mlir/test/Pass/ir-printing.mlir +++ b/mlir/test/Pass/ir-printing.mlir @@ -64,3 +64,4 @@ // AFTER_FAILURE-NOT: // -----// IR Dump After{{.*}}CSE // AFTER_FAILURE: // -----// IR Dump After{{.*}}TestFailurePass Failed //----- // +// AFTER_FAILURE: func @foo() diff --git a/mlir/test/lib/Pass/TestPassManager.cpp b/mlir/test/lib/Pass/TestPassManager.cpp --- a/mlir/test/lib/Pass/TestPassManager.cpp +++ b/mlir/test/lib/Pass/TestPassManager.cpp @@ -108,6 +108,37 @@ } }; +/// A test pass that creates an invalid operation in a function body. +struct TestInvalidIRPass + : public PassWrapper> { + MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestInvalidIRPass) + + TestInvalidIRPass() = default; + TestInvalidIRPass(const TestInvalidIRPass &other) {} + + StringRef getArgument() const final { return "test-pass-create-invalid-ir"; } + StringRef getDescription() const final { + return "Test pass that adds an invalid operation in a function body"; + } + void getDependentDialects(DialectRegistry ®istry) const final { + registry.insert(); + } + void runOnOperation() final { + if (signalFailure) + signalPassFailure(); + if (!emitInvalidIR) + return; + OpBuilder b(getOperation().getBody()); + OperationState state(b.getUnknownLoc(), "test.any_attr_of_i32_str"); + b.create(state); + } + Option signalFailure{*this, "signal-pass-failure", + llvm::cl::desc("Trigger a pass failure")}; + Option emitInvalidIR{*this, "emit-invalid-ir", llvm::cl::init(true), + llvm::cl::desc("Emit invalid IR")}; +}; + /// A test pass that always fails to enable testing the failure recovery /// mechanisms of the pass manager. struct TestInvalidParentPass @@ -179,6 +210,7 @@ PassRegistration(); PassRegistration(); + PassRegistration(); PassRegistration(); PassRegistration();