<div style="font-family: arial, helvetica, sans-serif; font-size: 10pt">FTR, here is test generator:<div><br></div><div><div><font face="courier new, monospace">package main</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">import (</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">       </span>"fmt"</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">   </span>"os"</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"text/template"</font></div><div><font face="courier new, monospace">)</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">func main() {</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">  </span>fmt.Print(header)</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre"> </span>for size := uint32(0); size < 5; size++ {</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>for _, order := range []string{"unordered", "monotonic" /*"consume",*/, "acquire", "seq_cst"} {</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                        </span>output(loadTempl, size, order, nil)</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">               </span>}</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>for _, order := range []string{"unordered", "monotonic", "release", "seq_cst"} {</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                        </span>output(storeTempl, size, order, nil)</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">              </span>}</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>for _, order := range []string{"monotonic" /*"consume",*/, "acquire", "release", "acq_rel", "seq_cst"} {</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                        </span>for _, rmw := range []string{"xchg", "add", "sub", "and", "or", "xor"} {</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                                </span>output(rmwTempl, size, order, map[string]string{"RMW": rmw, "TsanRMW": tsanRMWs[rmw]})</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">                        </span>}</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>}</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">         </span>for _, order := range []string{"monotonic" /*"consume",*/, "acquire", "release", "acq_rel", "seq_cst"} {</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                        </span>output(casTempl, size, order, nil)</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>}</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>}</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre"> </span>for _, order := range []string{ /*"consume",*/ "acquire", "release", "acq_rel", "seq_cst"} {</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>for _, ftype := range []string{"signal", "thread"} {</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">                  </span>output(fenceTempl, 0, order, map[string]string{"FenceType": ftype, "Scope": tsanScopes[ftype]})</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>}</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre"> </span>}</font></div><div><font face="courier new, monospace">}</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">func output(templ *template.Template, size uint32, order string, params map[string]string) {</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">  </span>data := map[string]string{</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>"Size":      fmt.Sprint(8 * (1 << size)),</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">         </span>"ByteSize":  fmt.Sprint(1 << size),</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>"Order":     order,</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">             </span>"TsanOrder": tsanOrders[order],</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>}</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre"> </span>for k, v := range params {</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>data[k] = v</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">       </span>}</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre"> </span>templ.Execute(os.Stdout, data)</font></div>
<div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">var tsanOrders = map[string]string{</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">  </span>"unordered": "100501",</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"monotonic": "100501",</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"consume":   "100502",</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"acquire":   "100504",</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"release":   "100508",</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"acq_rel":   "100516",</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"seq_cst":   "100532",</font></div>
<div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">var tsanRMWs = map[string]string{</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">    </span>"xchg": "exchange",</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"add":  "fetch_add",</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">  </span>"sub":  "fetch_sub",</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"and":  "fetch_and",</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">  </span>"or":   "fetch_or",</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"xor":  "fetch_xor",</font></div><div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">var tsanScopes = map[string]string{</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">    </span>"signal": "singlethread",</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>"thread": "",</font></div><div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">var loadTempl = template.Must(template.New("foo").Parse(`</font></div><div><font face="courier new, monospace">define i{{.Size}} @atomic{{.Size}}_load_{{.Order}}(i{{.Size}}* %a) nounwind uwtable {</font></div>
<div><font face="courier new, monospace">entry:</font></div><div><font face="courier new, monospace">  %0 = load atomic i{{.Size}}* %a {{.Order}}, align {{.ByteSize}}</font></div><div><font face="courier new, monospace">  ret i{{.Size}} %0</font></div>
<div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace">; CHECK: atomic{{.Size}}_load_{{.Order}}</font></div><div><font face="courier new, monospace">; CHECK: call i{{.Size}} @__tsan_atomic{{.Size}}_load(i{{.Size}}* %a, i32 {{.TsanOrder}})</font></div>
<div><font face="courier new, monospace">`))</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">var storeTempl = template.Must(template.New("foo").Parse(`</font></div>
<div><font face="courier new, monospace">define void @atomic{{.Size}}_store_{{.Order}}(i{{.Size}}* %a) nounwind uwtable {</font></div><div><font face="courier new, monospace">entry:</font></div><div><font face="courier new, monospace">  store atomic i{{.Size}} 0, i{{.Size}}* %a {{.Order}}, align {{.ByteSize}}</font></div>
<div><font face="courier new, monospace">  ret void</font></div><div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace">; CHECK: atomic{{.Size}}_store_{{.Order}}</font></div><div><font face="courier new, monospace">; CHECK: call void @__tsan_atomic{{.Size}}_store(i{{.Size}}* %a, i{{.Size}} 0, i32 {{.TsanOrder}})</font></div>
<div><font face="courier new, monospace">`))</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">var rmwTempl = template.Must(template.New("foo").Parse(`</font></div>
<div><font face="courier new, monospace">define void @atomic{{.Size}}_{{.RMW}}_{{.Order}}(i{{.Size}}* %a) nounwind uwtable {</font></div><div><font face="courier new, monospace">entry:</font></div><div><font face="courier new, monospace">  atomicrmw {{.RMW}} i{{.Size}}* %a, i{{.Size}} 0 {{.Order}}</font></div>
<div><font face="courier new, monospace">  ret void</font></div><div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace">; CHECK: atomic{{.Size}}_{{.RMW}}_{{.Order}}</font></div><div>
<font face="courier new, monospace">; CHECK: call i{{.Size}} @__tsan_atomic{{.Size}}_{{.TsanRMW}}(i{{.Size}}* %a, i{{.Size}} 0, i32 {{.TsanOrder}})</font></div><div><font face="courier new, monospace">`))</font></div><div>
<font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">var casTempl = template.Must(template.New("foo").Parse(`</font></div><div><font face="courier new, monospace">define void @atomic{{.Size}}_cas_{{.Order}}(i{{.Size}}* %a) nounwind uwtable {</font></div>
<div><font face="courier new, monospace">entry:</font></div><div><font face="courier new, monospace">  cmpxchg i{{.Size}}* %a, i{{.Size}} 0, i{{.Size}} 1 {{.Order}}</font></div><div><font face="courier new, monospace">  ret void</font></div>
<div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace">; CHECK: atomic{{.Size}}_cas_{{.Order}}</font></div><div><font face="courier new, monospace">; CHECK: call i{{.Size}} @__tsan_atomic{{.Size}}_compare_exchange_val(i{{.Size}}* %a, i{{.Size}} 0, i{{.Size}} 1, i32 {{.TsanOrder}})</font></div>
<div><font face="courier new, monospace">`))</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">var fenceTempl = template.Must(template.New("foo").Parse(`</font></div>
<div><font face="courier new, monospace">define void @atomic_{{.FenceType}}_fence_{{.Order}}() nounwind uwtable {</font></div><div><font face="courier new, monospace">entry:</font></div><div><font face="courier new, monospace">  fence {{.Scope}} {{.Order}}</font></div>
<div><font face="courier new, monospace">  ret void</font></div><div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace">; CHECK: atomic_{{.FenceType}}_fence_{{.Order}}</font></div><div>
<font face="courier new, monospace">; CHECK: call void @__tsan_atomic_{{.FenceType}}_fence(i32 {{.TsanOrder}})</font></div><div><font face="courier new, monospace">`))</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">var header = `; RUN: opt < %s -tsan -S | FileCheck %s</font></div><div><font face="courier new, monospace">; Check that atomic memory operations are converted to calls into ThreadSanitizer runtime.</font></div>
<div><font face="courier new, monospace">target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"</font></div>
<div><font face="courier new, monospace">`</font></div></div><div><br></div><div><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Nov 1, 2012 at 10:46 PM, Dmitry Vyukov <span dir="ltr"><<a href="mailto:dvyukov@google.com" target="_blank">dvyukov@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="font-family:arial,helvetica,sans-serif;font-size:10pt">Please review the following patch:<div><a href="https://codereview.appspot.com/6775091" target="_blank">https://codereview.appspot.com/6775091</a><br>
</div><div><br></div>
<div>The patch intercepts atomic RMW, CAS and fences.</div><div><br></div><div><br></div></div>
</blockquote></div><br></div></div>