This is an archive of the discontinued LLVM Phabricator instance.

[GVNSink] Make GVNSink resistant against self referencing instructions (PR36954)
ClosedPublic

Authored by yurai007 on Nov 15 2021, 7:15 AM.

Details

Summary

Before this change GVNSink pass suffers from stack overflow while processing self referenced instruction in unreachable basic block.
According [1] and [2] it's reasonable to make pass resistant against self referencing instructions.
To fix issue we skip sinking analysis when we reach instruction coming from unreachable block.

[1] https://groups.google.com/g/llvm-dev/c/843Tig9IzwA
[2] https://lists.llvm.org/pipermail/llvm-dev/2015-February/082629.html

Diff Detail

Event Timeline

yurai007 created this revision.Nov 15 2021, 7:15 AM
yurai007 requested review of this revision.Nov 15 2021, 7:15 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 15 2021, 7:15 AM

Skip analysis for unreachable BBs?

nikic added inline comments.Nov 16 2021, 12:27 PM
llvm/lib/Transforms/Scalar/GVNSink.cpp
364

This checks for a directly self-referential instruction, but the references may also be cyclic across multiple instructions.

As @xbolva00 mentioned, it may be simpler/cleaner to skip unreachable blocks.

llvm/test/Transforms/GVNSink/sink-common-code.ll
775

Can this test be further reduced?

yurai007 added inline comments.Nov 17 2021, 2:18 AM
llvm/lib/Transforms/Scalar/GVNSink.cpp
364

Yes, and that's what I proposed as alternative solution: https://bugs.llvm.org/show_bug.cgi?id=36954#c9 It would save some work and resolve cycles problem. The only drawback I see now is need of giving GVNSink access to DT since we need isReachableFromEntry or analogous machinery for checking reachability. I started with first, simpler approach because it was preferred by @jeroen.dobbelaere, however checking cycles with this idea during lookupOrAdd run seem to be nontrivial. So yes, I can switch to second approach and check where it leads.

yurai007 updated this revision to Diff 387894.Nov 17 2021, 3:54 AM
yurai007 edited the summary of this revision. (Show Details)
yurai007 marked an inline comment as done.

Looks like problem still occurs: https://github.com/llvm/llvm-project/issues/36302 and https://godbolt.org/z/ofGW3zzaG . After rebasing I'm gonna move on with patch.

Herald added a project: Restricted Project. · View Herald TranscriptMay 2 2022, 1:46 AM
yurai007 updated this revision to Diff 426379.May 2 2022, 4:54 AM
yurai007 edited the summary of this revision. (Show Details)
yurai007 marked an inline comment as done.

Addressed all comments.

nikic added a comment.May 2 2022, 5:43 AM

We don't strictly need a dominator tree here, it's possible to collect unreachable blocks upfront. It seems a bit odd to require dominator tree just for this purpose.

We don't strictly need a dominator tree here, it's possible to collect unreachable blocks upfront. It seems a bit odd to require dominator tree just for this purpose.

Ok. I will get rid of it.

yurai007 updated this revision to Diff 426672.May 3 2022, 5:55 AM
yurai007 edited the summary of this revision. (Show Details)

Now basic blocks reachable from entry are collected up front only once before function sinking.
Another option would be doing it in flight but now we are processing instructions in reverse order starting from bottom block via ReversePostOrderTraversal.
I guess it would make collecting visited and reachable BBs from entry less straightforward than there is now.

nikic added inline comments.May 6 2022, 3:56 AM
llvm/lib/Transforms/Scalar/GVNSink.cpp
393

Is the optional here needed? Don't we expect this to always be set before it gets used?

582

Can't you just reuse RPOT here? That is, iterate it into a set? RPOT doesn't visit unreachable blocks, and it is cached, so reusing it is fine.

yurai007 added inline comments.May 6 2022, 9:23 AM
llvm/lib/Transforms/Scalar/GVNSink.cpp
582

Thanks for pointing this out. I had to have some kind of mental block to not see how RPOT could be reused in such obvious way.

yurai007 added inline comments.May 7 2022, 3:05 AM
llvm/lib/Transforms/Scalar/GVNSink.cpp
393

Technically it's possible to use ValueTable without ReachableBBs being set. But for now we always set it before sinking so yes - Optional can be simply removed.

yurai007 updated this revision to Diff 427838.May 7 2022, 3:14 AM
yurai007 marked 2 inline comments as done.
nikic accepted this revision.May 7 2022, 6:38 AM

LGTM, though it would be good to further reduce the test case if that's possible.

This revision is now accepted and ready to land.May 7 2022, 6:38 AM
yurai007 updated this revision to Diff 428091.May 9 2022, 8:09 AM

Reduce test case even further.

LGTM, though it would be good to further reduce the test case if that's possible.

Thanks a lot for review!

This revision was landed with ongoing or failed builds.May 10 2022, 7:07 AM
This revision was automatically updated to reflect the committed changes.