[AArch64][SVE] Missed vectorization opportunity for early-exit loop with strided access compared to GCC
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
**Description:**
Clang fails to auto-vectorize a nested loop with early exit (`break`) and strided memory access on AArch64 with SVE enabled, while GCC successfully vectorizes the same loop under identical compilation flags.
The inner loop iterates backwards with a conditional `break` when `a[idx] != -1`, and computes `idx = i * m + j` which creates a strided access pattern due to the outer loop decrementing by 2. Clang 21.1.1 reports that it cannot identify the reduction value and cannot vectorize early exit loops. Clang trunk (23.0.0git) provides a more specific diagnostic indicating that early-exit vectorization with strided fault-only-first load is not yet supported. In contrast, GCC 16.0 successfully handles this pattern using loop versioning and generates vectorized code.
**Test case:**
```c
#include
#include
int foo(
const int * __restrict__ a,
int n,
int m) {
int product = 1;
for (int i = n - 1; i >= 0; i -= 2)
{
for (int j = m - 1; j >= 0; j -= 1)
{
int idx = i * m + j;
product *= a[(idx + 29)];
if ((a[idx] != -1)) {
break;
}
}
}
return product;
}
```
**clang version:**
```
clang version 21.1.1
Target: unknown
Thread model: posix
Build config: +unoptimized, +assertions
```
**Clang options:**
```
-S -O3 -ftree-vectorize -ftree-slp-vectorize --target=aarch64-linux-gnu -march=armv9-a+sve -Rpass=.*vectorize.* -Rpass-missed=.*vectorize.* -Rpass-analysis=.*vectorize.*
```
**The result of Clang 21.1.1:**
```
test.c:4:7: remark: loop not vectorized: value that could not be identified as reduction is used outside the loop [-Rpass-analysis=loop-vectorize]
4 | int foo(
| ^
test.c:4:7: note: could not determine the original source location for example.c:0:0
test.c:11:9: remark: loop not vectorized: Cannot vectorize early exit loop [-Rpass-analysis=loop-vectorize]
11 | for (int j = m - 1; j >= 0; j -= 1)
| ^
test.c:11:9: remark: loop not vectorized [-Rpass-missed=loop-vectorize]
```
Also reproducible on Godbolt (https://godbolt.org/z/GKrabc1jn).
**clang version (Clang trunk):**
```
clang version 23.0.0git (https://github.com/llvm/llvm-project.git 793bdd8597894c6efafc98ef8ddfbf6292a8024c)
Target: aarch64-unknown-linux-gnu
Thread model: posix
```
**The result of Clang trunk:**
```
test.c:11:9: remark: loop not vectorized: value that could not be identified as reduction is used outside the loop [-Rpass-analysis=loop-vectorize]
11 | for (int j = m - 1; j >= 0; j -= 1)
| ^
test.c:11:9: remark: loop not vectorized: Cannot vectorize early exit loop with strided fault-only-first load [-Rpass-analysis=loop-vectorize]
test.c:11:9: remark: loop not vectorized [-Rpass-missed=loop-vectorize]
```
Also reproducible on Godbolt (https://godbolt.org/z/EqbGbj187).
**However, GCC vectorizes it.** GCC version 16.0
**gcc version:**
```
aarch64-linux-gnu-gcc (GCC) 16.0.1 20260419 (experimental)
Copyright (C) 2026 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```
**GCC options:**
```
-S -march=armv9-a+sve -ftree-vectorize -O3 -fopt-info-vec-all
```
**The result of GCC:**
```
test.c:9:27: missed: couldn't vectorize loop
test.c:9:27: missed: not vectorized: unsupported control flow in loop.
test.c:11:31: optimized: loop vectorized using 16 byte vectors and unroll factor 8
test.c:11:31: optimized: loop versioned for vectorization to enhance alignment
test.c:4:7: note: vectorized 1 loops in function.
test.c:13:17: note: ***** Analysis failed with vector mode VNx8HI
test.c:13:17: note: ***** The result for vector mode VNx16QI would be the same
test.c:13:17: note: ***** Re-trying analysis with vector mode VNx8QI
test.c:13:17: note: ***** Analysis failed with vector mode VNx8QI
test.c:13:17: note: ***** Re-trying analysis with vector mode VNx4QI
test.c:13:17: note: ***** Analysis failed with vector mode VNx4QI
test.c:13:17: note: ***** Re-trying analysis with vector mode VNx2QI
test.c:13:17: note: ***** Analysis failed with vector mode VNx2QI
test.c:13:17: note: ***** Re-trying analysis with vector mode V16QI
test.c:4:7: note: ***** Analysis failed with vector mode V16QI
test.c:4:7: note: ***** Re-trying analysis with vector mode V8QI
test.c:4:7: note: ***** Analysis failed with vector mode V8QI
test.c:4:7: note: ***** Re-trying analysis with vector mode V4HI
test.c:4:7: note: ***** Analysis failed with vector mode V4HI
test.c:4:7: note: ***** Re-trying analysis with vector mode V2SI
test.c:4:7: note: ***** Analysis failed with vector mode V2SI
```
Also reproducible on Godbolt: https://godbolt.org/z/6MqM3GEEd
Contributor guide
Assessment
This issue has not been assessed yet.