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

    <tr>
        <th>Summary</th>
        <td>
            [LICM] Miscompilation caused by wrong AA result
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            miscompilation,
            loopoptim,
            llvm:optimizations,
            TBAA,
            llvm:analysis
      </td>
    </tr>

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

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

<pre>
    Reproducer: https://godbolt.org/z/Y1vvbndf8
```
@c = dso_local global i32 0, align 4
@d = dso_local local_unnamed_addr global ptr @c, align 8

define i32 @main() {
entry:
  br label %for.cond

for.cond: ; preds = %f.exit.split, %entry
  %b.0 = phi i32 [ 0, %entry ], [ %inc6, %f.exit.split ]
  %cmp = icmp ult i32 %b.0, 2
  br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup

for.cond1.preheader:                              ; preds = %for.cond
  br label %for.cond1

for.cond.cleanup: ; preds = %for.cond
  %0 = load i32, ptr @c, align 4, !tbaa !13
  ret i32 %0

for.cond1: ; preds = %for.cond1, %for.cond1.preheader
  %i.0 = phi i32 [ %inc, %for.cond1 ], [ 0, %for.cond1.preheader ]
  %cmp2 = icmp ult i32 %i.0, 2
  %inc = add nuw nsw i32 %i.0, 1
  br i1 %cmp2, label %for.cond1, label %for.body.i.preheader, !llvm.loop !17

for.body.i.preheader:                             ; preds = %for.cond1
  %cmp2.lcssa = phi i1 [ %cmp2, %for.cond1 ]
  %1 = xor i1 %cmp2.lcssa, true
  %2 = bitcast i1 %1 to <1 x i1>
  %3 = call <1 x ptr> @llvm.masked.load.v1p0.p0(ptr @d, i32 8, <1 x i1> %2, <1 x ptr> poison), !tbaa !9
  %4 = bitcast <1 x ptr> %3 to ptr
  store i32 0, ptr @c, align 4, !tbaa !13
  %5 = load i32, ptr %4, align 4, !tbaa !13
 %tobool1.not.i = icmp ne i32 %5, 0
  %tobool1.not.i.fr = freeze i1 %tobool1.not.i
  br i1 %tobool1.not.i.fr, label %f.exit.split, label %for.body.i.preheader.split

for.body.i.preheader.split: ; preds = %for.body.i.preheader
  br label %for.body.i

for.body.i:                                       ; preds = %for.body.i.preheader.split, %for.body.i
  %n.04.i = phi i8 [ %add.i, %for.body.i ], [ -66, %for.body.i.preheader.split ]
  %add.i = add nsw i8 %n.04.i, 1
  %tobool.not.i = icmp eq i8 %add.i, 0
  br i1 %tobool.not.i, label %f.exit, label %for.body.i, !llvm.loop !15

f.exit:                                           ; preds = %for.body.i
  br label %f.exit.split

f.exit.split: ; preds = %for.body.i.preheader, %f.exit
  store i32 7, ptr %4, align 4, !tbaa !13
  %inc6 = add nuw nsw i32 %b.0, 1
  br label %for.cond, !llvm.loop !18
}

!9 = !{!10, !10, i64 0}
!10 = !{!"any pointer", !11, i64 0}
!11 = !{!"omnipotent char", !12, i64 0}
!12 = !{!"Simple C/C++ TBAA"}
!13 = !{!14, !14, i64 0}
!14 = !{!"int", !11, i64 0}
!15 = distinct !{!15, !16}
!16 = !{!"llvm.loop.mustprogress"}
!17 = distinct !{!17, !16}
!18 = distinct !{!18, !16}
```
After LICM:
```
source_filename = "/app/example.ll"

define i32 @main() {
entry:
  br label %for.cond

for.cond:                                         ; preds = %f.exit.split, %entry
  %0 = phi i32 [ poison, %entry ], [ 0, %f.exit.split ]
  %b.0 = phi i32 [ 0, %entry ], [ %inc6, %f.exit.split ]
  %cmp = icmp ult i32 %b.0, 2
  br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup

for.cond1.preheader: ; preds = %for.cond
  br label %for.cond1

for.cond.cleanup:                                 ; preds = %for.cond
  %.lcssa = phi i32 [ %0, %for.cond ]
  store i32 %.lcssa, ptr @c, align 4, !tbaa !0
  %1 = load i32, ptr @c, align 4, !tbaa !0
 ret i32 %1

for.cond1:                                        ; preds = %for.cond1, %for.cond1.preheader
  %i.0 = phi i32 [ %inc, %for.cond1 ], [ 0, %for.cond1.preheader ]
  %cmp2 = icmp ult i32 %i.0, 2
  %inc = add nuw nsw i32 %i.0, 1
  br i1 %cmp2, label %for.cond1, label %for.body.i.preheader, !llvm.loop !4

for.body.i.preheader: ; preds = %for.cond1
  %cmp2.lcssa = phi i1 [ %cmp2, %for.cond1 ]
  %2 = xor i1 %cmp2.lcssa, true
  %3 = bitcast i1 %2 to <1 x i1>
  %4 = call <1 x ptr> @llvm.masked.load.v1p0.p0(ptr @d, i32 8, <1 x i1> %3, <1 x ptr> poison), !tbaa !6
  %5 = bitcast <1 x ptr> %4 to ptr
 %6 = load i32, ptr %5, align 4, !tbaa !0
  %tobool1.not.i = icmp ne i32 %6, 0
  %tobool1.not.i.fr = freeze i1 %tobool1.not.i
  br i1 %tobool1.not.i.fr, label %f.exit.split, label %for.body.i.preheader.split

for.body.i.preheader.split: ; preds = %for.body.i.preheader
  br label %for.body.i

for.body.i:                                       ; preds = %for.body.i, %for.body.i.preheader.split
  %n.04.i = phi i8 [ %add.i, %for.body.i ], [ -66, %for.body.i.preheader.split ]
  %add.i = add nsw i8 %n.04.i, 1
  %tobool.not.i = icmp eq i8 %add.i, 0
  br i1 %tobool.not.i, label %f.exit, label %for.body.i, !llvm.loop !8

f.exit: ; preds = %for.body.i
  br label %f.exit.split

f.exit.split:                                     ; preds = %f.exit, %for.body.i.preheader
  store i32 7, ptr %5, align 4, !tbaa !0
  %inc6 = add nuw nsw i32 %b.0, 1
  br label %for.cond, !llvm.loop !9
}

declare <1 x ptr> @llvm.masked.load.v1p0.p0(ptr nocapture, i32 immarg, <1 x i1>, <1 x ptr>) #0

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) }

!0 = !{!1, !1, i64 0}
!1 = !{!"int", !2, i64 0}
!2 = !{!"omnipotent char", !3, i64 0}
!3 = !{!"Simple C/C++ TBAA"}
!4 = distinct !{!4, !5}
!5 = !{!"llvm.loop.mustprogress"}
!6 = !{!7, !7, i64 0}
!7 = !{!"any pointer", !2, i64 0}
!8 = distinct !{!8, !5}
!9 = distinct !{!9, !5}
```
```
> lli test.ll
> echo $?
7
> bin/opt -passes=licm test.ll -S -o out.ll
> lli out.ll
> echo $?
0
```
`store i32 7, ptr %5, align 4, !tbaa !0` may write something to `@c`. So this transform is incorrect.

Related patch: https://github.com/llvm/llvm-project/pull/96878
Original C code (needs x86 +cf or riscv +zicldst):
```
#include "csmith.h"
uint32_t c = 0;
int32_t *d = &c;
void f(int32_t *o) {
  uint8_t n;
  for (n = 190; n; n += 1) {
    *o = 0;
    if (*d)
      break;
 }
}
int main() {
  for (int b = 0; b <= 1; b++) {
    uint64_t j[2];
    int i;
    for (i = 0; i < 2; i++)
      j[i] = 1;
 f(&c);
    safe_add_func_int32_t_s_s(0, j[1]);
    *d = 7;
  }
 printf("%d\n", c);
  return 0;
}
```

cc @nikic @fhahn @KanRobert 

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWkuP27oV_jX0hoggUZZsL7ywZ66Bor0okHTTlUGRlM0bilRJah759QWp98PjmUGTTRMEHok673N4eD7Z2Bh-kYztQXIEyeMKV_aq9J5a8vLj9XmVKfq6_8pKrWhFmAbxAV6tLQ2IDwCdADpdFM2UsIHSF4BOPwA6_Tt6esokzbcgfAThAaRh87--XYcEgvgRUqPOQhEs4EWoDAvIYwRDgB4gFvwi4bqjpxN6_3mupMQFo2dMqW5FlFZDp6CX0hrhPynLuWReEViHBeYSoC1AOwg2x5qCSatfnW_-DsJMQ4EzJiBASa50QJSkQ4ndWnyAID7CUjNqvLmOIWAv3AamFNw6iwBKavmNcICSLAg9dXnltVnJsY5BSwtB8ujvk6Nb45KkzeOhdE_VSyVF6aVyd1EJW4v22hwzGnjHo4bBPZi5GgWlZleGKdOLzwMiGJZVuRSSIW98gG_-m4duFOvlPERLWjuLFhMykQpQUodfKExdkJyT8xpa1xGPbIax-xvFrQDNutiGizF404yozeRCxHoL-UKJ1JUwZR_WSnhb9rxY0GK18Em11Eo9KaYUyuoZSvM8oY6WagstF9ds1TWbgI9rDqBIiKciEEqVPvibaaBnXHeq7Y18jKMSCGIM7oMftbFvXZoFv-ePPNuLGkahlucYra7YgLiOf8YtwcY2DBG0CoL4IYIvkEcg_mNAH3t6goVoKUqrQfyHq1sfrAKb74wGrqyDp6gMgzIEaNtUNnUWuKxtvQ8DFd6WwWIjtVTcKAnQbrIPdgOT1iMXJlY5i63ytw2HsUqzvuN_ZM8BlCTLmxYl63cIACixKlNKRIFUNuB97bdHA0oSxxwONI44glx7plwz9oM1-RpRzDbBlH9c-pNz4s090ZDd2QMN1a3uM9syN9psTbes7G5Tf3vD3bC431VD3T4HMgjXTbr8dty22xFTGvAZ57AbfknT2fOp6skG9kL7Zuca3ba3YtTquvxOC4r9p2HqLAxvVEZTNvOquFEPi50xGSWqZn93ku4karFChnU7U_3REhxONfM2sfngLm-HpVvHVTY_ruaD3lKQ24Fy8zh02XXDxrvIDZMoipoTuLng6RqGPZNbHtMDhLB8db1WWhcN1LJHy-zRjF0VkpfKMmkhueKhCLQsAs1EfONFKRh8AOj0ANARoCP81_FwcKKGjPHE1TYL9cVc0XqmiEt738W6zVNuLJfEDvQlLWM6ok9narrUBUVlbKnVRTNjpu5sbunZLOvZ3qLfLtCP0c8ht0zDf_zt4c8OZEwojKo0YeecC-bwTeMSAuiEyxKgE3vBLkeBEG71l4Gbz7eQ-yBoPt-2E8cyDgrvI6D_H1z1c6DTp06KCbSajs89dpmCk2GY-5bfiXjfhBjOpu-PobqWf4DpFsMUfWA7_IZ-_0vot34P8vsl6A59BN3FC-gOvYHu1j8R3cXvR3fpDHDdRHfrMboDKElvIbTkfRv4LkJLfyO0X4PQ7uKm3wjt3QhtuwzQfhLs-lziO5_uFOIyNHvn9v4ZyGy3CMwoIwJr9uFOKhXBpa00a9spLwqsL9OeOmunfuBG8ehtMLZW86yyzPhHdag3R69DiAyT71Aq16qgVOZVEihVJZ-5pPCZC6GZrbSEBSuUfgVoi_WlYIVLsGaY1gP-FItOsGXU4pJlnPU2OlsGj3PseBN-xosC4k-Cz_UN8NWWWzIkTj6HCCdAsoWBm0VHNu_D8cthvAUlt0ve7G4Q7-bEk-_cJrfxH1AIDi0z1uHIbpGRq4IArUF8qhc3_bPM4cmTKi38UmJjmAHxo-CkaKXAL9_gFwVVNRbp9EzXZmpumJmGn2gyaQgL_AqfNbcMGlUwe-Xy4setNPQIIA0D-E1Be-UGWo2lyZUuIDeQS6K0ZsQGw-30lQlsGYUltuS68P0nt9cqC4gqADq56mr-fCm1-osRC9CprBxYP-3S7aY5Af6p-YVLLOADJIoyCNBWMteFX7YpBOhIcqg01NyQJ3f7gxNBjXUz2o23BgDFXBJReVmImILba3Dt3hBUXNoYnS2sZ_gQxM0rgXYdoANt6jgl3dMnxSnMAdoOyNTolQKETvT2bKHsuCDMlfYueYnRzqnzz6F03vjFiRToRU-Mc8s8h_41xsF1un7ZHQsMf-9J-9JvL7i0cOktSGeeI8g6lf7yobbN3dUdaGamczddny38CyRH5AaSkbXSQj5aaXX1etylg1buslMy9MxJ5iB5hK0xzcPce5ISXwYDFQbn7IwpPeeVJOcmVWdzNgBt_VHqBEZ-1hozdknfDJa7-MFSc2lrpQighILkQTb9bGJDc0T1mbvZiPwnIe4Alvw79xf5FV-lu_g7ll9VxrSFNd2K7mO6i3d4xfbRBoUhilG8W133JMHphkbJNt8kWc4wDTOS58luF8Zxnu3WK75HIVqHmzCO0ihOdkEYhWm8SZKY5DRhIQbrkBWYi8CfB0pfVtyYiu13mzQMV37eMP4XEQgV3BBVlFxgy1UTAHeQKFWq0vKiX3GbPz74Rf7DU5vuYXuSDSmxxOLVcE-UPK703veNrLoYN59wY01vnuVW-N9o-HeHySP8c2QWJLgyjMLMdT4lL_DgxgNTCbuqtNh_uGX5aBjXtHxAnvbovwEAAP__Vjoqbg">