1/* PR sanitizer/65400 */
2/* { dg-shouldfail "tsan" } */
3/* { dg-additional-options "-fno-omit-frame-pointer -ldl" } */
4
5#include <pthread.h>
6#include "tsan_barrier.h"
7
8static pthread_barrier_t barrier;
9int v;
10
11int
12fn1 (int a, int b, int c)
13{
14  int r = (a ^ b) % c;
15  r = r * a * b + c;
16  r = (r ^ b) % c;
17  return r;
18}
19
20int
21fn2 (int a, int b, int c)
22{
23  int r = (a ^ b) % c;
24  r = r * a * b + c;
25  r = (r ^ b) % c;
26  return r;
27}
28
29__attribute__((noinline, noclone)) void
30foo (void)
31{
32  barrier_wait (&barrier);
33  barrier_wait (&barrier);
34  v++;
35}
36
37__attribute__((noinline, noclone)) void
38bar (void)
39{
40  int (*fna) (int, int, int);
41  int (*fnb) (int, int, int);
42  int i;
43  asm ("" : "=g" (fna) : "0" (fn1));
44  asm ("" : "=g" (fnb) : "0" (fn2));
45  for (i = 0; i < 128; i++)
46    {
47      fna (0, 0, i + 1);
48      fnb (0, 0, i + 1);
49    }
50  foo ();
51}
52
53__attribute__((noinline, noclone)) void *
54tf (void *arg)
55{
56  (void) arg;
57  bar ();
58  return NULL;
59}
60
61int
62main ()
63{
64  pthread_t th;
65  barrier_init (&barrier, 2);
66  if (pthread_create (&th, NULL, tf, NULL))
67    return 0;
68  barrier_wait (&barrier);
69  v++;
70  barrier_wait (&barrier);
71  pthread_join (th, NULL);
72  return 0;
73}
74
75/* { dg-output "WARNING: ThreadSanitizer: data race.*#2 _?tf" } */
76