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