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

    <tr>
        <th>Summary</th>
        <td>
            [clang] Miscompiled atomic ordering at -O1 (clang-14 onwards)
        </td>
    </tr>

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

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

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

<pre>
    Hi LLVM,

please have a look at the following code:

``` cpp
#include <utility>
#include <atomic>
#include <cstdint>

std::pair<std::size_t *, std::size_t> load(
    std::atomic<std::int64_t>& m_beginChange,
 std::atomic<std::int64_t>& m_endChange,
    const std::pair<std::size_t*, std::size_t>& p)
{
    while (true)
    {
        std::int64_t changeNumber = m_endChange.load(std::memory_order_seq_cst);

 std::size_t *array = p.first;
        std::size_t length = p.second;

        if (changeNumber == m_beginChange.load(std::memory_order_seq_cst))
        {
 return { array, length };
        }
    }
}
```

At -O2 clang-13 and onwards generate the following code:

``` asm
 mov     r8, qword ptr [rsi]
        mov     rax, qword ptr [rdx]
 mov     r9, qword ptr [rdx + 8]
        mov     rcx, qword ptr [rdi]
 cmp     r8, rcx
        jne     .LBB0_1
        mov     rdx, r9
        ret
```

This looks correct to me in regards to ordering.

At -01 clang-13 generates the same code.

Starting with clang-14 we get the following code generation at -O1:

``` asm
 mov     r8, qword ptr [rsi]
        mov     rcx, qword ptr [rdi]
        cmp     r8, rcx
        cmove   rax, qword ptr [rdx]
 cmove   r9, qword ptr [rdx + 8]
        jne     .LBB0_1
 mov     rdx, r9
        ret
```

This looks wrong to me. The loads from the pair have now been reordered to after the comparison. If I am not mistaken that is against sequential consistent ordering rules which prevent any reordering across atomic operations (read,write,modify).

Indeed, at -O2 clang-14 and later do again generate the what I believe is the correct code as shown in the first snippet without the conditional moves.

Can you confirm whether this is a bug or indeed allowed by the standard?

Please see here for a godbolt link: https://gcc.godbolt.org/z/1MW6e6dh6

This originally came up in an Aeron issue. See https://github.com/real-logic/aeron/issues/1411 for more details but above should be the minimal example.

Thanks,
Stephan 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0Vttu2zgQ_Rr6ZRBDohzZfvCDLzU2QLtdoMXuYzASxxIbilRJKq779QtS8jVJL8CuEdiINDM8M-fMDNE5WWmiBbtfsfvNCDtfG7v45KmtUW-MUgXZalQYcVj8IeH9-78_ML5myYYly_67VYSOoMZnAgRlzBOgB18T7IxSZi91BaURxLLlpRvLk_4PyrYdHvFM6lJ1goBl685LJf2BZe9ee4veNLJ842XpvJDan9_Gb-dFwJAtW5SWZevT_05-p0cPjC8ZX8PNY5a9A2VQMD7rwwDA2eYI4xxMap9PohvjOTSPBVVSr2vUFZ0K9zv-pMWtNwCURjsPP8nozYRC5Jbx-VCd6eoceF9LRcD4zNuOTibhzZXZVREGyFBGnH92TUEWWLa5RD8eanhyaqgx9vBorCD76OjrY-l8OC9bXXJ2Cz6QhNbiIcZvxztpnT_5vEA2OCnSla8HF0el0eL2nOEjdyH320T6XC6Y_OVsLgt4XURLvrM6PICYUGDqiHO6eZFSeHZBxeZI3eammy6TWnq4-8ihVKiruzQD1AKM3qMVDirSZNHT7zQqumbA0JjniMrOAuyve2MFtN4Cu19ZJ9n95hr8yRy_vbQX3872J8P5a3bA-Apmb0cvX4t-gaZs2gvUwfwqzhdN8Xf8frVKHtM3DhHxEHvDqyX_AyI-19LFyeigNNZS6cEbaAikBktVJMQbiOqRuhrfkpikZxKPxLnInMOGImlXPp88Wh_o3EtfH10nsCeo6LXRfAwqjQ6z--5j-j9q4GcsDZ-fkFU25pl-RVInw9-R1OtS-K80sLdGV70CxvC5prhfHOysaSI5YZr3-1SbPRREQSVRHCSCG-482WhZmqZFK53RY3jYwQNgA9p4aKTz-EQafI0epAOsUMaNQV870l6iiitEOk_an4QHtlPkwg4oa2gtPYeXqA_H44MJltY4B_3iAtMOunFhbloKU3G9t9KHddUYIXcHxudX4nzQgiiY9VLjZ32G-aQw5CZMj_h6TO1DMg9QkJL0TCGtvgZ9R0UhowNXm70OnRV1HvYDOC3blnxsB9P5wU0LGZCjCsSSuwK5Rg0H0wWrnbQN7GvydSy6dLGeUHQVGAsyZgMY2okEFIe-LT1qgVawbHsZ9a_-quSIoCYbutACQmVEYZQHJfUTy5ZQe9-60IB8y_i2KsvxYDE2tmJ8-53xbfrhn5xyUecvJGasrKRGpQ5QhuHQtaEWqGFJ1miQznU0hk8BwvU50tddMS5Nw_jWEqo7ZSpZMr7F4Mj4Nrq6cPgkTSP2xlgCQR6lclB0HrAIzeZq0ykBRc9aI7VsUAF9w6ZV14Pqc436yZ1uNsOtE0ZikYl5NscRLdJ8OklmSZrPR_VikuM0zXJKc5wWYor3yMU9ZiIT5XSaTNKRXPCEZ0mazjhP82Q-niGSQMxnu52YpzNkk4QalGqs1HMTCjqKaS3yJM3SkcKClIt3Yc417ftyMc7D1dgugs9d0VWOTRIlnXfnKF56FS_RUc3sfgMfpAvtKVWQx9AtpyaKQzZeNY7iHxYz4_NRZ9XiB-SEM4efu9aaL1T6S3ZiJv8GAAD__0GwkEk">