Description
When I try to use both unroll_count(8) and vectorize(disable) on a loop, I get unexpected results.
Example, compiled with -O3:
typedef struct { int i, j; } Pair;
void j(Pair *p);
void f(void) {
Pair p[640];
#pragma clang loop unroll_count(8) vectorize(disable)
for (int j = 0; j < 640; ++j)
p[j] = (Pair){0, 1000};
j(p);
}
The loop is unrolled with factor 5 instead of 8 as specified in the unroll_count: https://godbolt.org/z/Keoxqob57
If I change the trip count to 64, it's completely unrolled which is also unexpected.
If I remove "vectorize(disable)", the loop is unrolled with factor 8 as I expect.
I think there are some issues with followup metadata. The unroll_count is placed in a "llvm.loop.vectorize.followup_all" metadata node, and vectorization is disabled, meaning the followup metadata isn't promoted to become normal loop metadata. So the UnrollPass doesn't see it.
For the unexpected full unroll with a lower trip count: this happens in the FullUnrollPass, which is before LoopVectorizePass, so the followup metadata hasn't even had a chance to become normal loop metadata. This seems like a flaw in the followup metadata design.