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

    <tr>
        <th>Summary</th>
        <td>
            Vectorization Miscompilation in clang 15+
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          yuxuanchen1997
      </td>
    </tr>
</table>

<pre>
    We believe there is a problem in LoopAccessAnalysis or LoopVectorize that caused the following code snippet to produce wrong result.

Compiler command 
```
clang -Xclang -target-cpu -Xclang haswell -Xclang -tune-cpu -Xclang skylake -O2 repro.c
```

repro.c
```c
#include <stdio.h>
#include <stdlib.h>

typedef struct {
  unsigned long long ref_count;
} MyObject;

static int mycount(MyObject** arr) {
  MyObject** old_arr = arr;
  while (*arr++)
    ;
  return (int)(arr - old_arr) - 1;
}

void my_inplace_repeat(MyObject** arr, int times) {
  int orig_elem_count = mycount(arr);
  int pos = orig_elem_count;
  for (int i = 1; i < times; i++) {
    for (int j = 0; j < orig_elem_count; j++) {
      MyObject* obj = arr[j];
 obj->ref_count++;
      arr[pos++] = obj;
    }
  }
  arr[pos] = 0; // NULL terminated list
}

MyObject* obj_alloc() {
 printf("allocating\n");
  MyObject* ret = malloc(sizeof(MyObject));
 ret->ref_count = 1;
  return ret;
}

int main() {
 MyObject** arr = malloc(sizeof(MyObject*) * 1000);
  arr[0] = obj_alloc();
  arr[1] = 0;

  my_inplace_repeat(arr, 4);
 my_inplace_repeat(arr, 2);

  int count = mycount(arr);
 printf("count = %d\n", count);
  for (int i = 0; i < count; i++) {
 if (arr[i]->ref_count != count) {
      printf("BUG: ref_count should be %d, but %llu was found.\n", count,
      arr[i]->ref_count); return 1;
    }
  }
  return 0;

```

Compiler Explorer: https://godbolt.org/z/9Er6n81PT

This issue repros on LLVM 15 onwards.

The vectorization happened in the inner loop of `my_inplace_repeat`. Somehow Vectorization saw this `obj->ref_count++` as safe to vectorize while `obj` might be an alias from the previous iteration. This code snippet deliberately created aliases in the array argument to `my_inplace_repeat`.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMVl2zojgQ_TXxpUsLAqg8-ODHdV_u7GzVzszu260ALcQJCZWE6zi_fisBFfQ6O1UWQnL6pLtPdxJmDC8l4ookG5LsJqy1ldKrc_ujZTKvUIZpuphkqjiv_kHIUHB8R7AVagRugEGjVSawBi7hValmnedozFoycTbcgNJ-9BvmVmn-01kyCzlrDRaOBQ5KCHXisoRcFQhG8qZBC1Y54qLNEU5ayRI0mlbYGQl2JFh3z62qGy5QQ67qmskC-sl50P_8Zy6YLGH6b_9vmS7RTvOmvY5VzJxQiAGmlThCmO9nwb4jTD9T0NhoNcs_XKt7foy4fNOIy1y0BQKJtsYWXM0qEr08mRU8G077pz03WOABjNVtboEsNt04QCu9mAUIlzLR5e3wlqtWWhL1MLLYwafz5-yI-WDQP41llufApYX63FnR5RVL14SugWlNaDpc9Q6gRPHGtAYS7Tw4ugJPFRcIhC4JXXuajf-ll3mAAVijbbV0aO7cSAldOtbphd85MYVwGNYwlHfFC6jPb1w2guX4prFB9iycrQ_Z8hrNXWxuXGlevqHAukukD-yWns6VgePOpFHGw-5MB6iD0n1swD3UReJft70j7vOaoqFPI-OjNw4c-uiNH5eE4xOakXSgsuNVs2RzJMnu5q7KjlMSvdyKqSOMRmSdYaNMP5vsuhxkxxHwKtTo9Wbcm_mQCN0Tuoc_v76-gkVdc8msK29u7Ieq38XzxoRQuS-4YeiN5tIe_DD1CGa5LEmylYTSsZhDQo299hdWw3-iOoxqKh2Za7SjtF2FvityjfZZHfteZFw-BPFYx__r3Noz0DWEQRCM4-zSHww0G-buARgOVRq6Cx_2XN9k8YjqF8CRCMO--p0GHKp7wxOaFFeFt9Abp7_qyODWkddW-rAj-QF6P5INJ8nuTnMaOrbLivctOHR38_UPEq1vezaYSrWigAw7_-kWstYxJkK0cGIGDqqVxewxsO1jYz541oV_qcHwN5q0hwajs-QXJ-H1hH750QilUbvoKmsbQ6J119ulKjIl7EzpktD9T0L36Yuey2X415ch05eKG-DGtNgdwAaUhNfXb58gTEDJE9OFmY0NEN77WwezXEmoWNOgOxy59DcPLiVqEEo1oA5A5sFjQc6DGfytaqzUCb6NyAw7gXU-kXnwZHOcB8AMGHZAd5t5v96A-lPQ2zlQzcvKOomZBCa4E1Wr2rvYaHznqjXALWq_8Ax8JkZ3pQIFz9w8ijPkGv0W6ZnQXIJlWrMzMF22NUp_vXoW8KRYRUUapWyCq3CeLpY0jsNkUq2CxfyQxvM8ycI0XcYLDOM4xgVjdJHMF9lywlc0oFEY0CBcJFGUzOK4oGkSzBdBXERxFJI4wJpxMRPivXaKT7yiq3m6iOOJYBkK4--hlPp7lyvpZDfRK4efZm1pSBy4vd_cGCy3AldjcT5xk_vK6z65hO4aFyaEbiatFqu7GuS2arNZrmpC9465_5s2WnU75947agjde1__CwAA___Ly07x">