Closed lukeg101 closed 1 year ago
@llvm/issue-subscribers-backend-powerpc
I would argue that perhaps the unconditional branch to the next statement is not needed either, so replace b .next_label; .next_label: isync
with lwsync
My Arm colleagues mentioned this may be of interest to you @nemanjai 🙂
Linking GCC discussion as there are two proposed solutions in it: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111246
I'm sorry - there was a bug in the translation tool. LLVM is correct. I will think twice and check everything before I submit another bug.
Consider the following litmus test that captures bad behaviour:
where 'P0:r0 = 0' means thread P0, local variable r0 has value 0. [x] means x is a global.
When simulating this test under the C/C++ model from its initial state, the outcome of execution in the exists clause is forbidden by the source model. The allowed outcomes are:
When compiling to target PPC64le with clang trunk
-c -g -O1 -pthread --std=c11 -ffreestanding -mabi=elfv1
(https://godbolt.org/z/xj9W7nr9G), the compiled program has the following outcomes when simulated under the PPC model:which occurs since the
b L0x50; isync
pattern allows the memory effect of the load of y on thread P1 to be reordered after the store to x on P1. We observe the execution:{ P1:r0=0;[x]=0} -> P1:W[x]=1 -> P0:W[x]=2 -> P0:W[y]=1 -> P1:R[y]=0 -> { P1:r0=1; [x]=2; }
where the local variable
r0
is stored in register r9 in the compiled code.The problem is isync forces the instructions to finish, but not their memory effects. Hence the forbidden outcome { P1:r0=1; [x]=2; } is allowed under the ppc model.
We have observed this behaviour with several hundred Message Passing and 'S' pattern tests (the above is an S pattern test).
To fix this, we advise replacing the isync with lwsync to forbid the buggy behaviour:
which no longer allows the buggy outcome under the ppc model:
I'm happy to discuss this as needed.
I have reported the same bug in GCC.