Index: mlir/lib/IR/AsmPrinter.cpp =================================================================== --- mlir/lib/IR/AsmPrinter.cpp +++ mlir/lib/IR/AsmPrinter.cpp @@ -25,6 +25,7 @@ #include "mlir/IR/OpImplementation.h" #include "mlir/IR/Operation.h" #include "mlir/IR/SubElementInterfaces.h" +#include "mlir/IR/Verifier.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/MapVector.h" @@ -2906,7 +2907,18 @@ } void Operation::dump() { - print(llvm::errs(), OpPrintingFlags().useLocalScope()); + OpPrintingFlags flags; + flags.useLocalScope(); + // First verify the operation. If the operation fails to verify then custom + // print functions may fail and we have to use generic operation printing. + { + // Ignore errors emitted by the verifier. + ScopedDiagnosticHandler diagHandler(getContext(), + [](Diagnostic &) { return success(); }); + if (failed(verify(this))) + flags.printGenericOpForm(); + } + print(llvm::errs(), flags); llvm::errs() << "\n"; } Index: mlir/lib/IR/Operation.cpp =================================================================== --- mlir/lib/IR/Operation.cpp +++ mlir/lib/IR/Operation.cpp @@ -1097,6 +1097,8 @@ // Check that any value that is used by an operation is defined in the // same region as either an operation result. auto *operandRegion = operand.getParentRegion(); + if (!operandRegion) + return op.emitError("operation's operand is unlinked"); if (!region.isAncestor(operandRegion)) { return op.emitOpError("using value defined outside the region") .attachNote(isolatedOp->getLoc()) Index: mlir/test/Conversion/AffineToStandard/lower-affine.mlir =================================================================== --- mlir/test/Conversion/AffineToStandard/lower-affine.mlir +++ mlir/test/Conversion/AffineToStandard/lower-affine.mlir @@ -1,4 +1,5 @@ -// RUN: mlir-opt -lower-affine %s | FileCheck %s +// `-debug` is used here to check that we don't crash when it's specified. +// RUN: mlir-opt -lower-affine -debug %s | FileCheck %s // CHECK-LABEL: func @empty() { func @empty() { Index: mlir/test/Conversion/SCFToStandard/convert-to-cfg.mlir =================================================================== --- mlir/test/Conversion/SCFToStandard/convert-to-cfg.mlir +++ mlir/test/Conversion/SCFToStandard/convert-to-cfg.mlir @@ -1,4 +1,5 @@ -// RUN: mlir-opt -allow-unregistered-dialect -convert-scf-to-std %s | FileCheck %s +// `-debug` is used here to check that we don't crash when it's specified. +// RUN: mlir-opt -allow-unregistered-dialect -convert-scf-to-std -debug %s | FileCheck %s // CHECK-LABEL: func @simple_std_for_loop(%{{.*}}: index, %{{.*}}: index, %{{.*}}: index) { // CHECK-NEXT: br ^bb1(%{{.*}} : index)