<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">