Verify that the first block of a cfgfunc does not have predecessors.
authorAlex Zinenko <zinenko@google.com>
Tue, 23 Oct 2018 15:12:59 +0000 (08:12 -0700)
committerjpienaar <jpienaar@google.com>
Fri, 29 Mar 2019 20:36:01 +0000 (13:36 -0700)
This was left as a TODO in the code.  Note that the spec does not explicitly
prohibit the first basic block from having a predecessor, and may be worth
updating.

The error is reported at the location of the cfgfunc to which the basic block
belongs since the location information of the block label is not propagated
beyond the IR parser.  Arguably, pointing to a function that starts with an
ill-formed block is better than pointing to the first operation in that block
as it makes easier to follow the code down until the first block label.

PiperOrigin-RevId: 218343654

mlir/lib/Analysis/Verifier.cpp
mlir/test/IR/invalid.mlir

index 399de956d353c4bb2690e32823129f9be0280126..f4223863488b606eb0475b044d60ca7d6f48df34 100644 (file)
@@ -183,14 +183,18 @@ bool CFGFuncVerifier::verify() {
 
   // TODO: Lots to be done here, including verifying dominance information when
   // we have uses and defs.
-  // TODO: Verify the first block has no predecessors.
 
   if (fn.empty())
     return failure("cfgfunc must have at least one basic block", fn);
 
+  // Verify the first block has no predecessors.
+  auto *firstBB = &fn.front();
+  if (!firstBB->hasNoPredecessors()) {
+    return failure("first block of cfgfunc must not have predecessors", fn);
+  }
+
   // Verify that the argument list of the function and the arg list of the first
   // block line up.
-  auto *firstBB = &fn.front();
   auto fnInputTypes = fn.getType()->getInputs();
   if (fnInputTypes.size() != firstBB->getNumArguments())
     return failure("first block of cfgfunc must have " +
index b7f30f1885ca2f8af28819488a296d37518b2347..11aa1b1b3527c713bbe70dae3b5237edc35974d3 100644 (file)
@@ -110,6 +110,16 @@ bb42:
 
 // -----
 
+cfgfunc @block_first_has_predecessor() {
+// expected-error@-1 {{first block of cfgfunc must not have predecessors}}
+bb42:
+  br bb43
+bb43:
+  br bb42
+}
+
+// -----
+
 cfgfunc @illegalattrs() -> ()
   attributes { key } { // expected-error {{expected ':' in attribute list}}
 bb42: