This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo][Dexter] Incorrect DBG_VALUE after MCP dead copy instruction removal.
ClosedPublic

Authored by CarlosAlbertoEnciso on Sep 27 2018, 8:01 AM.

Details

Summary

For the below test:

int main() {
  volatile int foo = 4;
  int read1 = foo;
  int read2 = foo;

  switch ((read1 == 4) ? 3 : 1) {
  case 1:
    read1 *= read2;
    break;
  case 3:
    read1 /= read2;
    break;
  }

  return read1;
}

Debug location information for 'read1' is wrong with -O2.

When in the debugger, on the line "return read1;", the value of "read1"
is reported as '4', where it should be '1', as described by:

PR38773

Diff Detail

Repository
rL LLVM

Event Timeline

Thanks, this looks mostly good!

include/llvm/CodeGen/MachineInstr.h
1547 ↗(On Diff #167325)

How about:

/// Find all DBG_VALUEs immediately following this instruction that point to a register def in this instruction and point them to \p Reg instead.

Looking at the implementation of collectDebugValues() I'm somewhat puzzled how it works. Perhaps I'm misunderstanding what it is supposed to do, please let me know. It's scanning for DBG_VALUEs that point to Op0 of the instruction. Is Op0 always going to be a def? Or should it be improved?

1548 ↗(On Diff #167325)

Could you give this a more descriptive name?

test/CodeGen/MIR/X86/pr38773.mir
153 ↗(On Diff #167325)

This line is an exact duplicate of the previous line. While this won't break anything, it's inefficient.
Looking at the definition of collectDebugValues it doesn't look like this patch is responsible, but it would still be good to fix. Whoever is inserting these DBG_VALUEs in the first place should be doing a check for duplicates? Doing a linear search of any DBG_VALUEs immediately following the insertion point (like collectDebugValues does) should be sufficient.

It would be good to change the title to reflect what is done in MCP (at least before submitting this).

Can the test be reduced to only contain the bb.2.sw.bb1 block?

test/CodeGen/MIR/X86/pr38773.mir
46 ↗(On Diff #167325)

Can the lifetime markers be removed?

50 ↗(On Diff #167325)

Should unrelated debug values for other variables be removed to minimize the test?

CarlosAlbertoEnciso marked 4 inline comments as done.Sep 28 2018, 3:42 AM

It would be good to change the title to reflect what is done in MCP (at least before submitting this).

We are using the tags: [DebugInfo][Dexter] and identify the issues detected by the DexTer tool.

For the title, may be something like:

Incorrect DBG_VALUE after MCP dead copy instruction removal.

Can the test be reduced to only contain the bb.2.sw.bb1 block?

Yes. I have reduced the test case, just to contain bb.2.sw.bb1 block.

include/llvm/CodeGen/MachineInstr.h
1547 ↗(On Diff #167325)

/// Find all DBG_VALUEs immediately following this instruction that point to a register def in this instruction and point them to \p Reg instead.

That is a better description.

test/CodeGen/MIR/X86/pr38773.mir
46 ↗(On Diff #167325)

I have removed all the not required markers.

50 ↗(On Diff #167325)

I have removed all the not required debug values. I have left only the ones for 'read1'.

153 ↗(On Diff #167325)

The duplicated line has been removed. Modified the IR just to include only a single DBG_VALUE.

153 ↗(On Diff #167325)

Looking at the definition of collectDebugValues it doesn't look like this patch is responsible, but it would still be good to fix.

If you are OK, I can leave that issue to be fix in another patch.

Whoever is inserting these DBG_VALUEs in the first place should be doing a check for duplicates? Doing a linear search of any DBG_VALUEs immediately following the insertion point (like collectDebugValues does) should be sufficient.

That is a very good point.

During the review D50887, there were some discussions about the collectDebugValues implementation. The idea was to use the list of USEs instead of linearly scanning.

Another interesting modification, was the one you raised on PR38763#c8 to extended llvm.dbg.value to take more than one LLVM SSA Value.

I would suggest if we can create specific bugzillas to address the following issues:

  • collectDebugValues implementation (to use the list of USEs).
  • Check for duplicates when inserting DBG_VALUEs.
  • Extended llvm.dbg.value to take more than one LLVM SSA Value.

I am happy to create those bugzillas, so we can have something in concrete to work on.

CarlosAlbertoEnciso marked 10 inline comments as done.Sep 28 2018, 8:28 AM
CarlosAlbertoEnciso added inline comments.
include/llvm/CodeGen/MachineInstr.h
1547 ↗(On Diff #167325)

Looking at the implementation of collectDebugValues() I'm somewhat puzzled how it works. Perhaps I'm misunderstanding what it is supposed to do, please let me know. It's scanning for DBG_VALUEs that point to Op0 of the instruction.

It scans all the MI that follows the given instruction (they are referenced by 'DI').

if (!DI->isDebugValue())
  return;

Returns when the scanned DI is not a DBG_VALUE

if (DI->getOperand(0).isReg() &&
    DI->getOperand(0).getReg() == MI.getOperand(0).getReg())
  DbgValues.push_back(&*DI);

Records the scanned DI (which already we know is DBG_VALUE), only if:

  • The DI machine operand type is a 'register operand' and
  • The DI register number is the same as the MI register number.

Is Op0 always going to be a def?

As far as I understand it, only for the case of DBG_VALUE, the Op0 should always be a def.

Or should it be improved?

Only the first operand in the MI (getOperand(0)) is considered, which I can see as a possible limitation for cases where a different operand register needs to be modified.

And if the assumption that Op0 is not always a def, then extra checks should be added.

1548 ↗(On Diff #167325)

What about: changeDebugValuesDefReg

meaning

Changes the register definition for the DBG_VALUEs to the given 'register'.

CarlosAlbertoEnciso retitled this revision from [DebugInfo][Dexter] Divide-before-return displays wrong value in debugger to [DebugInfo][Dexter] Incorrect DBG_VALUE after MCP dead copy instruction removal..Sep 28 2018, 8:30 AM
CarlosAlbertoEnciso marked an inline comment as done.

Address issues raised by the reviewers.

  • Title for the review itself
  • Reduce test case
  • Better description and name for the new function.
CarlosAlbertoEnciso marked 2 inline comments as done.Sep 28 2018, 8:35 AM
aprantl accepted this revision.Sep 28 2018, 8:47 AM
aprantl added inline comments.
include/llvm/CodeGen/MachineInstr.h
1547 ↗(On Diff #167325)

Oh I see. MI is always a DBG_VALUE. Then looking at Op0 makes perfect sense. Thanks for clearing that up!

test/CodeGen/MIR/X86/pr38773.mir
153 ↗(On Diff #167325)

I am happy to create those bugzillas, so we can have something in concrete to work on.

Please do. Working in small increments makes it much easier to reason over patches and also makes reviews much faster!

This revision is now accepted and ready to land.Sep 28 2018, 8:47 AM
vsk accepted this revision.Sep 28 2018, 9:06 AM

+ 1, lgtm as well, thanks!

This revision was automatically updated to reflect the committed changes.

Thanks very much to all the reviewers for your valuable comments and suggestions.