This is an archive of the discontinued LLVM Phabricator instance.

[clang] Add pragma force_vectorize
Needs ReviewPublic

Authored by kitaisreal on Aug 2 2023, 9:16 AM.

Details

Summary

Add pragma force_vectorize to emit error if loop is not vectorized.
Performance critical applications heavily rely on specific loops being vectorized.
Example:

class Sum {
public:
    __attribute__((noinline)) void sumData(uint64_t * data, size_t size) {
        /// This loop must be vectorized
        #pragma clang loop force_vectorize(enable)
        for (size_t i = 0; i < size; ++i) {
            sum += data[i];
        }
    }
private:
    uint64_t sum = 0;
};

If someone breaks vectorization or new version compiler is unable to vectorize it, error will be emitted.

class Sum {
public:
    __attribute__((noinline)) void sumData(uint64_t * data, size_t size) {
        /// This loop must be vectorized
        #pragma clang loop force_vectorize(enable)
        for (size_t i = 0; i < size; ++i) {
            sum += data[i];
            sum += sum;
        }
    }
private:
    uint64_t sum = 0;
};

clang-17 -emit-llvm -S -O3 -g test_ir.cpp -o test_ir.ll
test_ir.cpp:9:9: error: loop not force vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
    9 |         for (size_t i = 0; i < size; ++i) {
      |         ^
1 error generated.

Diff Detail

Event Timeline

kitaisreal created this revision.Aug 2 2023, 9:16 AM
kitaisreal requested review of this revision.Aug 2 2023, 9:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 2 2023, 9:16 AM
kitaisreal edited the summary of this revision. (Show Details)Aug 2 2023, 9:21 AM

It seems that maybe it is better to specify pragma like this, without (enable).

#pragma clang loop force_vectorize
for (size_t i = 0; i < size; ++i) {
    sum += data[i];
}

But maybe ability to enable or disable force_vectorize can be helpful if we will have pragma for code sections. That way client can disable force vectorization for specific loop.

kitaisreal updated this revision to Diff 547810.Aug 7 2023, 8:47 AM

Fixed build.

Fixed tests.

Hello @aaron.ballman, @erichkeane could you please review this revision ? I wondering if this feature would be useful.

Hello @aaron.ballman, @erichkeane could you please review this revision ? I wondering if this feature would be useful.

My apologies, this fell off my radar by accident, sorry for the delayed response!

I think the utility you're proposing is valuable in theory, but I'm wondering if this is really the right design for the feature (pragmas are awkward for everyone). e.g., should we use an attribute that appertains only to particular kinds of looping constructs? Should this really be an error as opposed to a warning the user is free to ignore?

It seems we already support -Rpass-missed=loop-vectorize and -Rpass-analysis=loop-vectorize (https://www.llvm.org/docs/Vectorizers.html#diagnostics) for similar purposes, is there a reason those don't suffice?

I think this is a topic where people may have enough opinions to warrant raising it as an RFC on Discourse (https://discourse.llvm.org/) to get feedback on the design. Note, we've largely switched reviews over to GitHub PRs. We don't usually move a review from Phab to GitHub because we'll lose significant review context, but it may be a reasonable approach here given the unfortunate lack of review thus far. So my recommendation if you're still interested in pursuing this would be to start a discussion on Discourse and then open a new review on GitHub once the design is more settled.