This is an archive of the discontinued LLVM Phabricator instance.

[Dominators] Simplify child lists and make them deterministic
ClosedPublic

Authored by bkramer on Jun 20 2018, 1:11 PM.

Details

Summary

This fixes an extremely subtle non-determinism that can only be
triggered by an unfortunate alignment of passes. In my case:

  • JumpThreading does large dominator tree updates
  • CorrelatedValuePropagation preserves domtree now
  • LICM codegen depends on the order of children on domtree nodes

The last part is non-deterministic if the update was stored in a set.
But it turns out that the set is completely unnecessary, updates are
deduplicated at an earlier stage so we can just use a vector, which is
both more efficient and doesn't destroy the input ordering.

I didn't manage to get the 240 MB IR file reduced enough, triggering
this bug requires a lot of jump threading, so landing this without a
test case.

Diff Detail

Repository
rL LLVM

Event Timeline

bkramer created this revision.Jun 20 2018, 1:11 PM

I always prefer deterministic execution (all other things being equal). Have you done any testing of performance impact to this change? The adding and erasing of Dominator elements may cost more with how the SmallVector type performs the operations.

Otherwise I think the patch looks good. However, @kuhar is the Dominator expert here and I'd recommend waiting for him to speak up before committing.

I didn't manage to get the 240 MB IR file reduced enough, triggering this bug requires a lot of jump threading, so landing this without a test case.

Did you try bugpoint? a 240MB IR fire is indeed huge but maybe letting it run over night can help reduce the problem space. Non-deterministic errors like these are very difficult to narrow down though.

include/llvm/Support/GenericDomTreeConstruction.h
86 ↗(On Diff #152141)

Why did you reduce the initialization size from 4 elements down to 1?

I always prefer deterministic execution (all other things being equal). Have you done any testing of performance impact to this change? The adding and erasing of Dominator elements may cost more with how the SmallVector type performs the operations.

Otherwise I think the patch looks good. However, @kuhar is the Dominator expert here and I'd recommend waiting for him to speak up before committing.

I didn't manage to get the 240 MB IR file reduced enough, triggering this bug requires a lot of jump threading, so landing this without a test case.

Did you try bugpoint? a 240MB IR fire is indeed huge but maybe letting it run over night can help reduce the problem space. Non-deterministic errors like these are very difficult to narrow down though.

I didn't have success bugpointing this. It compiles really slowly and you need a lot of compiles in an interestingness function for a determinism bug. The other problem is you need to be really unlucky to get all the transforms trigger in the right order, blowing up the amount of input needed.

include/llvm/Support/GenericDomTreeConstruction.h
86 ↗(On Diff #152141)

No good reason, I'll bump it back to 4.

kuhar added inline comments.
include/llvm/Support/GenericDomTreeConstruction.h
1221 ↗(On Diff #152141)

Won't this also introduce non-determinism in the case you described?

1255 ↗(On Diff #152141)

Related to above.

1272 ↗(On Diff #152141)

I think this deserves a comment -- it's only obvious that the successor/predecessor is at the end once you realize updates are performed in the same order as they happened to be legalized.

bkramer updated this revision to Diff 152159.Jun 20 2018, 2:06 PM

Address comments.

bkramer marked an inline comment as done.Jun 20 2018, 2:08 PM
bkramer added inline comments.
include/llvm/Support/GenericDomTreeConstruction.h
1221 ↗(On Diff #152141)

It would, but we restore a deterministic order below by sorting back to input order.

1255 ↗(On Diff #152141)

Right, this makes the order deterministic again.

1272 ↗(On Diff #152141)

Done.

kuhar accepted this revision.Jun 20 2018, 2:10 PM
This revision is now accepted and ready to land.Jun 20 2018, 2:10 PM
This revision was automatically updated to reflect the committed changes.