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

    <tr>
        <th>Summary</th>
        <td>
            [x86-64] Intermediate llvm.clmul.i32 results get needlessly truncated
        </td>
    </tr>

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

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

    <tr>
      <th>Reporter</th>
      <td>
          8051Enthusiast
      </td>
    </tr>
</table>

<pre>
    [Godbolt](https://godbolt.org/z/4hrKddvah)

Given this LLVM IR
```llvm
define noundef i32 @mod_inv(i32 noundef %m) {
start:
  %_2 = and i32 %m, 13
  %_4 = and i32 %m, 2
  %_3 = sub nsw i32 0, %_4
  %0 = xor i32 %_2, %_3
  %_8 = tail call i32 @llvm.clmul.i32(i32 %0, i32 %0)
  %1 = tail call i32 @llvm.clmul.i32(i32 %_8, i32 %m)
  %_8.1 = tail call i32 @llvm.clmul.i32(i32 %1, i32 %1)
  %2 = tail call i32 @llvm.clmul.i32(i32 %_8.1, i32 %m)
  %_8.2 = tail call i32 @llvm.clmul.i32(i32 %2, i32 %2)
  %3 = tail call i32 @llvm.clmul.i32(i32 %_8.2, i32 %m)
  ret i32 %3
}
```
the x86-64 backend currently generates this code:
```asm
mod_inv:                                # @mod_inv
 mov     eax, edi
        and     eax, 13
        movd    xmm0, edi
 and     edi, 2
        neg     edi
        xor     edi, eax
        movd xmm1, edi
        pclmulqdq       xmm1, xmm1, 0
        movq    rax, xmm1
        movd    xmm1, eax
        pclmulqdq       xmm1, xmm0, 0
 movq    rax, xmm1
        movd    xmm1, eax
        pclmulqdq       xmm1, xmm1, 0
        movq    rax, xmm1
        movd    xmm1, eax
 pclmulqdq       xmm1, xmm0, 0
        movq    rax, xmm1
        movd xmm1, eax
        pclmulqdq       xmm1, xmm1, 0
        movq    rax, xmm1
 movd    xmm1, eax
        pclmulqdq       xmm1, xmm0, 0
        movq rax, xmm1
        ret
```
However, the intermediate results do not need to be truncated, as any garbage bits can only influence the bits at the same or higher position (as it is with other arithmetic operations like addition or regular multiplication too).
I would expect assembly like this to be generated:
```asm
mod_inv:                                # @mod_inv
 mov     eax, edi
        and     eax, 13
        movd    xmm0, edi
 and     edi, 2
        neg     edi
        xor     edi, eax
        movd xmm1, edi
        pclmulqdq       xmm1, xmm1, 0
        pclmulqdq xmm1, xmm0, 0
        pclmulqdq       xmm1, xmm1, 0
        pclmulqdq xmm1, xmm0, 0
        pclmulqdq       xmm1, xmm1, 0
        pclmulqdq xmm1, xmm0, 0
        movq    rax, xmm1
        ret
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsVk2P2zYQ_TX0ZbAGRVkfPvigdOt00fTSQ68GJY4lNhTpkJQ_-usLUitb2Wy3cZEcCkQwYIHvzZt50HBI7pxsNeKGZO9I9rjgg--M3ZQ0S37Wvhuc5M4vaiMugfHeiNooT7JHwsrO-4MjaUXYlrBtO0JLY1vCtn8Rtl119lchjrwjbE1oRWj1Xh5Rg--kgw8f_vgNnn4P6zkdf0ode0IrgXupEbQZtMA9yJQBWdHeiJ3UR8LKsDCBhGU9YWsgxTtCK-e59aEgWkGAdgxI-ghci1Elkn-CJL0SVq8S2BVPI-6GGrQ7RQ4NhBg6kWjknI2dNHZs4twSlZHkuVTQcKUmV8HyslH9oJYyZc_mgmZQuL2vJ53kPpldOdPpZzq7cnmnVDJTSmZK7N6Klsk_13SnGJspsZlSendN7LWaLPppLXxIUjzOu5XQyncI5zJ_yFdQ8-YjagHNYC1qry7QokbLPbqx3xsjcGzNqwJ3od2nxk4r-JeHsHS-E2gFvTlGBPk5GEAhY-HjE7p6Bj53_fj05hjBc9_TWeQ1RMjbPhgfje0Vuq2Grp8FhFQvkpz7PvmytkP8DJ_Ep0nnmTX9089lIs2OPiLlVSfJlyW8kYde83ynBN_GyFc5-PoE383FN_gO8wSvW7DoX2zBX8wJj2gDN-xGqT3aHoXkHsGiG5R3IAxo40EjCvAGagRvB91wjyLEcQdcX6DltuYtQi29g4ZrMFpdQOq9GlA3GOUjxn18d7xHMBY62XZo4WCc9NJoIKzkDqQH6eAkfQfGB5xb6bsevWzAHMJgkEY7UPIjAhdiDDUWLLaD4hb6QXl5ULKJRPDGELZeElo9wckMSgCeD9h44M5hX6vLqBQnzWhxGj_ix9D5L11-477Vqv8HxbeHwosdtRCbVKzTNV_gJilKWq7W-apYdJsip82eUmR5zgvOkoTWaV5mtBH1HstVtpAbRllOc1okOStYsaw5y3ie7-u9EPtin5IVxZ5LtYzHsLHtQjo3YAhjSbZQvEbl4i2UMY0niChhLFxK7SYEPdRD68I5Lp13NxkvvYrX1_EoJtkjPM3HwOfH_nUqtDiOBIXOqcttJCwGqzYvrrbSd0O9bExP2DbeUse_h4M1f2LjCdvGah1h22c7xw37OwAA__9UeStl">