This patch incorporates also the one from https://reviews.llvm.org/D35478 in order to make it work well for SCEVDivision, when having SExt expressions. Before the patch, SCEVDivision::divide() was not working due to casts (SExt, etc). This was manifesting for example when used in the delinearization algorithm of Polly, implemented in ScopDetection.cpp (note that ScalarEvolution.cpp seems to have a delinearize() method also which is an appendix), which needs to perform SCEV division. Delinearization does (see paper Grosser et al, "On recovering Multi-dimensional Arrays in Polly", IMPACT 2015, Section 4 - http://impact.gforge.inria.fr/impact2015/papers/impact2015-grosser.pdf ): - sum of product expansion - after a simple removal process, products are sorted by the number of factors - check that the smaller terms in the sorted array divide the larger ones - symbolically divide the original offset expression by the size of the individual array dimensions starting from the innermost dimension . Note that I did not check to see if the sum of product expansion gives in certain corner cases errors due to ScalarEvolution. However, even the initial patch (from https://reviews.llvm.org/D35478) had "bugs" - it was not working because it was not treating the Nominator. Therefore, we are now treating it for cast expressions. Note that SCEVDivision is a SCEVVisitor - see http://llvm.org/doxygen/ScalarEvolutionExpressions_8h_source.html#l00445: we see that we only need to treat it for Trunc, ZExt, SExt - methods visitTruncateExpr(), visitZeroExtendExpr(), visitSignExtendExpr(). Note that in this patch we only address the SExt. We also had to adapt numberOfTerms() to treat for cast expressions.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Please post patches with full context (http://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface)
Missing unit-tests.
Please put the rename into a separate patch; it makes the functional changes more difficult to review.
I don't think you can "ignore" all these operations like this; I mean, I can see ignoring sign-extension because it's signed division, but zero-extension or truncation actually changes the result. (4294967300/4294967298 is very different from 4/2.)
Thanks Alex for the patch. I just see it now. As Eli is mentioning already, could you separate the patch into separate differentials?
- One for renaming nominator/denominator to dividend/divisor. It will be discussed/decided on independently.
- One for allowing sext in delinerization (this differential, please add at least one unit-test)
- Another for zext, trunc expressions, these probably need some discussion about their correctness.
Thanks.
Adding very simple unit tests on which normally Polly fails to detect the right SCoP due to the sext (and trunc, as well) in both dividend and divisor used in the third step of the delinearization algorithm (it seems the SCEV expressions sext(N * N), sext(N), etc are created by the 1st step of the delinearization algorithm extracting the terms from the sum of products from the array index i * N * N + j * N + k) presented in Section 4.1 of the paper Grosser et al, "On recovering Multi-dimensional Arrays in Polly", IMPACT 2015 - http://impact.gforge.inria.fr/impact2015/papers/impact2015-grosser.pdf ). Because of this Polly complains of non-affine expression for array indexing.
To make Polly work, we need to apply the patch I already committed (I will put another patch ASAP).
Please note my patch is not incremental w.r.t. patch from https://reviews.llvm.org/D35478 - you need to apply ONLY my patch.
As requested by Michael (Meinersbur) I add the .ll unit tests (and also the .c files used to generate the .ll files, just in case).
This is a commit to LLVM, not Polly. The unit test should be in LLVM as well. There are already tests in test\Analysis\Delinearization. You can model a new one after one that already exists.
Note that in this patch we only address the SExt, as suggested by Michael (Meinersbur).
Could you re-upload the patch with the LLVM source directory as patch root (so it patches include/llvm/Analysis/ScalarEvolution.h instead of ./ScalarEvolution.h).
Could you format your changes using clang-format?
We also need a test-case.
Added correct path to the ScalarEvolution.cpp file (lib/Analysis/ScalarEvolution.cpp). Again, my patch incorporates also the one from https://reviews.llvm.org/D35478 - in order to make it work well for SCEVDivision, when having SExt expressions. My own changes are basically only the ones handling SCEVSignExtendExpr.
Please always upload all patches with the full context.
Also, the tests need to be added as well, with the code changes, into the repo.
Adding as Roman said the patch for ScalarEvolution.cpp and also the associated test test/Analysis/Delinearization/test_sext.ll .
test/Analysis/Delinearization/test_sext.ll | ||
---|---|---|
41 | I'm guessing this is the expected result that you want to check? Look at other files in that directory, e.g. test/Analysis/Delinearization/constant_functions_multi_dim.ll |
Adding, as Roman suggested, in the header of the test_sext.ll file a line describing the RUN command and a CHECK line.
lib/Analysis/ScalarEvolution.cpp | ||
---|---|---|
945–955 | This patch is for handling sext only, correct? In this case, are these two cases needed? | |
1083 | This change looks unnecessary/unrelated to this patch. | |
1089 | This change looks unnecessary/unrelated to this patch. | |
1111–1113 | This change looks unnecessary/unrelated to this patch. | |
test/Analysis/Delinearization/test_sext.ll | ||
5 | Is this a line to be checked? Then the line must start with CHECK: instead of AddRec: |
I could not apply the patch: test/Analysis/Delinearization/test_sext.ll is marked to modify an existing file which does not exist. Did you add the file using git add -N and created the diff against that?
I applied this patch. However, your test-case fails.
lib/Analysis/ScalarEvolution.cpp | ||
---|---|---|
943 | Please document what this function is supposed to do. | |
945–960 | These seem to just ignore casts of the denominator. If SCEVDivision implements a signed division, then this should be ok for sext. If it implements unsigned division, it should be ok for zext. However, it is never semantically correct for both at the same time nor for trunc. | |
969 | SCEV only has SCEVUDivExpr, i.e. cannot represent signed division. Therefore signed division seems the wrong interpretation here. SCEVDivision::divide might actually do a signed division, unfortunately I cannot find any documentation supporting this. | |
test/Analysis/Delinearization/test_sext.ll | ||
11 | This check fails for me. I get the output: Base offset: %a ArrayDecl[UnknownSize][%N][%N] with elements of 16 bytes. Maybe you want to check the ArrayRef line as well. |
Made a better patch following comments from Michael Kruse.
Most importantly I added comments that I consider SCEVDivision::divide() to be signed division.
Hello. I just have some test Nits.
lib/Analysis/ScalarEvolution.cpp | ||
---|---|---|
10720 | Don't need the brackets, like the if below | |
test/Analysis/Delinearization/test_sext.ll | ||
2 | This line doesn't seem to be true and can be removed I think | |
3 | It's probably best to not run -O3 here, as it could change the output as llvm evolves. You can run -O3 on the input now and use that generated IR for this test, then just needing -delinearize -analyze. | |
62 | source_filename and ModuleID can be removed | |
66 | This Function Attrs comment and the #0 on the function can be removed |
Addressed small review issue of greened (David Greene) on comment in method: void visitAddRecExpr(const SCEVAddRecExpr *Numerator) .
Not really sure why this patch got stuck, do you not want it to progress?
The comments in code read *really* weird, and inline comments aren't being addressed.
Yeas, I would like to see this implemented, but I don't have confidence that this review is going forward. It has always been the first item on my Phabricator dashboard a I wanted to clean it up.
Please document what this function is supposed to do.