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

    <tr>
        <th>Summary</th>
        <td>
            Take advantage of `assume`s on `x * x` (with `nuw`)
        </td>
    </tr>

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

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

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

<pre>
    Rust stabilized its [`isqrt`](https://doc.rust-lang.org/nightly/std/primitive.u16.html#method.isqrt) method [today](https://blog.rust-lang.org/2025/01/09/Rust-1.84.0.html#stabilized-apis), so I was looking at its codegen.

The output for
```rust
let root = u16::isqrt(num);
```
currently has a manual
```
assume(root <= 255)
```

I was thinking that it'd be nice to give LLVM a bit more specific information, like
```
assume(root * root <= num)
```
since that's (a partial) definition of what `isqrt` *does*, and strictly more specific.

Sadly, that assume today doesn't seem to be worth bothering adding, since `opt` seems like it doesn't take advantage of it even in a "simple" situation that doesn't need to know anything about `num`: <https://llvm.godbolt.org/z/zoq4T5fKr>

But Alive2 confirms that it would be allowed to <https://alive2.llvm.org/ce/z/ko8HYR>
```llvm
define i1 @src(i16 noundef %num, i16 noundef %s) noundef zeroext {
start:
  %_4 = mul nuw i16 noundef %s, noundef %s
  %cond = icmp ule i16 %_4, noundef %num
 assume i1 %cond
  %_0 = icmp ult i16 noundef %s, 256
  ret i1 %_0
}
=>
define i1 @tgt(i16 noundef %num, i16 noundef %s) noundef zeroext {
start:
  ret i1 1
}
Transformation seems to be correct!
```

---

Original Rust code I used to get the LLVM IR: <https://rust.godbolt.org/z/vM8qj4xjf>
```rust
pub unsafe fn isqrt_facts(num: u16, s: u16) -> bool {
 std::hint::assert_unchecked(u16::unchecked_mul(s, s) <= num);
    s <= 255
}
```

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysVkFv2zgT_TX0ZWCDoixFPvigJjW-4muxQDdYYE8BJY0kNhTpkkM76a9fkFLcOAn2tEDiSAxn3pvhm0dL79VgEPes-MSKu5UMNFq3960lmtpp1djuef89eAJPslFa_cIOFHmI-0uu_E9HrOSsuGOiGomOnuU1EwcmDp1tNy54Wmtpho11AxMHo4aR9DMTB08dE4ejU5MidcJNyMrNSJNmIp-QRttt5txiB_N7RCTbyeePsBpth3dggouCiQPP4seOiUOsY51tqu2Gv2D9rmotj8ozsWPiFryFL3CWHrS1j8oMICkV3doOBzQbxmvG6_sRwQY6BoLeurhW8vknMmG81kjgrCVg-R2ErIx083qpqzJhinD5p9eRjNdtcA4N6WcYpQcJkzRB6jebpPdhQiaqJf9thBBFETNe72S8nmuhUZlUDI2pHCZuOmgQjGoRyMKgTghfv_71DSQ0imCyDsEfsVW9akGZ3rpJkrImdkirR_x3SqKG19yWaq9DvDIRe5SRjAcmKglH6UhJHQ--w14ZFSHB9nCOtF9pLkJ0Fj0TdWQkTQeenGpj5664L8f1p-yi8m7n-me2kBQFMY1h4obAI06xGQ3C2ToaobE0oksa6DplhiSPRJuV3B4TkRjkU0tA0atkJB8RZHeShuSAsQZFgCc0oAxIYEJ4NR01MiHAKwqpuzO930kMYhcZPRp7Bmme4zEOIBsbUjdiX0vO8jo2-nootD5Nm8F2jdW0jMSv-Gt_bu-L_v-O5Z_nznwKBLVWJxTQWtMrN_kXkcDZBp1kIrW255nKOySZgjcJcAZqcUF7tNX__v6-QL0cfdzIeJ3OF0FlwLbcu5aJSmUlGBtMhz0wUSTV3MKb1Timl_df6Cw-EbCbOEiepKPIi9cQtz5s0_BNQYMJ5w8S3V6_L2GtNV0KVO10hKAxRaZ8b0IiQ16_yCmWMkdfCPDXeehDBqIo03aHtGR4SJN7cxc_87u5e1fdooH-624t6NkF-d5J4y9Tv6h8no3WOoctMZG9d5v1ej0__OHUoIzUkO6P6J3wBYKfNTQgAY2L4Xz5_qGAo41-IODTt-rnj-3Tj_6NqhbXPYYGgvGyR-gNJLd46GVLfvHcvE5eHOf48ryDNcs_Q2OtXloD8YJKfj0qQ_OT9B4dPQTTjtg-YsdEdXH1y-LDFDQTlZ8BxO6NASa7BwDwr137ctivWrnq9nm3y3dyhfvsJi-3FS-3xWrcF9hnjcyqptj1TSOrpsjKvNmW7Q3vmibPV2ofrz6eZZzn2y0vNn0udn2OyFvBszIr2JbjJJW-TOxKeR9wnwmxzcRKywa1T18JhDB4hvRfJkT8huD2MWjdhMGzLdfKk_-dhhRp3N-_8z1W8uV6KLkHa-LCU7ojnmYnr86KxtnPzrF8sVsFp_fXehgUjaHZtHZa3G35sz46-yPJ8ZCYeiYOSymnvfgnAAD__3I2t6s">