Step 03 · The Verifier

llvm::verifyModule(module, &os) returns true on failure and writes a description into os. We call it as the last step of build and refuse to return a module that does not verify.

What the verifier catches

  • Blocks without a terminator (we used to emit a defensive CreateUnreachable for safety).
  • Branch targets in a different function.
  • Type mismatches (add i64, i32).
  • Values used outside the dominance tree of their definition.
  • Improper SSA — multiple definitions of the same %x.

Why it matters

A module that fails verification will often segfault lli or the backend instead of producing a clean diagnostic. Verifying up front turns those into a single string we can surface to the user.

Test hook

auto cg = compile("print 1;");
CHECK(cg.ok);                       // verifier passed
CHECK(cg.mod != nullptr);           // module survived
CHECK_CONTAINS(cg.toText(), "ModuleID");

On failure, CodegenResult::error carries the verifier's report verbatim, which is invaluable when developing new lowering rules.