$ clang -O2 -c 02_vectorize.c -o /dev/null -Rpass=loop-vectorize -Rpass-missed=loop-vectorize -Rpass-analysis=loop-vectorize
axpy : remark: vectorized loop (vectorization width: 4, interleaved count: 2)
axpy_restrict : remark: vectorized loop (vectorization width: 4, interleaved count: 2)
dot : remark: loop not vectorized: cannot prove it is safe to reorder floating-point
operations; allow reordering by specifying '#pragma clang loop vectorize(enable)'
before the loop or by providing the compiler option '-ffast-math'
dot_pragma : remark: vectorized loop (vectorization width: 4, interleaved count: 2)
prefix : remark: loop not vectorized: unsafe dependent memory operations in loop.
Use #pragma clang loop distribute(enable) to allow loop distribution ...
find_neg : remark: loop not vectorized: Cannot vectorize potentially faulting early exit loop
gather : remark: loop not vectorized: cannot identify array bounds
main's loops : vectorized (the fill loop)Read it: width 4 = four floats per 128-bit register; interleave 2 = two independent vector accumulators/streams per iteration. `axpy` vectorized even though y and x may alias: clang emitted a RUNTIME overlap check and two versions of the loop (versioning). `restrict` removes the check.
$ clang -O2 -march=native -c 02_vectorize.c -o /dev/null -Rpass=loop-vectorize
axpy, axpy_restrict, dot_pragma : vectorized loop (vectorization width: 8, interleaved count: 4)
gather : vectorized loop (vectorization width: 8, interleaved count: 1)With AVX2 the width doubles, and `gather` now vectorizes (vpgatherdd exists), while the cost model still refuses to interleave it.