Use LLVM verifier in lowering (#5733)

Suggested by zygoloid while looking at #5678 

```
CHECK failure at toolchain/lower/context.cpp:62: !llvm::verifyModule(*llvm_module_, &errs): Verifier errors: Instruction does not dominate all uses!
  %.loc17_46.1.temp = alloca { i1, i32, i32 }, align 8, !dbg !13
  %tuple.elem0.loc17_46.2.tuple.elem = getelementptr inbounds nuw { i1, i32, i32 }, ptr %.loc17_46.1.temp, i32 0, i32 0, !dbg !13
Instruction does not dominate all uses!
  %.loc17_46.1.temp = alloca { i1, i32, i32 }, align 8, !dbg !13
  %tuple.elem1.loc17_46.2.tuple.elem = getelementptr inbounds nuw { i1, i32, i32 }, ptr %.loc17_46.1.temp, i32 0, i32 1, !dbg !13
Instruction does not dominate all uses!
  %.loc17_46.1.temp = alloca { i1, i32, i32 }, align 8, !dbg !13
  %tuple.elem2.loc17_46.2.tuple.elem = getelementptr inbounds nuw { i1, i32, i32 }, ptr %.loc17_46.1.temp, i32 0, i32 2, !dbg !13
```

Adds a `--llvm-verifier` flag to be able to turn this off easily,
particularly for debugging the LLVM IR.

The call workaround is due to a verifier requirement `inlinable function
call in a function with debug info must have a !dbg location`. It
specifically comes up for the `++x` case, with `%1 = call i32
@"_CConvert.8b3d5d6a6c17be04:ImplicitAs.Core.b88d1103f417c6d4"(i32
%other)`. I think #5397 is in the direction of a fix for that, but #5397
was set aside because it puts the debug info in too many places.
Instead, address this by adding a stub location for calls that don't
have a good location. I'm deliberately putting this next to the TODO so
that it's easier to understand the association.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
This commit is contained in:
Jon Ross-Perkins
2025-06-26 21:34:09 +00:00
committed by GitHub
co-authored by Dana Jansens
parent fcf445b517
commit c3b0c2e425
9 changed files with 123 additions and 9 deletions
+15 -2
View File
@@ -294,6 +294,17 @@ Whether to emit DWARF debug information.
arg_b.Default(true);
arg_b.Set(&include_debug_info);
});
b.AddFlag(
{
.name = "verify-llvm-ir",
.help = R"""(
Whether to run the LLVM verifier on modules.
)""",
},
[&](auto& arg_b) {
arg_b.Default(true);
arg_b.Set(&run_llvm_verifier);
});
}
static constexpr CommandLine::CommandInfo SubcommandInfo = {
@@ -712,8 +723,10 @@ auto CompilationUnit::RunLower() -> void {
llvm::ArrayRef<Parse::GetTreeAndSubtreesFn> subtrees =
cache_->tree_and_subtrees_getters();
module_ = Lower::LowerToLLVM(
*llvm_context_, driver_env_->fs, options_->include_debug_info, subtrees,
input_filename_, *sem_ir_, &inst_namer, vlog_stream_);
*llvm_context_, driver_env_->fs,
options_->run_llvm_verifier ? driver_env_->error_stream : nullptr,
options_->include_debug_info, subtrees, input_filename_, *sem_ir_,
&inst_namer, vlog_stream_);
});
if (vlog_stream_) {
CARBON_VLOG("*** llvm::Module ***\n");