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

    <tr>
        <th>Summary</th>
        <td>
            Potential missed optimization opportunity: 8 byte std::array comparisons seem to be producing different assembly
        </td>
    </tr>

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

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

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

<pre>
    I noticed 8 byte std::array comparisons seem to be producing assembly different from bit_casting. gcc seems to do what I expect for a char array, but clang generates an extra mov instruction. In the std::byte case we get 8 byte cmp. 

[link to compiler explorer](https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DIApACYAQuYukl9ZATwDKjdAGFUtAK4sGIM6SuADJ4DJgAcj4ARpjEEgCcpAAOqAqETgwe3r56KWmOAiFhkSwxcVy2mPYFDEIETMQEWT5%2BAXaYDhl1DQRFEdGxCbb1jc05FQojvaH9pYNcAJS2qF7EyOwc5gDMocjeWADUJltuDcRMAJ7H2CYaAILbu/uYRydRhNe3D2Y7DHteh2ObmQk3wgk%2B9y%2BUVQngOaBYSQamC4EDQDEmB1BIBAZ0uQKxICiFwImFIBwAHNcjmYAGxJMkE3FXE4EokksmUrbYA7EBZfEwAdis9wOop5mAIqwYBySrwAIsc5TzjsKHgKFZD7tDYfDEcRMGZUQIMYziOdmcCEA0OVTzHSGQR0NimUDkFayBSqbz%2BUKvmLxZLiNLZYrFcqtqrBRqHvcAPSxzGsF5MBRKUq0C4HPBUA4XFYHLxKOHurPoklMdAHVA5tmYKEw2hw1AIpFbI1lzGO51mvEsruE4mkz1c6n2ztOnE9i2swc2kfeyG%2BkVi/WB6WswgAfVEkyBXlCBBpkk3BGuECSC3lYY3BG3KdPJ33giPJ7P3ojPrlHCWtE4AFZeD8bheFQTg3GsaxMRWNYXm2HhSAITRvyWABrEAti4AA6clyS4GkNHickBQ0AVJA0LYNBpfROEkQCkNIUCOF4BQQA0BCkKWOBYCQXU6FichKF4%2Bg4j2QxgC4XC2JoWgSWIFiICiej3mYYgLk4eDlIaC4AHkom0DpEOA0h4TYQRtIYDN6KwKIvGAU5aFoFijKwFgxPEDgtFIfB9U6AA3TAnM8zBVA6LwSXU3gDyqejaDwKJzlUjwsHoghiDwFgItIfziGhJQ5UwVyjFiowOL4AxgAUAA1PBMAAd20pJGEy/hBBEMR2CkGRBEUFR1A8nQ9AMErTEsax9DiljICWVAkhqJyAFp5tBRURqsSwzA0A55u0rYQOytKsEmiAlnaTpnAgVwxj8CpghmEoylyVJ0gEK7HvyDI%2Bnu%2BZKmqLopleiYqgMv6ek%2BgZymGHoAchxowbmcoTug9YJB/f86P6hjOAOVRyRpeajzhIbgAOCTMKwzaIFwQgSGpDCFl4QytAWVD0JpTCfhpAVyQ0Mw/3JP8uHiLZyWojhaNIIDPMY5jWPY/rOJgRAUGbJI%2BLICgjQRNWQHEyQKmk2T5MUjHNNUzLTZ0vSDMykzGAIczLIx6zbPsxzMpctyNk87zgf8wLeGC0LwqMqLfwx2L4q0pKvYZtKMqM7LcswfLCuAYrQHlsqmAq6q6oapqjJa4RRHETqi56tR6N0AIiZQCDLHGqIjum2aMgWpbHRW%2BuLA2radr22IDoC%2BATqBs6/Auhh3E8Fo9Fu4pwbe57Mhn8Zkiemo4YewHfoEbpRlX66fuBvepi377Jihw%2B9Ev2G7sXxZllWZHH7DgCJfoxjsdx/HJAOYBkDIBJpIMmBxKb4CIMQWmiwGYcRZhhbCuF8KEWIqRcilFRbi0liBTgMs2KM2QqLMw6Mpa4LlkzJY2U0jOEkEAA%3D%3D)


```cpp
#include <array>
#include <bit>
#include <cstdint>

// produces completely different asm then the other 2 functions
bool compare1(const std::array<std::byte, 8> &p, std::array<std::byte, 8> r)
{
    return p == r;
}

// seems to be similar to bit_casting, but clang generates 1 more instruction
bool compare2(const std::array<char, 8> &p, std::array<char, 8> r)
{
    return p == r;
}

// same assembly if you use char instead of byte
bool compare3(const std::array<std::byte, 8> &p, std::array<std::byte, 8> r)
{
    return std::bit_cast<uint64_t>(p) == std::bit_cast<uint64_t>(r);
}
```

clang
```asm
compare1(std::array<std::byte, 8ul> const&, std::array<std::byte, 8ul>):  # @compare1(std::array<std::byte, 8ul> const&, std::array<std::byte, 8ul>)
        cmp     byte ptr [rdi], sil
        sete    al
        jne     .LBB0_8
        mov     eax, esi
        shr     eax, 8
        cmp     byte ptr [rdi + 1], al
 sete    al
        jne     .LBB0_8
        mov     eax, esi
 shr     eax, 16
        cmp     byte ptr [rdi + 2], al
        sete al
        jne     .LBB0_8
        mov     eax, esi
        shr eax, 24
        cmp     byte ptr [rdi + 3], al
        sete    al
 jne     .LBB0_8
        mov     rax, rsi
        shr     rax, 32
        cmp     byte ptr [rdi + 4], al
        sete    al
 jne     .LBB0_8
        mov     rax, rsi
        shr     rax, 40
 cmp     byte ptr [rdi + 5], al
        sete    al
        jne .LBB0_8
        mov     rax, rsi
        shr     rax, 48
        cmp byte ptr [rdi + 6], al
        sete    al
        jne .LBB0_8
        shr     rsi, 56
        cmp     byte ptr [rdi + 7], sil
        sete    al
.LBB0_8:
 ret
compare2(std::array<char, 8ul> const&, std::array<char, 8ul>): # @compare2(std::array<char, 8ul> const&, std::array<char, 8ul>)
 mov     qword ptr [rsp - 8], rsi
        cmp     qword ptr [rdi], rsi
 sete    al
        ret
compare3(std::array<std::byte, 8ul> const&, std::array<std::byte, 8ul>):  # @compare3(std::array<std::byte, 8ul> const&, std::array<std::byte, 8ul>)
        cmp     qword ptr [rdi], rsi
        sete    al
 ret
```

gcc
```asm
compare1(std::array<std::byte, 8ul> const&, std::array<std::byte, 8ul>):
        mov     rax, rsi
 cmp     BYTE PTR [rdi], sil
        jne     .L9
        cmp     ah, BYTE PTR [rdi+1]
        jne     .L9
        mov     rdx, rsi
 shr     rdx, 16
        cmp     BYTE PTR [rdi+2], dl
        jne .L9
        mov     rdx, rsi
        shr     rdx, 24
        cmp BYTE PTR [rdi+3], dl
        jne     .L9
        mov     rdx, rsi
 shr     rdx, 32
        cmp     BYTE PTR [rdi+4], dl
        jne .L9
        mov     rdx, rsi
        shr     rdx, 40
        cmp BYTE PTR [rdi+5], dl
        jne     .L9
        mov     rdx, rsi
 shr     rdx, 48
        cmp     BYTE PTR [rdi+6], dl
        jne .L9
        shr     rax, 56
        cmp     BYTE PTR [rdi+7], al
        sete    al
        ret
.L9:
        xor     eax, eax
        ret
compare2(std::array<char, 8ul> const&, std::array<char, 8ul>):
        cmp     QWORD PTR [rdi], rsi
        sete    al
 ret
compare3(std::array<std::byte, 8ul> const&, std::array<std::byte, 8ul>):
        cmp     QWORD PTR [rdi], rsi
        sete    al
 ret
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWVmTosj3_TTUS8ZUYLKoD_WQbIKKCm6FLxMsKaSsQiLip_-HS-1VPdXz757-GR1kSy733JPkObfErSoSZhg_MILECMqdW9MoLx-KyCUJhndeHrQPBshySnwcgB7wWopBRQOGQwyH3LJ0W-DnaeGWpMqzClQYp4DmwMOgKPOg9kkWAreqcOolLQjIdotLnFGwLfMUeIT-7bsVJVl4D0Lfv8yuztODHDSRS4EB8LHAPgXbvAQu8CO3BJegDJSBV1PgJ24WghBnuHQproCbAXykpQvS_ABIVtGy9inJs3tgZIBGr7BfMvHdCoMGgxDTp-T8tLgHDKswLLpdBSkhWXyGdc6UJLg8o0ryEpeMoDCwF1FaVOdVocZALcwDL0_ofV6GlxvcieHQ1BmHEdKkfSBY8hE5zcyRTDmV7EAaI61jyT5yZ6qMzFMjURN1kdVo1LSkFtlhf0QtR0VtRTzWekTysSdJaJRL2QKhJdKLBpkHpDmLOR2GHcVABZIdZNVOHSf9DVo0ymgXoIG2pGjEVwPDFOc1Uoa8MgyRv-ORXexUNZT9AqHpHu3VRdhgrhTE0TqdIqJF8bw5-qsWpjNHU1RDXZiWul4IDBSghB5dR4mSjmLZmhoMjrLndXY-K2hWvju4er9wJj4azuFe66rttPGFUDFzf4fXSFkOE1orvm2iYVeHsuMiY-zVDNRqx24DO5pgToFOV9EpjuDUS62Ya8L4ErXfXprlysrCqSs5c8tNZV5VLEVNpY5kSGjD1tboaMhEa4xUM6QG6RN_lzpocByascppjyqv5nFcpcvSc1BXlTZbtUEBqfrNNC-EFBn7xpHaedkgo_KFxWlXjfRwpG2ULlWcraL6tjnYLC3DdE5kGqS-rCJ2ulqc9PnAstkJSZdKrLmtNN97pyva0SEdHzdjMhlvnFLz93RfSvZeP_hoNj-eBpUmmJI9Wu5Zmddn0hLxj5qjj4-jqV6XszxOzADpKyTQ1BmpDYyaDjIKzTM6yWkwFTrpQa3KWuXT-NTxxQye6DRT-wRWjQ_jLW4HFxDxijBQW0viumpCtF2pcSs9JrIkFXHMSYNalecylzgOJw24UTAbclxIZsPujMt3szLR5TVVeaRtsNLzIqxZi5AbVO7RtNcT5zGFejRHxsI-tGsklSqihEdI9JN2zg_iiU78WLJYtBoiduxMpGJrT9XYkuOJsZSnGi9ZFmIlOR6tp5IjW49LUSN-NNL4C_CQ30HrGMr8owyH-Tqcrw2NGDLBOy51nHAc81hJDFfmkR7nKasU6hSxEb9wLJsajjIRR83IOAzQUnC1XCO7UaOFx5mqhFQztlJ_KSLELVBm9k7SConjZv645EKl3eOdqzSj4SlZ7ppKz8OIKI0WGtTYnsggGlrCslm1O43kzXTMo2OIlgh1ZpKJUADZYjhQWwZqkSSppg3leGBL6lKzO6iXWX1kquVCrdxjXyHJzpDXKxRH-2GLtEKgkr2099W8OSEWCULNlo41bemoUlOCksxdFBkKV81x15OLMErVvE3a1ZAN1VFXP7SKceEsqy_NZpTux3mRYOLsQ_Mg4ushCjdtOtBz5EfHvPFSP1_UYd8ZSgzUtj1xJka7KZqu7NYusLs7RYYXoqm8MEfNyTW0xgrng0KRtYS3WorWK4UdFgt5GxVo1Vqs2TBQ44azXq2T8aZd57vInRiGMjMdYbeeOQzUyukwtNFy4A2vYMeGHO4se7K2dLW1RmkMF4K53OmTyfI0XmzYw1wx2_g0QIZ_GhtH8eTNquPJLHzaTuJe9xRue80YD2R23OzN_XjbHOGY37PF6OBs6Mjcm92xXzXbsVwjp7T0pNqnaC_uxdwt9ruhy9u2ri72RBCpLU5YZJCNJStjfbA3dnUKXTNcF55ury9Y6zGCpRuUEBpKLl-FcLGXKpGBGqqjiFN7Wt7Xar5oPCx0zSjrbWKC05x3cKNvc9Ur7ORRFLe1dMAF4brdIYmaq7SpBzjoVo_HTZKsN7reVUJ5uM2Puyo4MlDTh2jqSLFiSMPCMFPpOPJ42TCtdUqagePbmyjy5FrrjdS1sbd9kmi2R9iESIvQrODIhNZ-bDaiWbj8OIlPQwcu2d1UjVWEGChwyu3Sf-N_16vIXv_5RXG7AzmS-UkdYMBw8tWVOfWzPo_QL3r8igYke9V7G3P20VsBgauL7SaY4jcVhFulZ0O_unpOI1wCCLZ1drH76rqQl-fJrTzBHQb2_Dyr6LvyheHkNzXBubLoMZwKGCgW5y_fHF6-0NaVrv8BAIAS07rMQAEYTmE4BZQMJz0NUz5J-rkE8jCoSEoSt7x8eymVvip9OiDNS_y66PlIAvyahHNt9c-5vxn1q1J2U_xSI5ItaPMa1BW-lnvnfLAbgHx7qc8-5sT90Y19mXPbIYaTa5JRkf_78ljDXsHA_hMV_zz6Eu0jX0-n7zV9lwfgXb9bpbfOl6f-G3nWyTnTC4sMFL9JzmXSBS4CgIEcYHj2vwz7vBXnj58Wl_ZSwxe0BIwglQG5FOgyqEjydniFKT637rv7u-xyG9yPJYn9u_e28_w3xfmD3eN5UVyRd4tG5ev-3rcQAgZKoHPD-Qzn1-J7B6wjfh8ZfI_sNYG_nL1bH-S_D5D7EcDXDH4LXHkFUH61tbd-Dn4fIP8nAPI3pfghMuG7yF5t7y8B98nJ-Ayf-KvwPcevyHk94See_-53FeQpMHdT57NBvJFi-JkmPvvpN6Tw7dib8L7V3d8Q45rM0w7vm7wMnjmqCvAX6N0Y-rDrT7S-nfOsyS_jv9rP9wxyf8bM_pOw_465rw7EM3OfFg6h7_9vlA3fVJEnOiRnoYLZwv4Hb3_R0S9odaPzvPerQeniwt9b6hlr8A7rs9QEP7Taj8GfjDb4VNS-G_694AVf-ulHBNwPEPy_SPjKLT9C4H8jCc-W-EMShN9Fwmem9zkJ4s-Q8M5av7K2j1G6P2muz5JyhvD-6B7zNwXmufmhkv8WL_w8c2s9tZWPqvETGvrfus_vyuJZ6--CBy7oc333Dj90up2-wHU7XP8ueuDcPg66XQ5jDnqe4HZ4H_Y4jhMEKPDYZe_IA2Qhz4qwx3Y6sNO_37KsB32PxdDvBLDLMjyLU5ck90lySO_zMrwjVVXjh77Y77N3ievhpLq8aYIwww24dDLwrHx35cN5zl9eHVYMzyakotXLKpTQBD_McoozStwEpKSqcADygpKUnFxK8gzkRZGXtM4Ibc8e_i9fVb3-fen6g8RdXSYP797wEBrV3r2fpwzUziBvzV9Fme-wTxmoXVKrGKhdUz88wP8LAAD__6CD1Io">