This is an archive of the discontinued LLVM Phabricator instance.

[LoopSimplify] Preserve LCSSA when merging exit blocks.
ClosedPublic

Authored by mzolotukhin on Jun 7 2016, 5:58 PM.

Details

Summary

This fixes PR26682. Also add LCSSA as a preserved pass to LoopSimplify,
that looks correct to me and allows to write a test for the issue.

Diff Detail

Repository
rL LLVM

Event Timeline

mzolotukhin updated this revision to Diff 59981.Jun 7 2016, 5:58 PM
mzolotukhin retitled this revision from to [LoopSimplify] Preserve LCSSA when merging exit blocks..
mzolotukhin updated this object.
mzolotukhin added reviewers: chandlerc, sanjoy, bogner.
mzolotukhin added a subscriber: llvm-commits.
sanjoy requested changes to this revision.Jun 7 2016, 6:53 PM
sanjoy edited edge metadata.
sanjoy added inline comments.
lib/Transforms/Utils/LoopSimplify.cpp
753 ↗(On Diff #59981)

We should definitely add asserts verifying this. I'd suggest something like

LoopSimplify::runOnFunction() {
#ifndef NDEBUG
  DenseSet<Loop *> InLCSSA;
  // put loops that are in LCSSA in InLCSSA
#endif

  .. do whatever it is that LoopSimplify does ..

#ifndef NDEBUG
  // assert every Loop in InLCSSA is in LCSSA
#endif
}

(i.e. we should also catch cases where simplifying a loop breaks LCSSA in another loop).

786 ↗(On Diff #59981)

Can this be folded to true? (I'm not asking you to do that in this change itself.)

This revision now requires changes to proceed.Jun 7 2016, 6:53 PM
mzolotukhin added inline comments.Jun 7 2016, 7:01 PM
lib/Transforms/Utils/LoopSimplify.cpp
753 ↗(On Diff #59981)

Good point. I'll add some verification.

786 ↗(On Diff #59981)

Theoretically, there might be users that don't want LCSSA to be preserved. They don't have LCSSA prior loop-simplify, so PreserveLCSSA is false for them. But I'm not sure if such users exist in real world, and I'd be glad to replace it with plain true and always preserve LCSSA here (and eventually in all loop passes).

sanjoy added inline comments.Jun 7 2016, 7:11 PM
lib/Transforms/Utils/LoopSimplify.cpp
786 ↗(On Diff #59981)

Yes, I'm more coming to the conclusion that this form of complexity
(having a prior pass affect behavior in a way that isn't obvious in
the IR itself) is probably not worth it unless it is actually paying off in
compile time / code quality.

mzolotukhin updated this revision to Diff 59994.Jun 7 2016, 9:30 PM
mzolotukhin edited edge metadata.
  • Add verification that LCSSA is not broken (requires D21118).
mzolotukhin edited edge metadata.
  • Use existing routine, don't reinvent a wheel.
sanjoy accepted this revision.Jun 8 2016, 3:57 PM
sanjoy edited edge metadata.
sanjoy added inline comments.
lib/Transforms/Utils/LoopSimplify.cpp
795 ↗(On Diff #60000)

The indent looks weird -- did you clang-format?

Note: since you're inside an NDEBUG it is fine to pull out the computation to outside the assert.

808 ↗(On Diff #60000)

Ditto.

This revision is now accepted and ready to land.Jun 8 2016, 3:57 PM
This revision was automatically updated to reflect the committed changes.
chandlerc edited edge metadata.Jun 8 2016, 6:01 PM

Minor post-commit coments.

I do think we should just always preserve LCSSA. I can't come up with any good reason for not preserving it, and it gives us one fewer code path to test.

llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp
791–793

Hoist the assert into the loop? As is, when the assert fires, you have to go step through a bunch ef iterations of stuff to find the loop in question.

803–805

Same comment as above.

Minor post-commit coments.

I do think we should just always preserve LCSSA. I can't come up with any good reason for not preserving it, and it gives us one fewer code path to test.