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

    <tr>
        <th>Summary</th>
        <td>
            GVN does not handle `readonly` properly
        </td>
    </tr>

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

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

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

<pre>
    Consider the following function:

```llvm
define void @foo(ptr readonly %0, i32 noundef %1) unnamed_addr {
  %3 = load ptr, ptr %0, align 8
  %4 = icmp eq ptr %3, %0
  br i1 %4, label %6, label %5

5:                                                ; preds = %2
  br label %8

6:                                                ; preds = %2
  %7 = getelementptr inbounds { ptr, i32 }, ptr %3, i64 0, i32 1
  store i32 42, ptr %7, align 4
  ret void

8:                                                ; preds = %5, %8
  br label %8
}
```

GVN replaces the definition of `%7` by `%7 = getelementptr inbounds { ptr, i32 }, ptr %0, i64 0, i32 1`, so InstCombine eventually removes the subsequent store, since it is derived from a `readonly` pointer. To the best of my knowledge this is incorrect. The language reference explicitly states: “This attribute indicates that the function does not write through this pointer argument, *even though it may write to the memory that the pointer points to.*” Alive2 also complains about this: https://alive2.llvm.org/ce/z/Lw8eFH

To add a bit of context: I have a Rust project which is affected by this issue. I reduced the problem to this (ugly) code: https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=f4089f905148ea6fb4c28c0cb0c1a076 The program should print 42 (which it actually does in Debug mode and when executed by Miri) but actually prints 0 in release mode. The `foo` function from above corresponds to `Inner::write_outer()`. The issue is present in both rustc stable (1.72.0) and nightly (1.74.0, 2023-09-07), so LLVM 16 and 17 are affected.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVl2P27YS_TX0y2ANmpL18eCHzfr63gWS-1As8hpQ4khiS5EKP7xxf30xlL3rNEWBFlksbIsazpxz5nAkGYIeLeKB7T-w_XEjU5ycP9gphWTHTefU5fDkbNAKPcQJYXDGuFdtRxiS7aN2lhWPjB8Zv31WfP035jyvSwoHbRHOTitgJR-cY6JZogePUjlrLsDEnjPxBLoQYF2yCgda2zHRQrJWzqi-SKU8sPrDmhPofgGsOIJxUsESPSWgrLdk0ujRQnMXX-Z43c8L4NdbbEGxec81sPOgdzmc7hjZoaGr6rur_T3nPSse4R_-seIDLB5VyJiY2Iu7-m9lmvsy1U8tw8S-zosjRjQ4o42kiLYdNSCQ1DdVqS2sPt4JnEXTVQlvbdvd8oboPOalUtztqN9bUt5CPcbsinuSzc8gub_2tPk7Tevjnxx7D-O_n_8PHhcjewzZ-NnEmgwPbgCKJk4Vh-5yu_rXavK_ULPKv4ODZxvik5s7OkJ4RhuTNOYCHmd3vmILqQv4NaGNq_p5p7Y9go6gAyj0-owKBu9mkAT3dvKIwOK0jei38OJytg5DJI7zBX6z7tWgGhHipAOl0rZ33mMft_AyIRhpxyRHBI8DeqSS-G0xutfRXCBEGTFQQ9l_BGs4a59eKI-M0esuRQRtle4pCOIk4zphrnMFlMMA1kV49ToSAu_SOK1IrphB-jGR1mu_H0kfiFOO0xFmebltXqnNODt_ea91S5O_A0S3ZeLxhvUIj0afUYA0wUHv5sVIbQPIzqWYYRCzKcaFfjBxYuIk844tzb6t8yMTpx6ZOP3OxOnja4On_9177MWBVAokdDoL3jsb8VukrM8wyTOChF9SiLB49yv2EV4n3U_UBTkM2EdUZL5rZ0LCLTyDR5V6VCs77zqD80peB2CiSaO50FDtncIf0S9GXrY-hfhAfb0SYMXpjD7kSX8MUXYGmajmnODo0aAMtIBKr0-Do-Bix0Q16hBZcRxK3rRDy_e7skFZDV3Zi6bnfcf7neR1lW20eDd6OUOYXDIKFq9thFIQ4ivnCLK_Oj_7Qls4YpdGICAgrYLXCS3gN-zTVZhP2mvi2qW7zTl1AE4JruBzitXOrMpPp4q_u3A9M507I2Tnh8XReY6Ogp-tRU_yFY_ZZ19ciuiZaJhoWcXXpLk31LXFY6Azqi10Lk5ASvewSkpUd9tabDlBJj5Wj1PMz0a6UW7zPBBcFA-8feA1VVgHxMePnz_BrsqbdjVIj2_-2G7UoVBt0coNHnZVW-72reDVZjrwuqv6tpR1r6qON63qZFs1XHZVVdXVvt7oA9XiLW94XVZltR2GDvsdyqEoSin2HSs5zlKbN7NvMtFDta937SZP25BfK4Sw-LqqwISgtwx_oD0PXRoDK7nRIYb3LFFHgweav28DYJJWGfxhbnm3oDeXTfLm8L2RRx2n1G17NzNxyi8i69fD9SQxccp4AhOnjPePAAAA___I4Lic">