This is an archive of the discontinued LLVM Phabricator instance.

WIP: [Verifier] Flag dbg.declares which specify different addresses for the same fragment
Needs ReviewPublic

Authored by vsk on Jul 29 2020, 2:49 PM.

Details

Summary

When verifying a basic block, keep track of the mapping between
!DILocalVariable fragments and addresses (typically stack slots). This
can help identify variables that are accidentally described as being in
two different stack slots.

Known check-llvm failures:

LLVM :: Transforms/Coroutines/coro-debug-frame-variable.ll
LLVM :: Transforms/LoopVectorize/discriminator.ll

Diff Detail

Event Timeline

vsk created this revision.Jul 29 2020, 2:49 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 29 2020, 2:49 PM
vsk requested review of this revision.Jul 29 2020, 2:49 PM
vsk updated this revision to Diff 281757.Jul 29 2020, 3:56 PM

Ignore inlined entities. It's not unexpected for a function that's inlined multiple times to introduce dbg.declares for the same inlined entity.

vsk added a comment.Jul 29 2020, 3:58 PM

@modocache Do you know anyone who could take a look at coro-debug-frame-variable.ll? This is what I'm seeing:

dbg.declares specify different addresses for the same fragment
  call void @llvm.dbg.declare(metadata i32* %i.reload.addr, metadata !14, metadata !DIExpression()), !dbg !16
  call void @llvm.dbg.declare(metadata i32* %i.reload.addr12, metadata !14, metadata !DIExpression()), !dbg !16
label %init.ready
void (%f.Frame*)* @f.resume
!14 = !DILocalVariable(name: "i", scope: !15, file: !1, line: 24, type: !10)
LLVM ERROR: Broken function
vsk edited the summary of this revision. (Show Details)Jul 29 2020, 3:58 PM

Hi @vsk, just a inline question from me. And in addition, I noticed that SourceLevelDebugging specifically states "there can only be one call to llvm.dbg.declare for a given concrete local variable". I wonder if we should update this to say something like "there can only be one call to llvm.dbg.declare for a given fragment of a local variable"?

Please let me know if these comments should wait til the patch is no longer WIP instead.

llvm/lib/IR/Verifier.cpp
270

Could we ever see two dbg.declares for the same variable fragment with different expressions?

dbg.declare(%x, metadata !1, metadata !DIExpression())
dbg.declare(%x, metadata !1, metadata !DIExpression(DW_OP_plus, DW_OP_constu, 1))

This is contrived and I don't have a reproducer, so I'm not sure if it is something worth considering. I was just reminded of PR41992 and PR43957 when I saw std::pair<DILocalVariable *, DIExpression *> being used to identify fragments of a variable.

vsk added a reviewer: davide.Jul 30 2020, 10:46 AM

The SourceLevelDebugging documentation update makes sense to me. And this check should probably make use of the DebugVariable wrapper.

Without a testcase it's not immediately obvious what this is catching. It's legal for two *different* fragments of the same variable to point to two separate allocas, I think that's the output of SROA. It's not legal for any one variable (fragment) to be described by a dbg.declare and any other instrinsic. A dbg.declare is supposed to be the only, authoritative location of a variable. So maybe the test could be even stricter.