I have a loop of the form
for (int i = 0; i < SOME_CONSTANT; ++i) {
// do some stuff involving `i`.
}
which clang is partially unrolling to do two passes at a time. I need it to not be unrolled at all.
One option is to add an inline assembly barrier to prevent clang/LLVM from seeing how i is modified:
for (int i = 0; i < SOME_CONSTANT; ++i) {
asm volatile("" : "=r"(i) : "0"(i));
// do some stuff involving `i`.
}
but I'm wondering if there is a clearer way without resorting to such hacks.
clang is quite aggressive with vectorization, even at "-O2" - and you may need to minimize that as well, so I'll add them here. The following pragma only affects the next loop statement:
_Pragma("clang loop unroll(disable) vectorize(disable)")
for (int i = 0; i < n; ++i) {
// do some stuff involving `i`.
}
I've needed this for my own purposes, and spent some time chasing up version numbers that support these options. This requires: __clang_major__.__clang_minor__ >= 3.7, which is ancient, and corresponds to Apple's hacked Xcode release version: __apple_build_version__ >= (7000072))
FYI, (__GNUC__ >= 8), provides the loop pragma: _Pragma("GCC unroll (0)"); and (__GNUC__ >= 14) finally provides: _Pragma("GCC novector") - earlier versions need to use optimization options, or various inline asm tricks.