[llvm-commits] tsan: support more atomic builtins

Dmitry Vyukov dvyukov at google.com
Thu Nov 1 12:07:58 PDT 2012


FTR, here is test generator:

package main

import (
"fmt"
"os"
"text/template"
)

func main() {
fmt.Print(header)
for size := uint32(0); size < 5; size++ {
for _, order := range []string{"unordered", "monotonic" /*"consume",*/,
"acquire", "seq_cst"} {
output(loadTempl, size, order, nil)
}
for _, order := range []string{"unordered", "monotonic", "release",
"seq_cst"} {
output(storeTempl, size, order, nil)
}
for _, order := range []string{"monotonic" /*"consume",*/, "acquire",
"release", "acq_rel", "seq_cst"} {
for _, rmw := range []string{"xchg", "add", "sub", "and", "or", "xor"} {
output(rmwTempl, size, order, map[string]string{"RMW": rmw, "TsanRMW":
tsanRMWs[rmw]})
}
}
for _, order := range []string{"monotonic" /*"consume",*/, "acquire",
"release", "acq_rel", "seq_cst"} {
output(casTempl, size, order, nil)
}
}
for _, order := range []string{ /*"consume",*/ "acquire", "release",
"acq_rel", "seq_cst"} {
for _, ftype := range []string{"signal", "thread"} {
output(fenceTempl, 0, order, map[string]string{"FenceType": ftype, "Scope":
tsanScopes[ftype]})
}
}
}

func output(templ *template.Template, size uint32, order string, params
map[string]string) {
data := map[string]string{
"Size":      fmt.Sprint(8 * (1 << size)),
"ByteSize":  fmt.Sprint(1 << size),
"Order":     order,
"TsanOrder": tsanOrders[order],
}
for k, v := range params {
data[k] = v
}
templ.Execute(os.Stdout, data)
}

var tsanOrders = map[string]string{
"unordered": "100501",
"monotonic": "100501",
"consume":   "100502",
"acquire":   "100504",
"release":   "100508",
"acq_rel":   "100516",
"seq_cst":   "100532",
}

var tsanRMWs = map[string]string{
"xchg": "exchange",
"add":  "fetch_add",
"sub":  "fetch_sub",
"and":  "fetch_and",
"or":   "fetch_or",
"xor":  "fetch_xor",
}

var tsanScopes = map[string]string{
"signal": "singlethread",
"thread": "",
}

var loadTempl = template.Must(template.New("foo").Parse(`
define i{{.Size}} @atomic{{.Size}}_load_{{.Order}}(i{{.Size}}* %a) nounwind
uwtable {
entry:
  %0 = load atomic i{{.Size}}* %a {{.Order}}, align {{.ByteSize}}
  ret i{{.Size}} %0
}
; CHECK: atomic{{.Size}}_load_{{.Order}}
; CHECK: call i{{.Size}} @__tsan_atomic{{.Size}}_load(i{{.Size}}* %a, i32
{{.TsanOrder}})
`))

var storeTempl = template.Must(template.New("foo").Parse(`
define void @atomic{{.Size}}_store_{{.Order}}(i{{.Size}}* %a) nounwind
uwtable {
entry:
  store atomic i{{.Size}} 0, i{{.Size}}* %a {{.Order}}, align {{.ByteSize}}
  ret void
}
; CHECK: atomic{{.Size}}_store_{{.Order}}
; CHECK: call void @__tsan_atomic{{.Size}}_store(i{{.Size}}* %a, i{{.Size}}
0, i32 {{.TsanOrder}})
`))

var rmwTempl = template.Must(template.New("foo").Parse(`
define void @atomic{{.Size}}_{{.RMW}}_{{.Order}}(i{{.Size}}* %a) nounwind
uwtable {
entry:
  atomicrmw {{.RMW}} i{{.Size}}* %a, i{{.Size}} 0 {{.Order}}
  ret void
}
; CHECK: atomic{{.Size}}_{{.RMW}}_{{.Order}}
; CHECK: call i{{.Size}} @__tsan_atomic{{.Size}}_{{.TsanRMW}}(i{{.Size}}*
%a, i{{.Size}} 0, i32 {{.TsanOrder}})
`))

var casTempl = template.Must(template.New("foo").Parse(`
define void @atomic{{.Size}}_cas_{{.Order}}(i{{.Size}}* %a) nounwind
uwtable {
entry:
  cmpxchg i{{.Size}}* %a, i{{.Size}} 0, i{{.Size}} 1 {{.Order}}
  ret void
}
; CHECK: atomic{{.Size}}_cas_{{.Order}}
; CHECK: call i{{.Size}}
@__tsan_atomic{{.Size}}_compare_exchange_val(i{{.Size}}* %a, i{{.Size}} 0,
i{{.Size}} 1, i32 {{.TsanOrder}})
`))

var fenceTempl = template.Must(template.New("foo").Parse(`
define void @atomic_{{.FenceType}}_fence_{{.Order}}() nounwind uwtable {
entry:
  fence {{.Scope}} {{.Order}}
  ret void
}
; CHECK: atomic_{{.FenceType}}_fence_{{.Order}}
; CHECK: call void @__tsan_atomic_{{.FenceType}}_fence(i32 {{.TsanOrder}})
`))

var header = `; RUN: opt < %s -tsan -S | FileCheck %s
; Check that atomic memory operations are converted to calls into
ThreadSanitizer runtime.
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"
`




On Thu, Nov 1, 2012 at 10:46 PM, Dmitry Vyukov <dvyukov at google.com> wrote:

> Please review the following patch:
> https://codereview.appspot.com/6775091
>
> The patch intercepts atomic RMW, CAS and fences.
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121101/f0f5f26f/attachment.html>


More information about the llvm-commits mailing list