Print custom assembly on pass failure by default

The printer is now resilient to invalid IR and will already automatically
fallback to the generic form on invalid IR. Using the generic printer on
pass failure was a conservative option before the printer was made
failsafe.

Reviewed By: lattner, rriddle, jpienaar, bondhugula

Differential Revision: https://reviews.llvm.org/D123915
This commit is contained in:
Mehdi Amini 2022-04-19 17:26:33 +00:00
parent 1aa3a54921
commit 83892d76f4
4 changed files with 46 additions and 2 deletions

View File

@ -170,8 +170,7 @@ void IRPrinterInstrumentation::runAfterPassFailed(Pass *pass, Operation *op) {
config->printAfterIfEnabled(pass, op, [&](raw_ostream &out) { config->printAfterIfEnabled(pass, op, [&](raw_ostream &out) {
out << formatv("// -----// IR Dump After {0} Failed", pass->getName()); out << formatv("// -----// IR Dump After {0} Failed", pass->getName());
printIR(op, config->shouldPrintAtModuleScope(), out, printIR(op, config->shouldPrintAtModuleScope(), out, OpPrintingFlags());
OpPrintingFlags().printGenericOpForm());
out << "\n\n"; out << "\n\n";
}); });
} }

View File

@ -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
}

View File

@ -64,3 +64,4 @@ func @bar() {
// AFTER_FAILURE-NOT: // -----// IR Dump After{{.*}}CSE // AFTER_FAILURE-NOT: // -----// IR Dump After{{.*}}CSE
// AFTER_FAILURE: // -----// IR Dump After{{.*}}TestFailurePass Failed //----- // // AFTER_FAILURE: // -----// IR Dump After{{.*}}TestFailurePass Failed //----- //
// AFTER_FAILURE: func @foo()

View File

@ -108,6 +108,37 @@ struct TestFailurePass : public PassWrapper<TestFailurePass, OperationPass<>> {
} }
}; };
/// A test pass that creates an invalid operation in a function body.
struct TestInvalidIRPass
: public PassWrapper<TestInvalidIRPass,
InterfacePass<FunctionOpInterface>> {
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 &registry) const final {
registry.insert<test::TestDialect>();
}
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<bool> signalFailure{*this, "signal-pass-failure",
llvm::cl::desc("Trigger a pass failure")};
Option<bool> 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 /// A test pass that always fails to enable testing the failure recovery
/// mechanisms of the pass manager. /// mechanisms of the pass manager.
struct TestInvalidParentPass struct TestInvalidParentPass
@ -179,6 +210,7 @@ void registerPassManagerTestPass() {
PassRegistration<TestCrashRecoveryPass>(); PassRegistration<TestCrashRecoveryPass>();
PassRegistration<TestFailurePass>(); PassRegistration<TestFailurePass>();
PassRegistration<TestInvalidIRPass>();
PassRegistration<TestInvalidParentPass>(); PassRegistration<TestInvalidParentPass>();
PassRegistration<TestStatisticPass>(); PassRegistration<TestStatisticPass>();