<div dir="ltr">This sounds exactly like the right thing to do. FWIW PNaCl provisions for this at the moment.<div><br></div><div>I haven't reviewed the patch, but your proposal sounds good.</div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Fri, Mar 7, 2014 at 5:47 AM, Tim Northover <span dir="ltr"><<a href="mailto:t.p.northover@gmail.com" target="_blank">t.p.northover@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi all,<br>
<br>
The C++11 (& C11) compare_exchange functions with explicit memory<br>
order allow you to specify two sets of semantics, one for when the<br>
exchange actually happens and one for when it fails. Unfortunately, at<br>
the moment the LLVM IR "cmpxchg" instruction only has one ordering,<br>
which means we get sub-optimal codegen.<br>
<br>
This probably affects all architectures which use<br>
load-linked/store-conditional instructions for atomic operations and<br>
don't have versions with built-in acquire/release semantics (and so<br>
need barriers). For example on ARMv7, an "acquire, relaxed" cmpxchg<br>
currently generates:<br>
<br>
        mov r9, #52<br>
        mov r3, #42<br>
LBB0_1:                                 @ =>This Inner Loop Header: Depth=1<br>
        ldrexb r1, [r0]<br>
        cmp r1, r3<br>
        bne LBB0_3<br>
@ BB#2:                                 @   in Loop: Header=BB0_1 Depth=1<br>
        strexb r2, r9, [r0]<br>
        cmp r2, #0<br>
        bne LBB0_1<br>
LBB0_3:<br>
        dmb ish<br>
        [...]<br>
<br>
That second barrier could be skipped by the first "bne" if we knew<br>
that the user didn't need any ordering in case of failure.<br>
<br>
The other atomic operations are not affected, so I'd like to add a<br>
second ordering operand to "cmpxchg" to support the full range of<br>
possible requests. The suggested syntax would be<br>
<br>
    cmpxchg [volatile] <ty>* <pointer>, <ty> <cmp>, <ty> <new><br>
[singlethread] <success ordering> <failure ordering><br>
<br>
That is, syntactically I propose:<br>
  + No comma between the two<br>
  + Both operands are required, even if "failure" is the natural pair<br>
of "success"<br>
<br>
Semantically, I would like to enforce the constraints in the standards:<br>
  + failure <= success<br>
  + failure != Release<br>
  + failure != AcquireRelease.<br>
<br>
Before the DAG, I suggest completely removing getOrdering from<br>
CmpXchgInst, in favour of getSuccessOrdering and getFailureOrdering to<br>
avoid errors. In the DAG, getOrdering would still exist and return the<br>
success ordering, which I believe would make existing targets<br>
conservatively correct. AtomicSDNode would add getFailureOrdering,<br>
used only by ATOMIC_CMP_SWAP nodes.<br>
<br>
Existing bitcode files would obviously be supported, and retain<br>
current semantics by BitcodeReader dropping the "release" part of any<br>
single ordering, and using the result as the "failure ordering" (as<br>
currently documented in the LanguageRef).<br>
<br>
I have attached initial patches for reference, but I'm not asking for<br>
thorough review at this stage.<br>
<br>
What do people think?<br>
<br>
Cheers.<br>
<span class="HOEnZb"><font color="#888888"><br>
Tim.<br>
</font></span><br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div><br></div>