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";
});
}
--- /dev/null
+// 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
+}
}
};
+/// 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 ®istry) 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
/// mechanisms of the pass manager.
struct TestInvalidParentPass
PassRegistration<TestCrashRecoveryPass>();
PassRegistration<TestFailurePass>();
+ PassRegistration<TestInvalidIRPass>();
PassRegistration<TestInvalidParentPass>();
PassRegistration<TestStatisticPass>();