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

    <tr>
        <th>Summary</th>
        <td>
            [X86] Bad mulhi codegen
        </td>
    </tr>

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

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

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

<pre>
    From https://github.com/rust-lang/rust/issues/130782, consider these two functions that only differ by the constant in the mul:

```llvm
define void @ok(ptr sret([32 x i8]) %ret, ptr %a) {
entry:
  %0 = load <16 x i16>, ptr %a, align 32
  %1 = and <16 x i16> %0, <i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767>
 %2 = zext nneg <16 x i16> %1 to <16 x i32>
  %3 = mul nsw <16 x i32> %2, <i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000, i32 -1000>
  %4 = lshr <16 x i32> %3, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
  %5 = trunc nuw <16 x i32> %4 to <16 x i16>
  store <16 x i16> %5, ptr %ret, align 32
  ret void
}

define void @bad(ptr sret([32 x i8]) %ret, ptr %a) {
entry:
  %0 = load <16 x i16>, ptr %a, align 32
  %1 = and <16 x i16> %0, <i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767>
  %2 = zext nneg <16 x i16> %1 to <16 x i32>
  %3 = mul nuw nsw <16 x i32> %2, <i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000, i32 1000>
  %4 = lshr <16 x i32> %3, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
  %5 = trunc nuw nsw <16 x i32> %4 to <16 x i16>
  store <16 x i16> %5, ptr %ret, align 32
  ret void
}
```

These generate:
```asm
ok: # @ok
        mov     rax, rdi
 vmovdqa ymm0, ymmword ptr [rsi]
        vpand   ymm0, ymm0, ymmword ptr [rip + .LCPI0_0]
        vpmulhw ymm0, ymm0, ymmword ptr [rip + .LCPI0_1] # [64536,64536,64536,64536,64536,64536,64536,64536,64536,64536,64536,64536,64536,64536,64536,64536]
 vmovdqa ymmword ptr [rdi], ymm0
        vzeroupper
 ret

bad:                                    # @bad
        mov rax, rdi
        vmovdqa ymm0, ymmword ptr [rsi]
        vpand   ymm0, ymm0, ymmword ptr [rip + .LCPI1_0]
        vpmovzxwd       ymm1, xmm0 # ymm1 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
 vextracti128    xmm0, ymm0, 1
        vpmovzxwd       ymm0, xmm0 # ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
 vpbroadcastd    ymm2, dword ptr [rip + .LCPI1_1] # ymm2 = [1000,0,1000,0,1000,0,1000,0,1000,0,1000,0,1000,0,1000,0]
        vpmulhuw ymm0, ymm0, ymm2
        vpmulhuw        ymm1, ymm1, ymm2
 vpackusdw       ymm0, ymm1, ymm0
        vpermq  ymm0, ymm0, 216 # ymm0 = ymm0[0,2,1,3]
        vmovdqa ymmword ptr [rdi], ymm0
 vzeroupper
        ret
```


</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWEuT4yYQ_jXoQo2Lh14-6BDb66pU5ZBDDrmlkEA2GQm8gPyYX58CybZkK5Ns1dZmp7KqmRE03S2-7uaDgVkrd0qIAiQrkGwi1rm9NoWSr7KKSs0vxdboFu6dO1hAfwJkC8h2J92-KxeVbgHZms66l4ap3dAGZCut7YQFZIspynICyBpWWlnJhYFuL6yA7qRh3anKSa0sdHvmoFbNBXJZ18LA8uL1gpFjykGpQr_tGj8HtAHo-jdF_U_THNtexEUtlYBHLTkEMdKvgOQHZ6A1wgGSg2RFCTxDmYNkA8gSApKEkTX0WoAkLEizVe9OKGcut69Cr4AgoBvYaMYhoGucem84BfTT1MkaskbuFKRkZIuDLVOPpsGvtwF0LXEKKcnSzPc_eod-GtADkpAA_k2cHVRK7GZCgKHTdzEld3M_SoN92zVQ2dODWvB_DSAl8AUjFAL60TuTCMR96dm9mYFPR_BxevXynbUmcJIAx5lOVVB1cymNJwUxsbdOGzFTQ8loGQ4r-3EhGuECQQwkkm3GnPJAICXjPxjku2CQr0wh3elf0Mh4PX6o9v-JNubT-G2p43oQGTPJb-GssxNKGObE_ehy1WV2OLPoV0D9DkmHE8vwrf5p9TG8DTv7CRkuh_Fjq4_8M4OXtg25v7TtSRveA0hWxkpPUBNfx4MnDjg2mTWVBwjICi5-Wf_6M_oDzfhpu2Z_-kI_GCSbHmWySuOE-gT_N-8bnlEMJxPnIXZXZFPsb8Lo7nAQZpD7Shll3W8Y9Kb93jMk3Bs8Zfwp29evf5uk4_mk6-Pb-cSH_qVtsfdzblsUsHhBWJpeApIV6mPo4wXIehDiOSGZE9I5YTwnTOaE6ZwwGwmHChBnZ1jlJCa5R3V-iBL-xyCgxyCgjxeEQ2k04xWzjg-owi7I3ymQ22r2ygGxB9bvQ_73Kzbn6aeb5R_yN6oPRTt6k1sQWPXaWX56SO1I9ZEKDsK0n59XFsHptBYu11ogax9X744-o_oCLnoioeG5c9HchhTxgvIlXbJIFDgjGc5RvsyjfVHVWR4jliYM1ThLU1Yvy5zhEtW0wmmJI1kQRGK0JDEmJMf5IqnjirEE8zSlOMtrECPRMtks_H_iC212UbgFKDBaZksUNawUjQ23DIQocYJhFBBf85EpvNFL2e0siFEjrbN3N066JlxP_J77YoYrxv35bS9hpbnYCRV1pineuaAIVwP96-Vg9J-imt5R9BM8FuSvAAAA__8ZnkzR">