This is an archive of the discontinued LLVM Phabricator instance.

[LoopSimplify] Fix incorrect SCEV invalidation
ClosedPublic

Authored by mkazantsev on Apr 22 2018, 11:02 PM.

Details

Summary

In the function simplifyOneLoop we optimistically assume that changes in the
inner loop only affect this very loop and have no impact on its parents. In fact,
after rL329047 has been merged, we can now calculate exit counts for outer
loops which may depend on inner loops. Thus, we need to invalidate all parents
when we do something to a loop.

There is an evidence of incorrect behavior of simplifyOneLoop: when we insert
SE->verify() check in the end of this funciton, it fails on a bunch of existing
test, in particular:

LLVM :: Transforms/LoopUnroll/peel-loop-not-forced.ll
LLVM :: Transforms/LoopUnroll/peel-loop-pgo.ll
LLVM :: Transforms/LoopUnroll/peel-loop.ll
LLVM :: Transforms/LoopUnroll/peel-loop2.ll

Note that previously we have fixed issues of this variety, see rL328483.
This patch makes this function invalidate the outermost loop properly.

Diff Detail

Repository
rL LLVM

Event Timeline

mkazantsev created this revision.Apr 22 2018, 11:02 PM
mkazantsev added a reviewer: sanjoy.
chandlerc accepted this revision.Apr 22 2018, 11:22 PM

LGTM, good spot. I'll also definitely check if this fixes the mystery stage2 miscompile we've seen on PPC. It's a good fix either way though.

This revision is now accepted and ready to land.Apr 22 2018, 11:22 PM
This revision was automatically updated to reflect the committed changes.

ScalarEvolution::verify has false positives (i.e. it fails when it shouldn't) in some corner cases which is why it isn't run by default from verifyAnalysis[0]. So I don't think it is safe to add calls to ScalarEvolution::verify like this (this should really have been a comment on ScalarEvolution::verify -- I'll add that once these new call sites are removed).

[0] An an example, going by memory, it will complain if you change the trip count of a loop from undef to undef + 1. Of course, undef + 1 is undef, but SCEV does not know that -- it assumes undef is an unknown constant.

Thanks @sanjoy, it seems that I am seeing something of this sort right now on one of my Fuzzer tests. I will undo the verification.

FWIW, I'm also running into issues where this commit made compilation of one source file run forever. Previously, compilation of the file took 47 seconds, now it doesn't finish in 10+ minutes.

If you want to have a look at that case in case it's an issue different from the others, it's available at https://martin.st/temp/glew-preproc.c, try building with clang -target x86_64-w64-mingw32 -c -O2 glew-preproc.c.

Hi @mstorsjo, I will take a look. Can I ask you to file a bug on https://bugs.llvm.org/ so that we could keep records of our findings?

Basically this patch is a correctness fix, but maybe there are cases where we could be a bit less aggressive.

Hi @mstorsjo, I will take a look. Can I ask you to file a bug on https://bugs.llvm.org/ so that we could keep records of our findings?

Basically this patch is a correctness fix, but maybe there are cases where we could be a bit less aggressive.

FWIW, it seems like this issue has disappeared since - the latest trunk is good now again, but I haven't bisected again to find exactly which commit fixed it.