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

    <tr>
        <th>Summary</th>
        <td>
            Missed use of movk on aarch64 when performing disjoint OR with shifted 16 bit immediate
        </td>
    </tr>

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

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

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

<pre>
    I've observed cases where clang emits a suboptimal sequence of `mov` + `orr` or when a `movk` would suffice:

The most straightforward case is as follows:
```
uint64_t foo(uint32_t* raw){
 // load
    uint64_t res = *raw;
    // movk
    res |= (uint64_t)0xfffd << 48;
    // ret
    return res;
}
```

For which clang emits:
```
        ldr     w8, [x0]
        mov     x9, #-844424930131968
        orr     x0, x8, x9
        ret
```

The `mov` + `orr` could instead be a single `movk`.

A related (but as far as I can tell, distinct) case:
```
uint64_t bar(uint32_t* raw){
    // load
 uint64_t res = *raw;
    // movk
    res |= (uint64_t)0xfffd << 48;
    // asr
    res = (int64_t)res >> 3;
    // ret
    return res;
}
```

For which clang emits:
```
        ldr     w8, [x0]
        mov     x9, #175921860444160
        movk    x9, #65535, lsl #48
        orr     x0, x9, x8, lsr #3
        ret
```

Based on a quick scan of the resulting IR, the additional consideration here is that the arithmetic shift is turned into a logical shift (and the constant is made correspondingly larger) before getting to ISel.

https://godbolt.org/z/h95E3zhhd
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzMVU1v2zgQ_TX0ZZCAIvV50MFOYiCHxQLdvReUOJLYUmJKUrbbX78Yym3cFJu9LWoIoGf45mk488RRIZhxQWxZcWDF406tcXK-XdBYPSm_65z-2j4zUZ0QXBfQn1BDrwIGOE_oEXqrlhFwNjGAgrB27iWaWVkI-GXFpUdwA7CSz-7ESg5MHMhy3pPlPLEsoK6Iz-Q8u9VqCOswmB6Z3DNOz98TwuxChBC9MuMUB-fPym_JgAmgAgzOWncO15iSXx--X80Sy_xjhME5JmoypfgYmdiDV2cmGlYdGN8DE0cmjmCd0mQCwI9IjwGYfAQm9hQiD1fANSQlv3kSsnrYwPV3AiYafhmGQQOTD0w-QF7_QuIx_uCIq1-IagOx6vHNkRjfH1P5TD_dNuHXw8P1Z7VP67lm4gFYcbhwVjzeAGZ3SuulSQAh7-o8z0XeSJ7JrCnrG6zzG9mFE_aSKC_NDWA7y5uMqYn_poU-td0sIaLS0CGpySyjxRtt3G80e_BoVURNBe7WmHqvPC3P0KsFIlpLGWkToll6Kn7SyTvK6JR_TxmvTfoujv9VGSr4W46N4DV-cz4x-QTyt1dVVhWNyOqS53me_cRFpfoJWhaFLOi_DZbs_B0JNq9CtMETWv6XHA8qoAZH98-X1fSfIZB43ABxQqrSaqNZRnj-QKTkU1qbaNyiLPRuCUajV2RDugpNgDipuCG9idOM0fQQJjPEtLn6BUni0YEC60bT0z2Ztpmo1aJTKDFHtaSQWWlyeI_hxS2avoevYJUf0ZOmOxycRxgxpkSjg-e_0F6_kinGl9S4JIPR6c7ZeO_8yMTxGxPHqSme5Ldp0jvdSt3IRu2wzao8k01RlsVuavNCN41seFfyvsyElogVz1CpQlZ1NfQ70wouCi55zTOe8eK-FnXDBc9rjUMvsWA5x1kZe2_taaZ370wIK7aZ5LIqd1Z1aEOaPUIseIa0y4SgUeRbCrrr1jGwnFsTYniliSZabP8wgTq4hjRlknyom8r3U5lvo-UF_eD8TOXRJnxyZonw5wc4mzhtpUcNWQmdiWDmGbVREXert-2b8pk4rd1972YmjpTFdbl78e4T0g1zTLkHJo7Xw51a8U8AAAD__9dwIYQ">