This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Preserve debug value when simplifying cast-of-select
ClosedPublic

Authored by vsk on Jul 12 2018, 3:10 PM.

Details

Summary

InstCombine has a cast transform that matches a cast-of-select:

Orig = cast (Src = select Cond TV FV)

And tries to replace it with a select which has the cast folded in:

NewSel = select Cond (cast TV) (cast FV)

The combiner does RAUW(Orig, NewSel), so any debug values for Orig would
survive the transform. But debug values for Src would be lost.

This patch teaches InstCombine to replace all debug uses of Src with
NewSel (taking care of doing any necessary DIExpression rewriting).

Diff Detail

Repository
rL LLVM

Event Timeline

vsk created this revision.Jul 12 2018, 3:10 PM

Judging by the pattern, i would almost guess every single transform in instcombine will need such a fix?
Can this be generalized somehow, fixing the outer place which actually applies replacements?

vsk added a comment.EditedJul 13 2018, 3:08 PM

Judging by the pattern, i would almost guess every single transform in instcombine will need such a fix?
Can this be generalized somehow, fixing the outer place which actually applies replacements?

There are general debug info salvage calls in InstCombine already (added in r297994 and r318320). These are pretty effective. I've measured that they ~halve the number of debug values dropped in InstCombine during an -O2 build of sqlite3.

However, there is a long tail of bugs that don't have a neat general solution (well, at least not one I can see :).

Fundamentally, after a combine is successfully applied the use counts of some instructions may drop to zero. The question is: what should the debug users of these instructions point to? It wouldn't be conservatively correct to simply point them to the newly-created value. Consider the following contrived combine:

%A = add %x, %x
dbg.value(%A, "my_var_1")

%B = mul %A, 2
dbg.value(%B, "my_var_2")

=>

%B = mul %x, 4
dbg.value(?, "my_var_1")
dbg.value(%B, "my_var_2")

We don't want to emit dbg.value(%B, "my_var_1"), because that would associate the wrong value with the variable "my_var_1". The correct thing to do would be to emit something like dbg.value(%B, "my_var_1", {DW_OP_lit2, DW_OP_div, DW_OP_stack_value}).

While I think there's more yet to be done with applying salvageDebugInfo, I do think we'll need targeted solutions like this one in the long haul.

Edit: Correct the example.

lebedev.ri accepted this revision.Jul 14 2018, 6:23 AM

I would prefer some more general solution, but this does not look awful, too.
You probably want to wait a bit in case others want to comment.

This revision is now accepted and ready to land.Jul 14 2018, 6:23 AM
This revision was automatically updated to reflect the committed changes.