[Mlir-commits] [mlir] c21ee1a - Improve the verifier diagnostic on dominance error
Mehdi Amini
llvmlistbot at llvm.org
Wed Dec 16 14:05:57 PST 2020
Author: Mehdi Amini
Date: 2020-12-16T22:05:17Z
New Revision: c21ee1a9426710eba5923062efd0e0b0789edd47
URL: https://github.com/llvm/llvm-project/commit/c21ee1a9426710eba5923062efd0e0b0789edd47
DIFF: https://github.com/llvm/llvm-project/commit/c21ee1a9426710eba5923062efd0e0b0789edd47.diff
LOG: Improve the verifier diagnostic on dominance error
Address PR47937
Differential Revision: https://reviews.llvm.org/D93361
Added:
Modified:
mlir/lib/IR/Verifier.cpp
mlir/test/IR/invalid.mlir
Removed:
################################################################################
diff --git a/mlir/lib/IR/Verifier.cpp b/mlir/lib/IR/Verifier.cpp
index e214a654dbee..036919bd84b9 100644
--- a/mlir/lib/IR/Verifier.cpp
+++ b/mlir/lib/IR/Verifier.cpp
@@ -245,6 +245,56 @@ LogicalResult OperationVerifier::verifyOperation(Operation &op) {
return success();
}
+/// Attach a note to an in-flight diagnostic that provide more information about
+/// where an op operand is defined.
+static void attachNoteForOperandDefinition(InFlightDiagnostic &diag,
+ Operation &op, Value operand) {
+ if (auto *useOp = operand.getDefiningOp()) {
+ Diagnostic ¬e = diag.attachNote(useOp->getLoc());
+ note << "operand defined here";
+ Block *block1 = op.getBlock();
+ Block *block2 = useOp->getBlock();
+ Region *region1 = block1->getParent();
+ Region *region2 = block2->getParent();
+ if (block1 == block2)
+ note << " (op in the same block)";
+ else if (region1 == region2)
+ note << " (op in the same region)";
+ else if (region2->isProperAncestor(region1))
+ note << " (op in a parent region)";
+ else if (region1->isProperAncestor(region2))
+ note << " (op in a child region)";
+ else
+ note << " (op is neither in a parent nor in a child region)";
+ return;
+ }
+ // Block argument case.
+ Block *block1 = op.getBlock();
+ Block *block2 = operand.cast<BlockArgument>().getOwner();
+ Region *region1 = block1->getParent();
+ Region *region2 = block2->getParent();
+ Location loc = UnknownLoc::get(op.getContext());
+ if (block2->getParentOp())
+ loc = block2->getParentOp()->getLoc();
+ Diagnostic ¬e = diag.attachNote(loc);
+ if (!region2) {
+ note << " (block without parent)";
+ return;
+ }
+ if (block1 == block2)
+ llvm::report_fatal_error("Internal error in dominance verification");
+ int index = std::distance(region2->begin(), block2->getIterator());
+ note << "operand defined as a block argument (block #" << index;
+ if (region1 == region2)
+ note << " in the same region)";
+ else if (region2->isProperAncestor(region1))
+ note << " in a parent region)";
+ else if (region1->isProperAncestor(region2))
+ note << " in a child region)";
+ else
+ note << " neither in a parent nor in a child region)";
+}
+
LogicalResult OperationVerifier::verifyDominance(Region ®ion) {
// Verify the dominance of each of the held operations.
for (Block &block : region) {
@@ -254,14 +304,14 @@ LogicalResult OperationVerifier::verifyDominance(Region ®ion) {
// Check that operands properly dominate this use.
for (unsigned operandNo = 0, e = op.getNumOperands(); operandNo != e;
++operandNo) {
- auto operand = op.getOperand(operandNo);
+ Value operand = op.getOperand(operandNo);
if (domInfo->properlyDominates(operand, &op))
continue;
- auto diag = op.emitError("operand #")
- << operandNo << " does not dominate this use";
- if (auto *useOp = operand.getDefiningOp())
- diag.attachNote(useOp->getLoc()) << "operand defined here";
+ InFlightDiagnostic diag = op.emitError("operand #")
+ << operandNo
+ << " does not dominate this use";
+ attachNoteForOperandDefinition(diag, op, operand);
return failure();
}
// Recursively verify dominance within each operation in the
diff --git a/mlir/test/IR/invalid.mlir b/mlir/test/IR/invalid.mlir
index 86245ad25c3b..4e6c950d637a 100644
--- a/mlir/test/IR/invalid.mlir
+++ b/mlir/test/IR/invalid.mlir
@@ -464,7 +464,49 @@ func @dominance_failure() {
"foo"(%x) : (i32) -> () // expected-error {{operand #0 does not dominate this use}}
br ^bb1
^bb1:
- %x = "bar"() : () -> i32 // expected-note {{operand defined here}}
+ %x = "bar"() : () -> i32 // expected-note {{operand defined here (op in the same region)}}
+ return
+}
+
+// -----
+
+func @dominance_failure() {
+^bb0:
+ "foo"(%x) : (i32) -> () // expected-error {{operand #0 does not dominate this use}}
+ %x = "bar"() : () -> i32 // expected-note {{operand defined here (op in the same block)}}
+ br ^bb1
+^bb1:
+ return
+}
+
+// -----
+
+func @dominance_failure() {
+ "foo"() ({
+ "foo"(%x) : (i32) -> () // expected-error {{operand #0 does not dominate this use}}
+ }) : () -> ()
+ %x = "bar"() : () -> i32 // expected-note {{operand defined here (op in a parent region)}}
+ return
+}
+
+// -----
+
+func @dominance_failure() { // expected-note {{operand defined as a block argument (block #1 in the same region)}}
+^bb0:
+ br ^bb1(%x : i32) // expected-error {{operand #0 does not dominate this use}}
+^bb1(%x : i32):
+ return
+}
+
+// -----
+
+func @dominance_failure() { // expected-note {{operand defined as a block argument (block #1 in a parent region)}}
+^bb0:
+ %f = "foo"() ({
+ "foo"(%x) : (i32) -> () // expected-error {{operand #0 does not dominate this use}}
+ }) : () -> (i32)
+ br ^bb1(%f : i32)
+^bb1(%x : i32):
return
}
More information about the Mlir-commits
mailing list