<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/76524>76524</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
x86 missed optimization for trunc i32 to i16 or i8 when ConstantRange of source already fits in destination
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
MitalAshok
</td>
</tr>
</table>
<pre>
An unnecessary zeroextend / signextend is emitted to zero bits that are already assumed to be zero.
For example:
```c++
void take_u16(std::uint16_t);
void u32_to_u16(std::uint32_t x) {
__builtin_assume(std::in_range<std::uint16_t>(x));
take_u16(x);
}
```
Emits an unnecessary `movzwl %di, %edi` before the tail call. GCC optimizes this to just jump to `take_u16`.
https://godbolt.org/z/qE77z3a7d
This optimization can also be done on other targets
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJxsU01zozgQ_TXi0jUu0ZgPHzh4nLCnvWzt3SVQY5QRkldqEse_fks4tSHZqVIBovt1v6enVjGaiyNqRflTlE-ZWnjyof3TsLLHOPlfWe_1e3t0sDhHA8WowjvcKXi6MTkNAjtYSzy2JgLNhpk0sF_zoDccgSfFoAKBsoGUfgcV4zI_snpaE3dCPgl5fDw7H4Buar5aEsVxGxGVfKxB4M-01r-v3mhg9YvOS14JbCLrhCuOi3GcV2cWeBDFNnkp8Mz-d-kpADeBBxD1BwLO534xlo07P4hvMcadg3IXEsXp_22LZ4FNKrYlsGV62wZE_fRN5Vb685yOUn31QlRy9q_3NwsgsNRG4Cl9kDaiktDT6AMBTwSsjIVBWbuDP04n8Fc2s7lT8sbE5MPLEhlelvmaNqKS_5Gs5BdvJuZrTDKxE9hdvO695Z0PF4HdXWD3z3Nd3wtV6y3o79Tko6di4x0MyoGycfVfe0fgHXieKACrcCGOmW4LfSgOKqM2r2VRN02Zy2xqD2NejbIoUfaYY14NuO9pX9Uo-xwb0plpUWKRIzZ5U5Sy3u2rsq9Gpcd6OBSktdhLmpWxO2tf50Q9MzEu1NZVifvMqp5sXEcC0dEbrEGBmCYktAnzo18uUeylNZHjZxU2bKm9NRXMJkbSXxWPPgCHxQ1gCkyHbPIKfADTwNtEDk7eRVaO_0q3CfwI0S9h-JyZMdlvHGiKbNxaM1uCbb8ZYnha-t3gZ4FdYvbx-nEN_oUGFtiteqLAbtX7bwAAAP__7sBCnA">