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
+6
View File
@@ -255,6 +255,12 @@ auto FunctionContext::GetDebugLoc(SemIR::InstId inst_id) -> llvm::DebugLoc {
// duplicated from the original signature.
//
// TODO: Handle this case better.
if (sem_ir().insts().Is<SemIR::Call>(inst_id)) {
// Return a stub location for calls, because they may be inlineable (an
// LLVM verifier issue).
return llvm::DILocation::get(builder_.getContext(), -1, -1,
di_subprogram_);
}
return llvm::DebugLoc();
}
return llvm::DILocation::get(builder_.getContext(), loc.line_number,