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

    <tr>
        <th>Summary</th>
        <td>
            [AVR] [missing opt] 16-bit operations cause unnecessary register shuffling
        </td>
    </tr>

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

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

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

<pre>
    **Problem**
All 16-bit pseudo instructions incorrectly assume that combined operations must be done on adjacent working registers. This is likely due the instruction set including 3 different 16-bit operations labeled as "word" operations, `ADIW`, `SBIW`, and `MOVW`. Only `MOVW` operates on all working registers, with `ADIW` and `SBIW` operating only on the pointer register pairs, r24:25...r30:r31.

An example of this can be seen with SUBW, a pseudo instruction for subtracting two 16-bit words (as seen [here](https://github.com/llvm/llvm-project/blob/f3d2a31d7d433f9c843a61caa7b025f3b7188ddf/llvm/lib/Target/AVR/AVRInstrInfo.td#L493)):
```
// SUBW Rd+1:Rd, Rr+1:Rr
// Subtracts two 16-bit values and places the result into Rd.
//
// Expands to:
// sub Rd,   Rr
// sbc Rd+1, Rr+1
```

**Reproduction Example**
When doing single 16-bit operation, we can force the bytes to be out of order using a byte swap. This should be dealt with by shuffling the operands of the `sub` and `sbc` instructions.
LLVM-IR:
```
; Function Attrs: mustprogress nofree noinline nosync nounwind willreturn memory(none)
define dso_local noundef i16 @test(i16 %0, i16 %1) unnamed_addr addrspace(1) #1 {
start:
  %2 = tail call addrspace(1) i16 @llvm.bswap.i16(i16 %0)
  %3 = tail call addrspace(1) i16 @llvm.bswap.i16(i16 %1)
  %_0 = sub i16 %2, %3
  ret i16 %_0
}
```
AVR Assembly:
```
test:
    movw r18, r22
 mov r18, r19
    clr r19
    mov r23, r22
    clr r22
    or r22, r18
    or r23, r19
    movw r18, r24
    mov r18, r19
 clr r19
    mov r25, r24
    clr r24
    or r24, r18
    or r25, r19
    sub r24, r22
    sbc r25, r23
    ret
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVl2P2rwS_jXmZlSU2AmECy7gpUgrteoR7dlerpx4Am4dO_LHUv79kZ2whGV7cfRKEcST8TPPfNrcOXnUiGtSbkm5m_HgT8au62CPaKUW8lWKwNWsNuKyJnRD6OY_1tQKu2FBsh3JNhulIF98qqWH3mEQBqR23obGS6MdSN0Ya7Hx6gLcudAh-BP30JiulhoFmB4tH3S74DzUCMJoBKOBi1-8Qe3hbOxvqY9g8SidR-vm8OMkHUgHSv5GdQERIi5ObYNDH82rIOJeBkK2LdqIN_KdmFa8RoUCuANC6dlYQSidKBD6D5BFttk9_SSLbFx9376tuBZR8vXbc5TM4ZtWl4lgREKX3FLq0aMIcpb-NLFyBR3NXNnoI5iIbnTyuDdSe7RvSNBzOcBZWhC2oeV8PrcsI2xjWT4fkjamTgP-4V2vEEwLPka04TpmwCHqgc73_25_Jgc_yC60xoILtbe8Sbz82VxjG0MYY1lxN6CRcntCi6TcEVqdvO8dYRtC94Tuj9KfQj1vTEfoXqnX69-n3ppf2HhC97UyNaH7lgnKWS6WomCsXTVVwfgibzhf1hktW1Yv86oSop3gyLjvB7dHjDib58Pw-xTdeNKtmXtBKPtSrBihq_iwMToxs8MzLBPVFA84CEK3OWGb-PIPHOx1ae91x9C4aWBeuQroUm57xRt0KYsWXVCxXL2Bg5hPYe4gP__puRYOvLnxHL64UMNAB-AdD1c3V8o3th_6OO6KzwF7a8SY6M9DmUz7_ucJNQgT0-6kPip86KpU0phKqjW2GRq0vsQu8CZWmQk-Fp6xAi2EiAI8KYA7837scXcyQYk0FpArP1RlfQF3Cm2rUtWdcDAaA5MKGWPbuFBPmsjVTVxNZ9MY5S9fnr9-ejr8Ne9sC_ughzhsvLexbtOo6q05WnQOtGktImgjtZI6vriLbkCboM9SCzhLpSz6YDV02Bl7IbTSRmOstmRDYBv3CWdelGm4SlsFtiDzBZAi8-g8oVVa0TINnPE9J3QFQWveoXjhQliIP67nDRJapa-EshzIcjuYcp5b_-YrRAwKhO3Ac6mgibPpAWFkETtqXqfUyHxxx2c1gWP_Ei6_h3vJEl4s71GBpvFLS3bVsnHQD99erllb7j7M5ub5ABvnsKvV5W8ZT9G-RQigM69nsHk1DFU6fujM65swX920G2XvBUmRsvvdV8WpwAzrBFi9E7MHO_esinf23hP7C6vyYffAqnhnvviYVfnAKubpqj71Lc6gN3PsJrfo3yVhJtZMrNiKz3CdL7M8L8ssr2anNeIi4zkuqgqrZVs3WbHMC1oslxlmRd3WM7mmGWV5TqtsmTFWzcuqyDDjRV2uqrapOCky7LhU81R7xh5n0rmA6yVb5MUs3QFcug1RqvEM6SOhNF6O7DqdSHU4uli70nl3Q_HSq3SNisdLuYtnXSddGmim91HyeONoeHAYWxcbdI7by-0Efxtts2DV-v8-KxNtR-g-ufW_AAAA__9N8PIJ">