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

    <tr>
        <th>Summary</th>
        <td>
            WRONG code, likely JumpThreadingPass
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            llvm:transforms
      </td>
    </tr>

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

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

<pre>
    [wrong0.tar.gz](https://github.com/llvm/llvm-project/files/14027750/wrong0.tar.gz)
(reduced c test case, should print 0)

runline:
clang -O3 -march=arch13 wrong0.i -o a.out -w -mllvm -available-load-scan-limit=12

The function n() below is called two times in the reduced test case. The first time f[0] has a value of 0 at the start of the function, and a value of 1 at the end. The second time n() is called, f[0] has a value of 1 at the top, while it is then set to 0 by k().
```
long k(long l, int m); // returns 0 

const int *n() {
  for (; C <= 0;) {
    A = (f[0] == 0 ? 1 : A % f[0]);
    f[C] = k(A, 0);
    g = &f[0];
    f[C] = 1 > *g;
 if (f[C])
      return &e;
    break;
  }
  return 0;
}
```
This is the transformation of jump threading:

```
 >     *** IR Dump After JumpThreadingPass on n ***
 > ; Function Attrs: nounwind
define dso_local ptr @n() local_unnamed_addr #1 {                               define dso_local ptr @n() local_unnamed_addr #1 {
entry: entry:
  %0 = load i64, ptr @C, align 8, !tbaa !4 %0 = load i64, ptr @C, align 8, !tbaa !4
  %cmp = icmp slt i64 %0, 1                                                       %cmp = icmp slt i64 %0, 1
  br i1 %cmp, label %for.body, label %for.end br i1 %cmp, label %for.body, label %for.end

for.body:                                         ; preds = %entry              for.body:                                         ; preds = %entry
  %1 = load i32, ptr @f, align 4, !tbaa !8 %1 = load i32, ptr @f, align 4, !tbaa !8
  %cmp1 = icmp eq i32 %1, 0                                                       %cmp1 = icmp eq i32 %1, 0
  br i1 %cmp1, label %cond.end, label %cond.false |       br i1 %cmp1, label %cond.end.thread, label %cond.end

cond.false:                                       ; preds = %for.body     |     cond.end.thread:                                  ; preds = %for.body
 >       store i64 1, ptr @A, align 8, !tbaa !4
 >       br label %3
 >
 >     cond.end:                                         ; preds = %for.body
  %2 = load i64, ptr @A, align 8, !tbaa !4 %2 = load i64, ptr @A, align 8, !tbaa !4
  %conv = sext i32 %1 to i64                                                      %conv = sext i32 %1 to i64
  %rem = srem i64 %2, %conv %rem = srem i64 %2, %conv
  br label %cond.end |       store i64 %rem, ptr @A, align 8, !tbaa !4
 >       %cmp.i = icmp sgt i64 %rem, 0
 > %cond.fr = freeze i1 %cmp.i
 >       br i1 %cond.fr, label %3, label %4
 >
 > 3:                                                ; preds = %cond.end.
 > %.pr = load i32, ptr @f, align 4, !tbaa !8
 >       br label %4

cond.end:                                         ; preds = %for.body,    |     4:                                                ; preds = %cond.end,
  %cond = phi i64 [ %rem, %cond.false ], [ 1, %for.body ] |       %5 = phi i32 [ %1, %cond.end ], [ %.pr, %3 ]
  store i64 %cond, ptr @A, align 8, !tbaa !4                              |       %6 = phi i64 [ 0, %3 ], [ %rem, %cond.end ]
  %cmp.i = icmp sgt i64 %cond, 0 |       %conv2 = trunc i64 %6 to i32
  %cond.i = select i1 %cmp.i, i64 0, i64 %cond <
  %conv2 = trunc i64 %cond.i to i32 <
  %arrayidx = getelementptr inbounds [1 x i32], ptr @f, i64 0, i64 %0             %arrayidx = getelementptr inbounds [1 x i32], ptr @f, i64 0, i64 %0
  store i32 %conv2, ptr %arrayidx, align 4, !tbaa !8 store i32 %conv2, ptr %arrayidx, align 4, !tbaa !8
  store ptr @f, ptr @g, align 8, !tbaa !10 store ptr @f, ptr @g, align 8, !tbaa !10
  %3 = load i32, ptr @f, align 4, !tbaa !8                                |       %cmp3 = icmp slt i32 %5, 1
  %cmp3 = icmp slt i32 %3, 1 <
  %conv4 = zext i1 %cmp3 to i32 %conv4 = zext i1 %cmp3 to i32
  store i32 %conv4, ptr %arrayidx, align 4, !tbaa !8                              store i32 %conv4, ptr %arrayidx, align 4, !tbaa !8
  br i1 %cmp3, label %return, label %for.end br i1 %cmp3, label %return, label %for.end

for.end:                                          ; preds = %cond.end,    |     for.end:                                          ; preds = %4, %entry
  br label %return br label %return

return: ; preds = %cond.end,    |     return: ; preds = %4, %for.e
  %retval.0 = phi ptr [ null, %for.end ], [ @e, %cond.end ]               |       %retval.0 = phi ptr [ null, %for.end ], [ @e, %4 ]
  ret ptr %retval.0 ret ptr %retval.0
} }
~

```

Before (left), `@f `is reloaded for the final icmp in cond.end (%3), which is necessary as the store to %conv2 just above goes to the same address. However, to the right JumpThreading has changed the final icmp to use the %5 value, which does not reflect the stored value of %conv2. This seems wrong and maybe JT has missed the fact that %arrayidx aliases `@f`?

@jmorse @MatzeB @nikic 

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0WVuP4yzS_jXkppTIBud0kYuk8-XbHWn3ffVqpL0cEbviMIMhC7h7ei72t6_AZ3c66cOs1Wo7UPVQUE8VuMytFblC3JD5jsz3E166szabL1r9aa1W8eSos2ff-WS0yqOZ42aW_yLzPaGrs3MXS9iW0AOhh1y4c3mcpbog9CDlY3ObXoz-jqkj9HASEi2hhziJ6HI5jwg9DGHpmkR7Em0JXRnMyhQzSMGhdZByi4Q-gD3rUmZwMUI5iDqF8N-USgqF3qTwO5Vc5TD9g8G04CY9E7b3t5hBPayAqQY-06WD6RNMC28vTPkjF5IfJU6l5tnUplxNpSiEI2wf0_6AX88Ip1KlTmgFitAVoWs4otRPICykXErMwD1pcKJAC0KBOyM0U2snNoMAJIx1QRJOZL6LyHwPZ26BwyOXJYI-QQTcBQjruHG-xfUs8OvDVdZXiBsFVFk1isVUq6waprG4tdUjvDZ2C-X0xcs9nYVEEM5ruzMqsOjAaYjg-Aw_KuRZvViLqP4LP6VWeZAID9KDeW8W3ptsBxWdwKArjbIQQX_FU62sC-KEbhv7yXJX9QKctAHfynbwAIQ9ELaHiLDdSAxgC76L0FU7X8L2QRoIO0AMhG29EJ23K1LZ10H49odaM8xn66cSjcXyeqRFi_MqiB_1__zM8k5GnBorH2obWl2oF8mD4wD1aJD_6LWQ5b55rFWitrftG7np61nY2rngDFf2pE3BA9X1Cb6XxQXc2SDPhMrbkLuKFGblL0K31R_8_S_Ye4TtyaGBL2Vx-dpg_cmtBR9PnXgPxnv20ITc1jnjMxAoXaonobJKMMOTUAiZ1d-kTrmEizNAkqjhS2j8VirFC8y-8SzznGGxJwjcvj6BXJmGyplnb3Hz0HqIzqPAAZ9zQCwSz6Ua_SFEthS5gpV_JDR2R879PfmwYm_gtLgEBOEfrHQeJeB6nfjOkrx23cVtDDgaEHEt7jskP6L0v0_azPz286IRVfYxrT5HWzm2ffuc2A4uBjNbh_Q8eHEo8_twex6Kex5mtOfhU-fhZOTh1YcVh9SIOx_ivz1KwA2p7j186E_3Hu41asQDh_pNLHj0ReOJS4tAlg_1YPcxZlUau44_3Htq-Lf79oVnG3pUvbWVY0veAv8q8ijnAlinDYbYi3sE2N7PDR3E0XRLw7rekVy7aJ-h_mgavom-lt9uzeHDin32a_UYICz-dC1F_SnHr-aHrnuovdENFpWYf6hTJ62srTHuy_Qi6QW3e0HSUaTC_ChPqjCbiV7az90It38oaIPWBI2TQfyFXbzOxDUm1t2V3iBq2eBXcpWo7D3sfI2kbcAO5zK7mE_k2-vhlrxIQb8twmhwf8OC5HcuDKEPwzjKgsTlLCo2zHc9RoxStz_lPgSRuO5tk2Y4KLesJXQ-72B9HFWwcR80EL2DrLxUC7DQU9s5iAGv-tZEc3uF-tYuXixCNLCks3G0Ms0kBhvzK2HWmB4Nx_bZoMqHzpQqbaQXIe8wOvJWjW1RYuoGAenf1hZJZXhvxPCyNcycV0aroashRyrcGP4ssp9BK0eHEgtUzntAqKMulWfZfBfDz2BvtVz96BqbNTye_E9GGHGnSuVh7q1qN-yto9pnAYaG9G2un_PXGRxHH1TrOY996IB6L7sM-Ftc2Ohtolqt-eBt4pYkq95nXjI1CeK_wnYctxANS-_LvEqD5J00uHl9Fv3aqXq4Y1a1gbvvW29VGr9uvXPjurm79PnxW7Dr5Rq-evU34rpw8rJpUIKsWtj2zcbf0Eh62x8ODobukctZ1O4mgQPzHahSyr7OaOtLIryyqdwKus-PlPT3LYOu4WuLfKWtrUt1dav_3CgvVf93ePLhQehK4skRug4GLCKfg_xdWDDoExRmoUoYKqdCcVmlCaGgWxS6qrLFui50pmcQFhSmaC03z8BtXYX1IzrdbXjfS-uAH_UjQq7R-r4gyAsEnmUGrZ3B3_QTPmI4g9T9RuRnN6yChfJreuYqx2xsq9NQWgyt4QgUarSdqZkfWWkHBk9h-25tzbpybmPyDEKdzyIWtiqLhxpywZ-PCF--BjMKYW1jBQ943A32Uy4Ft2ib5fY3dhh4LIm-F9r4010S_YO7XxhIosQPkdb13Um2YdmarfkEN_EyWkQspis2OW_S5WK5SJIsXS1WmCTrJY_5MV7yVRQvcI1sIjY0okkUUxYvWZLQ2Wods2wZzxcxWyx5NPd0LLiQMykfi5k2-URYW-JmuY6X80mIZhs-gFAaPlywbVvvtIT6g8DEbMK3jGOZW5JEUlhnOzQnnMTNv_7645__D6nOgiuk-IHy-WVlc1IauXn3l5NgryX0EEz-bwAAAP__pfPXvQ">