Skip to content

The unroll_count pragma does not work together with vectorize(disable) #75839

@mveriksson

Description

@mveriksson

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions