<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">