<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/60683>60683</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Integer range checks should lift outside of lossless truncations
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
scottmcm
</td>
</tr>
</table>
<pre>
I was experimenting in Rust with implementing the ASCII versions of certain unicode predicates in terms of an implementation on ASCII bytes, something like this <https://rust.godbolt.org/z/c495YKTsM>
```rust
pub fn demo_is_ascii_digit(c: char) -> bool {
if let Some(c) = AsciiChar::new(c) {
c.is_digit()
} else {
false
}
}
```
Unfortunately, that optimizes much worse than checking against the 32-bit type directly:
```llvm
define noundef zeroext i1 @_ZN10playground19demo_is_ascii_digit17h37e7c57418c2459fE(i32 noundef %c) unnamed_addr #0 {
start:
%_4.i = icmp ult i32 %c, 128
%_7.i = trunc i32 %c to i8
%0 = add i8 %_7.i, -48
%1 = icmp ult i8 %0, 10
%.0 = and i1 %_4.i, %1
ret i1 %.0
}
define noundef zeroext i1 @_ZN10playground18std_is_ascii_digit17he953dd4cafd53a1eE(i32 noundef %0) unnamed_addr #0 {
start:
%1 = add i32 %0, -48
%2 = icmp ult i32 %1, 10
ret i1 %2
}
```
Alive2 confirms that converting the former there into the latter is legal: <https://alive2.llvm.org/ce/z/_vhQJE>
But opt seemingly can't do it today: <https://llvm.godbolt.org/z/zdsEsvrsP>
Perhaps the way to get there would be to do something like this:
```diff
start:
%_4.i = icmp ult i32 %c, 128
- %_7.i = trunc i32 %c to i8
- %0 = add i8 %_7.i, -48
+ %0 = add i32 %c, -48
- %1 = icmp ult i8 %0, 10
+ %1 = icmp ult i32 %0, 10
%.0 = and i1 %_4.i, %1
ret i1 %.0
```
Since alive2 says that's legal <https://alive2.llvm.org/ce/z/bETvXP> and after that other existing optimizations can get the rest of the way: <https://llvm.godbolt.org/z/aEhThW96M>
I tried to make a C++ repro as well, which came out with a slightly different, but still suboptimal, output: <https://cpp.godbolt.org/z/r5xGxa8bc>
```cpp
bool is_ascii_char(uint32_t c) {
if (c < 128) {
auto b = (uint8_t)c;
return (b >= (uint8_t)'0') && (b <= (uint8_t)'9');
} else {
return false;
}
}
```
```llvm
define dso_local noundef zeroext i1 @_Z13is_ascii_charj(i32 noundef %0) local_unnamed_addr #0 {
%2 = icmp ult i32 %0, 128
%3 = and i32 %0, 254 ; <-- the comparisons got widened, but the `and` didn't disappear
%4 = add nsw i32 %3, -48
%5 = icmp ult i32 %4, 10
%6 = select i1 %2, i1 %5, i1 false
ret i1 %6
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUV1tv47oR_jX0y8CGREm-PPgh8TpFWpzitLtFLy8GRY4knqVIgaTieH99QUq-e_ckQeAo1Dcz5PCbb8bMOVlrxDUpnknxZcJ63xi7dtx43_J2UhpxWL_CnjnA9w6tbFF7qWuQGv7ZOw976RuQbafw-MY3CE9fN6-v8IbWSaMdmAo4Ws-khl5LbgRCZ1FIzjy64MqjbSOM6bMz5qXRYPTorTx4dIRuwJkWfRNCKfkdwTfSAck2jfedI9kToS-Evtje-VltRGmUnxlbE_ryg9AXnq-K__7tm_uNZFuSfCHJE5knw2-wGJa6voRKg8DW7KTbMcel3AlZS0_okpPsCXjDLKErmJJsC6UxCsjieTAGAJAVKPTw1bQYLegKSPYFnoKjTTDNnkj2pHF_entpHX74TLpTSEJX57dk8QVQObywqZhyeIUYj3Z6OJ5x_Dd-_ktXxvpeM4_qEPLqG-bBdF628gc6aHvewN5YF1LMNPAG-feQdVYzqZ2PF53RaSk9-EOHIKRF7tUhnO46rFJv7bAksJIaQZteC6zgB1qD7x5kCiRPdv_7e5p0ih1qG96nqwc3kC6abIELXizydMlpXqyqLaFLmdGTU0KLmNRea9ai2DEhLBCaJeeUOc-sP-0Tgskun8l4S5K3HfTKQ_A5-NpASpcjNkAXI9TbXvMTDrwBubxwmUQQEwLk8mgXnE3zS1R6EzVCkxg0uYDNRm9axGwNGw6o4OKIs-jHt7PklgOfz__SeXGfflwVmRA5Z5UoMpbig_Qnn09_es7VkM7kPlP04f2k16k6p4B-pAqelHxDCtzoSgYNikXAjX5De1KzytgWbXi0CFJ7E1cV8x4tSAcKa6aCLNypEIveZ4H_owhxHJVo99b846_bswzFz-c-ViA4xFbqWh2AM03owoMwEOrMCHZ4GCmGuNe7H8Jt3Zt1v98E-h1twzoXD7Jnh0DdGv14xL3plYASw6owj_T2vsSFrKrxCm5v9xPVNYUP1tf0YwVG6PMt8CLsCTb9YCEe3d0iLxh7JuKHi_ZR1V5T9avUHGEgEzh2GGhK6GLk3qeIV26_vf0n8CFui1U-UjtIf7h9wHfpIvPHThC7sAs8PDIELDofmvVIns_wkW2bb82_V_Pfbvj4Ct5KFOGKW_YdgcGG0OeQb4udNcAc7FGpkLp9I3kDnLUIph8HEAZOybrx6gCBiGhR-4Atew_OS6XA9WU8EIs-TO-73j_cOO-6B_u2xftf3tmy5PdzA--6YSXOASe5HEaEZS-1z-jOw32fl0ErlzxsIVbAozmA9d5AGUk0OlvuPKErTrIbpEXfWx1QAb69syB0kRC6iFHonND5Ebp5BF0N0HOUB2PHdeBhCLnE_4n8_nQ4EM7slOFM_bRNpdlVmv_4SQeKTna_6EO_6CrJddcPS9m5li8wtMjj0JU9h1xOp7EquGk7ZqULlVObQFKBGsWRkgFC5gnTgswTEFKMGi8d6zpk9iJoflIu7fbHwNl9byweniK_GyPmEedQIT_3SboZH4vx8WqiPMvT_GdXOhHrTKyyFZvgOp0v5ul8tUiWk2bNKrritOTVXJQ0yUUqqqKqSiHKghVFlkzkmiY0S2hKE5qn-XLGVshZWeQUyyKZp5zkCbZMqpOWTaRzPa7nyXyZTRQrUbnjtxe7DqBp2deO5ImSzruzmZde4fpVe6zRgmW6xmGmdeCa2PGUrHyQBicFBn1TxjmFzg19aBDCSW_V-loxaumbvpxx0466N_6Zdtb8gdwT-hK37Ah9ibv-fwAAAP__9hrh0A">