Closed Quuxplusone closed 6 years ago
Hans, I am marking it blocking as release 7 to bring that to your attention. However, as we already shipped 6.0 with this issue, maybe you might not want to take it (but this is a pain for users to debug such issue, you might want to take a patch :)
Bisect shows that this was introduced in https://reviews.llvm.org/rL313012
r313012 allows versioning of the loop for vectorisation.
In the example, the code is vectorizable and the vectorised version of the loop should be executed. So it seems that the change exposed some hidden bug.
FWIW I can reproduce this on AArch64 as well, so the problem is somewhere in the mid-end optimizers.
Pretty interesting, the problem also disappears when compiling with -
fsanitize=undefined, e.g.:
$ clang++ -O2 pr38786-2.cpp -o pr38786-2 && paste <(seq 1 5) <(seq 1 5) |
./pr38786-2
1
2
2
0
0
$ clang++ -fsanitize=undefined -O2 pr38786-2.cpp -o pr38786-2 && paste <(seq 1
5) <(seq 1 5) | ./pr38786-2
1
1
1
1
0
As far as I can see, the program isn't doing anything that is undefined, though.
Attached bug-38786.c
(326 bytes, text/x-csrc): Reduced testcase
Attached bug-38786.c
(322 bytes, text/x-csrc): Reduced testcase
Attached reproducer.ll
(1302 bytes, text/plain): vectorizer IR input
It seems that the problem is somewhere in fixFirstOrderRecurrence.
@Matthew, Anna: any idea what going on here? My analysis above would suggest that first order recurrences are broken at the moment, but maybe I've missed something obvious?
Attached PR38786.patch
(679 bytes, text/plain): Tentative fix
Thanks! Your patch fixes the issue.
(In reply to Orivej Desh from comment #10)
> Thanks! Your patch fixes the issue.
Are you working on a patch with test case that can be send for review? It would
be nice to get this fixed for the 7.0.0 release, but then it has to happen very
soon.
I have created https://reviews.llvm.org/D51639
For my notes: the patch landed in r341416. Let's have that bake in trunk a little bit before merging.
Merged in r341523.
This section of the patch doesn't apply to the 6.0 branch.
What should it be it?
--- lib/Transforms/Vectorize/LoopVectorize.cpp
+++ lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -4529,6 +4529,11 @@
// isOutOfScope operands cannot be uniform instructions.
if (isOutOfScope(OV))
continue;
+ // First order recurrence Phi's should typically be considered
+ // non-uniform.
+ auto *OP = dyn_cast<PHINode>(OV);
+ if (OP && Legal->isFirstOrderRecurrence(OP))
+ continue;
// If all the users of the operand are uniform, then add the
// operand into the uniform worklist.
auto *OI = cast<Instruction>(OV);
LoopVectorize.cpp in release_60 and release_70 do not have surrounding comments. You can apply the diff from release_70: svn diff http://llvm.org/svn/llvm-project/llvm/branches/release_70/{lib,test} -c341523
bug-38786.c
(326 bytes, text/x-csrc)bug-38786.c
(322 bytes, text/x-csrc)reproducer.ll
(1302 bytes, text/plain)PR38786.patch
(679 bytes, text/plain)