The logic of the `LoopVectorizationLegality::reportVectorizationFailure` method is extracted into a utility function which is exported through the `LoopVectorize.h` header file and is available for the LoopVectorize pass. The methods `createMissedAnalysis` as well as `reportVectorizationFailure` were removed, they aren't required anymore. The function `debugVectorizationFailure` is marked as static and is available in LoopVectorize.cpp only.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Sorry, I missed the original review request in the e-mail pile up. Yes, this is the direction I was suggesting. Thank you.
My preference is to have the utility declared in LoopVectorize.h as a more neutral place. If we had vectorizer utility .h/.cpp, that would have been ideal, What bothers me is Hints.vectorizeAnalysisPassName(). Anybody know why we use AlwaysPrint()?
Not a big fan of creating a new entry just for two parameters --- especially when those two parameters are probably the same for all cases. If we can always use LV_NAME, one of the two parameters can be eliminated.
If theLoop is the only thing left, passing it from all calls seems better than having two functions with the same name with same functionality (on in class and one at top level).
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
7396–7399 | Do we need :: here? | |
7410–7413 | Same as above |
I agree with Hideki, this could be in LoopVectorize.h.
Also the function overload is confusing, better to just use the same function for all cases.
Once the pattern is done, refactoring is not that hard. If we have overloaded functions, refactoring is a lot harder.
cheers,
--renato
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
7396–7399 | Doesn't make sense to me, given that it should be identical as calling the local function. Also, this pattern is confusing, better to just use the same helper function on all cases. |
The diff has been updated: private methods were removed, the function 'reportVectorizationFailure' was moved to LoopVectorize.cpp and declared in LoopVectorize.h (namespace llvm). I've removed the passName parameter and pass LV_NAME as pass name to ORE but this change breaks 3 regression tests:
- Transforms/LoopVectorize/control-flow.ll
- Transforms/LoopVectorize/no_switch.ll
- Transforms/LoopVectorize/pr38800.ll
They all run opt with -pass-remarks-missed='loop-vectorize'
@rengolin @hsaito I need you suggestions how to deal with the Hints.vectorizeAnalysisPassName() method, it is very long to always call it whenever the reportVectorizationFailure is invoked.
I'm assuming that the pass name isn't just LV_NAME, but whichever pass is using that function, which now that it's higher level, can be anything.
@rengolin @hsaito I need you suggestions how to deal with the Hints.vectorizeAnalysisPassName() method, it is very long to always call it whenever the reportVectorizationFailure is invoked.
I don't have a better idea on the top of my head, but this sounds like a change that can be done later as a quick refactory once someone comes up with a clever replacement.
I'd be ok having that for now... @hsaito may have a better idea, though.
--renato
I don't have a better idea, but I think the 3 failed tests are worth looking into, in trying to understand why we would want to emit the remark always. Which test failed?
Here is the log of lit on Vectorization:
- Testing: 319 tests, 8 threads --
Testing: 0 .. 10.. 20.. 30.. 40.
FAIL: LLVM :: Transforms/LoopVectorize/control-flow.ll (150 of 319)
- TEST 'LLVM :: Transforms/LoopVectorize/control-flow.ll' FAILED ****
Script:
: 'RUN: at line 1'; bin\opt.exe < llvm\test\Transforms\LoopVectorize\control-flow.ll -loop-vectorize -force-vector-width=4 -S -pass-remarks-missed='loop-vectorize' 2>&1 | bin\filecheck.exe llvm\test\Transforms\LoopVectorize\control-flow.ll
Exit Code: 1
Command Output (stdout):
$ ":" "RUN: at line 1"
$ "bin\opt.exe" "-loop-vectorize" "-force-vector-width=4" "-S" "-pass-remarks-missed=loop-vectorize"
$ "bin\filecheck.exe" "llvm\test\Transforms\LoopVectorize\control-flow.ll"
command stderr:
llvm\test\Transforms\LoopVectorize\control-flow.ll:13:10: error: CHECK: expected string not found in input
; CHECK: remark: source.cpp:5:9: loop not vectorized: loop control flow is not understood by vectorizer
^
<stdin>:1:1: note: scanning from here
remark: source.cpp:5:9: loop not vectorized: loop control flow is not understood by analyzer
^
error: command failed with exit status: 1
Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70
FAIL: LLVM :: Transforms/LoopVectorize/no_switch.ll (242 of 319)
- TEST 'LLVM :: Transforms/LoopVectorize/no_switch.ll' FAILED ****
Script:
: 'RUN: at line 1'; bin\opt.exe < llvm\test\Transforms\LoopVectorize\no_switch.ll -loop-vectorize -force-vector-width=4 -transform-warning -S 2>&1 | bin\filecheck.exe llvm\test\Transforms\LoopVectorize\no_switch.ll
: 'RUN: at line 2'; bin\opt.exe < llvm\test\Transforms\LoopVectorize\no_switch.ll -loop-vectorize -force-vector-width=1 -transform-warning -S 2>&1 | bin\filecheck.exe llvm\test\Transforms\LoopVectorize\no_switch.ll -check-prefix=NOANALYSIS
: 'RUN: at line 3'; bin\opt.exe < llvm\test\Transforms\LoopVectorize\no_switch.ll -loop-vectorize -force-vector-width=4 -transform-warning -pass-remarks-missed='loop-vectorize' -S 2>&1 | bin\filecheck.exe llvm\test\Transforms\LoopVectorize\no_switch.ll -check-prefix=MOREINFO
Exit Code: 1
Command Output (stdout):
$ ":" "RUN: at line 1"
$ "bin\opt.exe" "-loop-vectorize" "-force-vector-width=4" "-transform-warning" "-S"
$ "bin\filecheck.exe" "llvm\test\Transforms\LoopVectorize\no_switch.ll"
command stderr:
llvm\test\Transforms\LoopVectorize\no_switch.ll:5:10: error: CHECK: expected string not found in input
; CHECK: remark: source.cpp:4:5: loop not vectorized: loop contains a switch statement
^
<stdin>:1:1: note: scanning from here
warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
^
<stdin>:1:2: note: possible intended match here
warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
^
error: command failed with exit status: 1
Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80
FAIL: LLVM :: Transforms/LoopVectorize/pr38800.ll (272 of 319)
- TEST 'LLVM :: Transforms/LoopVectorize/pr38800.ll' FAILED ****
Script:
: 'RUN: at line 1'; bin\opt.exe -loop-vectorize -force-vector-width=2 -pass-remarks-missed='loop-vectorize' -S < llvm\test\Transforms\LoopVectorize\pr38800.ll 2>&1 | bin\filecheck.exe llvm\test\Transforms\LoopVectorize\pr38800.ll
Exit Code: 1
Command Output (stdout):
$ ":" "RUN: at line 1"
$ "bin\opt.exe" "-loop-vectorize" "-force-vector-width=2" "-pass-remarks-missed=loop-vectorize" "-S"
$ "bin\filecheck.exe" "llvm\test\Transforms\LoopVectorize\pr38800.ll"
command stderr:
llvm\test\Transforms\LoopVectorize\pr38800.ll:3:10: error: CHECK: expected string not found in input
; CHECK: remark: <unknown>:0:0: loop not vectorized: integer loop induction variable could not be identified
^
<stdin>:1:1: note: scanning from here
remark: <unknown>:0:0: loop not vectorized
^
error: command failed with exit status: 1
Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..
Testing Time: 5.85s
Failing Tests (3):
LLVM :: Transforms/LoopVectorize/control-flow.ll LLVM :: Transforms/LoopVectorize/no_switch.ll LLVM :: Transforms/LoopVectorize/pr38800.ll Expected Passes : 261 Unsupported Tests : 55 Unexpected Failures: 3
Looking at the expected output and the explanations on -Rpass* flags, it could be that those tests should be using -pass-remarks-analysis=loop-vectorize, instead of -pass-remarks-missed=loop-vectorize. Would you try?
Snippet from https://llvm.org/docs/Vectorizers.html:
Many loops cannot be vectorized including loops with complicated control flow, unvectorizable types, and unvectorizable calls. The loop vectorizer generates optimization remarks which can be queried using command line options to identify and diagnose loops that are skipped by the loop-vectorizer.
Optimization remarks are enabled using:
-Rpass=loop-vectorize identifies loops that were successfully vectorized.
-Rpass-missed=loop-vectorize identifies loops that failed vectorization and indicates if vectorization was specified.
-Rpass-analysis=loop-vectorize identifies the statements that caused vectorization to fail. If in addition -fsave-optimization-record is provided, multiple causes of vectorization failure may be listed (this behavior might change in the future).
@hsaito Thanks, it solves almost all problems with the tests, but one test - no_switch.ll - requires a bit more work.
The test no_switch.ll has been updated: the LV doesn't report remarks without -pass-remarks-missed='loop-vectorize' -pass-remarks-analysis='loop-vectorize', so the test from the CHECK section is removed. I have no idea why, but remarks with lambdas through the code emitted via OptimizationRemarkMissed, not OptimizationRemarkAnalysis (if I right understand, 'Missed' means the pass has not been applied by any reasons during optimization).
Thanks, @psamolysov. No more LIT test failures? I don't understand the issue with no_switch.ll either, but trying to understand that shouldn't block this patch.
I've renamed the createLVMissedAnalysis method to createLVAnalysis: 'Missed' confuses me because means that a Missed report will be emitted while in fact a Analysis one will be.
@hsaito The test no_switch.ll failed because remarks aren't written now by default, so without -pass-remarks-analysis. I've just removed the corresponding check from the test. But, I think, the NFC label from diff/commit should also be removed in this case because the behavior is changed a little bit. No other problems with tests in the LoopVectorize directory. If this diff is applied, the entire set of tests passes.
This is also not NFC because it changes the option name. In that case, we need to take a longer look and make sure it won't break anyone else and maybe even consider warning the community (which heavily uses opt around).
So, I'd recommend we don't change the name of the pass on this patch, keep the remark and maintain the NFC tag.
If we want to change the name, or behaviour, we can do so later.
@rengolin I think the pass name is not the problem. Before the method was used and the method just asks "Always Print":
const char *LoopVectorizeHints::vectorizeAnalysisPassName() const { if (getWidth() == 1) return LV_NAME; if (getForce() == LoopVectorizeHints::FK_Disabled) return LV_NAME; if (getForce() == LoopVectorizeHints::FK_Undefined && getWidth() == 0) return LV_NAME; return OptimizationRemarkAnalysis::AlwaysPrint; }
For example,
; CHECK: remark: source.cpp:5:9: loop not vectorized: loop control flow is not understood by vectorizer
works on the master branch even without -pass-remarks-missed/-pass-remarks-analysis options. Writing into the OptimizationRemarkMissed (for example, loop not vectorized (Force=true, Vector Width=4) requires -pass-remarks-missed even on the master branch. New behavior: reasons reported only when the -pass-remarks-analysis parameter is used.
The code was introduced by Tyler Nowicki in 2015:
commit e0f400feaa6b0f830cbbc288d0858c506046357b
Author: Tyler Nowicki <tyler.nowicki@gmail.com>
Date: Thu Aug 27 01:02:04 2015 +0000
Improved printing of analysis diagnostics in the loop vectorizer. This patch ensures that every analysis diagnostic produced by the vectorizer will be printed if the loop has a vectorization hint on it. The condition has also been improved to prevent printing when a disabling hint is specified.
Aha, that was a "hacky" way to get "loop contains a switch statement" along with the warning. I see. I suppose we can't blindly use LV_NAME, then.
I then suppose some tests (like pr38800.ll) didn't even need -pass-remarks-missed flag (which is incorrectly used, I think).
We better add some comments in vectorizeAnalysisPassName().
Better this way, let's keep the changes contained to one per patch. If there's interest to change that behaviour or not, it should not hold this patch, which looks good to me now. Thanks!
Done.
Sending include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
Sending include/llvm/Transforms/Vectorize/LoopVectorize.h
Sending lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
Sending lib/Transforms/Vectorize/LoopVectorize.cpp
Adding test/Transforms/LoopVectorize/nofloat-report.ll
Transmitting file data .....
Committed revision 367980.
Buildbot failures reported so far. Just FYI. I don't think any actions from this commit is needed.
http://lab.llvm.org:8011/builders/clang-cmake-aarch64-full/builds/7688 --- I don't think the failure is related to this commit.
http://lab.llvm.org:8011/builders/clang-cmake-aarch64-lld/builds/7038 --- seems to be the same issue as above
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/22705 --- just flaky? subsequent builds are fine.
Do we need :: here?