This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo] Invalidate debug info in ReassociatePass::RewriteExprTree
ClosedPublic

Authored by bjope on Apr 23 2018, 11:13 AM.

Details

Summary

When Reassociate is rewriting an expression tree it may
reuse old binary expression nodes, for new expressions.
Whenever an expression node is reused, but with a non-trivial
change in the result, we need to invalidate any debug info
that is associated with the node.

If for example rewriting

x = mul a, b
y = mul c, x

into

x = mul c, b
y = mul a, x

we still get the same result for 'y', but 'x' is a new expression.
All debug info referring to 'x' must be invalidated (marked as
optimized out) since we no longer calculate the expected value.

As a side-effect this patch avoid (at least some) problems where
reassociate could end up creating IR with debug-use before def.
Earlier the dbg.value nodes where left untouched in the IR, while
the reused binary nodes where sinked to just before the root node
of the rewritten expression tree. See PR27273 for more info about
such problems.

Diff Detail

Repository
rL LLVM

Event Timeline

bjope created this revision.Apr 23 2018, 11:13 AM
dexonsmith resigned from this revision.Apr 23 2018, 11:15 AM
aprantl added inline comments.Apr 23 2018, 11:23 AM
lib/Transforms/Scalar/Reassociate.cpp
785 ↗(On Diff #143603)

has -> have

786 ↗(On Diff #143603)

infor -> info

791 ↗(On Diff #143603)

I think it would be better use use and undef instead of a nullptr here. Otherwise the intrinsic may will be deleted and doesn't serve as an end point of the live range opened by the previous intrinsic describing the same variable any more.

bjope added inline comments.Apr 23 2018, 11:41 AM
lib/Transforms/Scalar/Reassociate.cpp
791 ↗(On Diff #143603)

Not sure if I understand what you mean by "use use and undef instead of nullptr".

I tried to find some place in the code where a dbg.value is invalidated (and not only erased) like this, to find out how to do it. But could not find any pattern to reuse. Do you know if we do this kind of invalidation somewhere already (maybe there is an existing helper similar to salvageDebugInfo that can be used)?

aprantl added inline comments.Apr 23 2018, 11:49 AM
lib/Transforms/Scalar/Reassociate.cpp
791 ↗(On Diff #143603)

Sorry this was supposed to say: use an %undef instead of a nullptr, i.e.:

DII->setOperand(UndefValue::get(...), MetadataAsValue::get(DII->getContext(), nullptr));

bjope added inline comments.Apr 23 2018, 12:08 PM
lib/Transforms/Scalar/Reassociate.cpp
791 ↗(On Diff #143603)

I thought the first was op-number, but maybe it is possible to do something like DII->setOperand(0, UndefValue::get(...)); ? But I think the operand also has to be metadata.

The resulting IR from my original proposal is basically

`call void @llvm.dbg.value(metadata !2, ...`

which is what Reassociate produce in other situations where it does rewrites without reusing existing instructions (when the original def is erased). Not sure exactly how the metadata is cleared in such situations (if it is for example is done as part of replaceAllUsesWith or eraseFromParent). I could not find anything explicit in Reassociate.cpp.

aprantl added inline comments.Apr 23 2018, 1:01 PM
lib/Transforms/Scalar/Reassociate.cpp
791 ↗(On Diff #143603)

Yes the first argument is the operand number, so it should be something like: DII->setOperand(0, MetadataAsValue::get(DII->getContext(), ValueAsMetadata::get(UndefValue::get(...))))

791 ↗(On Diff #143603)

see DIBuilder.cpp / getDbgIntrinsicValueImpl().

bjope updated this revision to Diff 143752.Apr 24 2018, 8:33 AM

Thanks Adrian! Updated according to your suggestion and this should be more correct.

bjope marked an inline comment as done.Apr 24 2018, 8:34 AM
aprantl accepted this revision.Apr 24 2018, 8:39 AM

Awesome!

This revision is now accepted and ready to land.Apr 24 2018, 8:39 AM
This revision was automatically updated to reflect the committed changes.