<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/80980>80980</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [AArch64][SVE] Cannot be vectorized because unsafe dependent memory operation in loop (TSVC, s115)
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          m-saito-fj
      </td>
    </tr>
</table>

<pre>
    Clang cannot SVE vectorize TSVC s114, but GCC13.2.0 can.

Option:
`-Ofast -march=armv8.2-a+sve`

```c
#define LEN 32000
#define LEN2 256
static int ntimes = 200000;

float a[LEN], b[LEN], c[LEN], d[LEN], e[LEN];
float aa[LEN2][LEN2], bb[LEN2][LEN2], cc[LEN2][LEN2], dd[LEN2][LEN2];

int dummy(float[LEN], float[LEN], float[LEN], float[LEN], float[LEN],
          float[LEN2][LEN2], float[LEN2][LEN2], float[LEN2][LEN2], float);

int s115()
{
        for (int nl = 0; nl < 1000*(ntimes/LEN2); nl++) {
                for (int j = 0; j < LEN2; j++) {
                        for (int i = j+1; i < LEN2; i++) {
 a[i] -= aa[j][i] * a[j];
 }
                }
                dummy(a, b, c, d, e, aa, bb, cc, 0.);
        }
        return 0;
}
```

See also (Clang vs GCC):
https://godbolt.org/z/h8WE5raja

for.body IR:
```llvm
for.body8.lr.ph:                                  ; preds = %for.body4
  %arrayidx12 = getelementptr inbounds [32000 x float], ptr @a, i64 0, i64 %indvars.iv37
  br label %for.body8, !dbg !26

for.body8: ; preds = %for.body8.lr.ph, %for.body8
  %indvars.iv34 = phi i64 [ %indvars.iv, %for.body8.lr.ph ], [ %indvars.iv.next35, %for.body8 ]
  %arrayidx10 = getelementptr inbounds [256 x [256 x float]], ptr @aa, i64 0, i64 %indvars.iv37, i64 %indvars.iv34, !dbg !27
  %0 = load float, ptr %arrayidx10, align 4, !dbg !27, !tbaa !28
  %1 = load float, ptr %arrayidx12, align 4, !dbg !32, !tbaa !28
 %mul13 = fmul fast float %1, %0, !dbg !33
  %arrayidx15 = getelementptr inbounds [32000 x float], ptr @a, i64 0, i64 %indvars.iv34, !dbg !34
  %2 = load float, ptr %arrayidx15, align 4, !dbg !35, !tbaa !28
  %sub = fsub fast float %2, %mul13, !dbg !35
  store float %sub, ptr %arrayidx15, align 4, !dbg !35, !tbaa !28
  %indvars.iv.next35 = add nuw nsw i64 %indvars.iv34, 1, !dbg !36
  %exitcond.not = icmp eq i64 %indvars.iv.next35, 256, !dbg !25
  br i1 %exitcond.not, label %for.cond1.loopexit.loopexit, label %for.body8, !dbg !26, !llvm.loop !37
}
```
`-mllvm -debug-only=loop-accesses` messages:
```
LAA: Found a runtime check ptr:  %arrayidx15 = getelementptr inbounds [32000 x float], ptr @a, i64 0, i64 %indvars.iv34, !dbg !34
LAA: Found a runtime check ptr:  %arrayidx12 = getelementptr inbounds [32000 x float], ptr @a, i64 0, i64 %indvars.iv37
LAA: We need to do 0 pointer comparisons.
LAA: May be able to perform a memory runtime check if needed.
LAA: Checking memory dependencies
LAA: Bad stride - Not striding over innermost loop   %arrayidx12 = getelementptr inbounds [32000 x float], ptr @a, i64 0, i64 %indvars.iv37 SCEV: {@a,+,4}<nw><%for.body4>
LAA: Src Scev: {@a,+,4}<nw><%for.body4>Sink Scev: {{(4 + @a)<nuw>,+,4}<nw><%for.body4>,+,4}<nuw><%for.body8>(Induction step: 0)
LAA: Distance for   %1 = load float, ptr %arrayidx12, align 4, !dbg !32, !tbaa !28 to   store float %sub, ptr %arrayidx15, align 4, !dbg !35, !tbaa !28: {4,+,4}<nw><%for.body8>
Pointer access with non-constant stride
LAA: Src Scev: {{(4 + @a)<nuw>,+,4}<nw><%for.body4>,+,4}<nuw><%for.body8>Sink Scev: {{(4 + @a)<nuw>,+,4}<nw><%for.body4>,+,4}<nuw><%for.body8>(Induction step: 1)
LAA: Distance for   %2 = load float, ptr %arrayidx15, align 4, !dbg !35, !tbaa !28 to   store float %sub, ptr %arrayidx15, align 4, !dbg !35, !tbaa !28: 0
Total Dependences: 2
LAA: unsafe dependent memory operations in loop
```
There seems to be a problem with the two dependencies.
1) Load and store for a[i]
2) Store for a[i] and load for a[j]

GCC13 is able to vectorize by vector masked load/store.
```asm
.L4:
        ld1w    z1.s, p0/z, [x8, x0, lsl 2]
        ld1w    z0.s, p0/z, [x10, x0, lsl 2]
        fmsb    z0.s, p1/m, z2.s, z1.s
        st1w    z0.s, p0, [x8, x0, lsl 2]
        add x0, x0, x20
        whilelo p0.s, w0, w9
        b.any .L4
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWFtz6jgS_jXipQuXLNtgHngIELamKntmazmVeZZtAcqxJa8kc8mv35JkwOZykqk9mZ0UFVtW96fuT92tC9WabwRjU5TMULIY0MZspZpWQ025kcP12yCTxXE6L6nYQE6FkAZWr8-wY7mRir8z-L56nYMOwxiROWSNgX_M52EUkABb-QDhBcJP_v_vteFSoKhtohEe_r6m2sCwoirfomhBVbVLAzKkiMz0jqER7urbpvvlbZtEBVtzweDl-RtEBGN8p4MASUb-uzbU8By4MCAMr5gGFC3A6mGMoll3rHUpqQGKktnL8zeULJx3vVbeaxW9Fru0TrAtYItIbNflzYJnj3ry_FFPUdzt6XtivS2aqjoikjojepb-oi9-KDj_dQRuzf5fO8nkjos6DBNEUtvpe8azvlFrqQCR1E1-6Sbezrl_n0NoQ4A8IZL6yEBk6cZ1Y4EoEZm53wRugO8M8HbBf3PwDsu2PoFzB487PKscWhTew-T3MG2ccZQsYGg1Xdi9eTrdV0S8yFs3XgCNF_dNethxCizq88OlhcsGlwRkbkf2we0DmcwBB90JfDiCYqZRAjp5eZI4l4FuCKwYA1pqaRnz1WqnbSlyY7UyW2NqbVtkichyI4tMliaQaoPI8h2R5Tb94zlR9I32CoFUga2B8Nu_u5XL_8pyV_XF0qBUQb1F0cNp7bAazaBWrPBlCJHkBBKfqEAkoUrRIy8OIXFSG2ZYySomTG0UcJHJRliAZObqHxxOCeTyxcqgGLs54KMY8OkFkYSLYkeVDvguGp_GyxSUNGNl15jU6iASFtnGPsjoHjupdfihPydSHFAH-OJlx5jYaddb7g1NZv3-axAPDa3DN-KBYAcTJddaTv4OyfgDkkkygsPl5cx1n-6P-b77Ob5ietyx0BtWSlqcimA7XNd4l3Al3wi4hfJtk1HqPnTJDz-BTR5iR-QRNiJJ1ZRh5ODXVVOCW-39SmjHbWcFXwFG92Ym-brwv3aom37kE9wkj7lJfsa7bjJPjX3pU9Ny6vm7wWwhtJGKXXR0k_1K625yyNlKiwJEsweh94-YDK9GGXVA2YGbXIoisBtJi8fzqgb2n1usTuLa_Vs_nJNOweLhNbAV7pUx2xEGpZS1FTu_3MjdL3e-bUu903Q-jT9Yk0Z4WFkNGBYsazZDKcojihZWf0jznGnNNBphqJjWdMP07dLimy9PT7ayLm2YAwXVuN0J5FuW_7Az7daZ_2-a_GkTv34ha036g4FgrAAjoZCAoZZcGKYgl1VNFddS6KCn8E96hIwBzUpmlWqm1lJVQKFilVTHK9_42sGzog8yt51cbE5KBauZKJjIOdM9wRktQBvFCwZD-CaNb1hNuWOWEsFUJbUBF3V_HYewmj-_uvV8PGvl3fZyHttwj-Zij6JnFM17G5bouefbSuWwytnuz8OsuPjRUx3PEEmtkbPW-olVbpz2Jy27Fmtu5VInl_4miia3p1TQhtXWBHw-UbSuLbg2VOTM7c-_Zv20wfc15d1zGn-CuPQ8pf9q08bXLdhzswUhxTCXwjLRxi376fz_dZP4d4uf8OP4-eV7jC-Nn3Zl-i4NLWFxKm5uCQPS87QRmq7ZuQCaU0WUNVPUkqSBC1fd7q5937dMMdCMVdo6ZAsz1EpmJat8EJotA7OXvQrb1mLLOrxYRqkoTkxIdT4Weyl7vIfVTafT8dPRfn07q_j_7o4LuD4vFZf7sOzYNqCi-gfzQIgsnQ3BlaNUt8fH4CU-bwFOx8OyCPf2-R4G2s0c9udUd8o5uH3KwdXwUpdAOgeaK3V8T90fFn6mv6501tMPEVlW9u2d-C_OsJ6ONrdjftJcu7E8dIw6ENwX2G95yUoJdYu9d2L7SV8qC6g4gqWzz_SgmEbFJJrQAZuGYzyO8GiCw8F2inGYEJJnoyjGeB2NwxHBxRrjaFTEOArZgE8JJjEmeByGSYLDYJzGZByOJus4x3mSExRjVlFeBm6LKNVmwLVu2DTFkxQP3AZTu_tVQgTbg-tExDIwUFOrM8yajUYxLrk2-oJiuCndxezTk8q3o9hf36xen22Izv1dbMYuoVdAxnLaaPZx4p3yDhBJv69e55ZJf4E2GTSqnF7dlHCzbbIglxUiS3fl4R_DWsk3lhtEls4pjcjSOf3fAAAA__8hxSEj">