12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
28ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov#include <pthread.h>
38ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov#include <stdio.h>
48ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov#include <stdlib.h>
58ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov#include <stdint.h>
68ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov
78ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovuint64_t objs[8*3*3*2][3];
88ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov
98ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovextern "C" {
108ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovuint16_t __tsan_unaligned_read2(void *addr);
118ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovuint32_t __tsan_unaligned_read4(void *addr);
128ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovuint64_t __tsan_unaligned_read8(void *addr);
138ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovvoid __tsan_unaligned_write2(void *addr, uint16_t v);
148ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovvoid __tsan_unaligned_write4(void *addr, uint32_t v);
158ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovvoid __tsan_unaligned_write8(void *addr, uint64_t v);
168ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov}
178ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov
188ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovstatic void access(char *p, int sz, int rw) {
198ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  if (rw) {
208ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    switch (sz) {
218ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    case 0: __tsan_unaligned_write2(p, 0); break;
228ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    case 1: __tsan_unaligned_write4(p, 0); break;
238ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    case 2: __tsan_unaligned_write8(p, 0); break;
248ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    default: exit(1);
258ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    }
268ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  } else {
278ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    switch (sz) {
288ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    case 0: __tsan_unaligned_read2(p); break;
298ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    case 1: __tsan_unaligned_read4(p); break;
308ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    case 2: __tsan_unaligned_read8(p); break;
318ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    default: exit(1);
328ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    }
338ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  }
348ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov}
358ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov
368ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovstatic int accesssize(int sz) {
378ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  switch (sz) {
388ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  case 0: return 2;
398ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  case 1: return 4;
408ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  case 2: return 8;
418ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  }
428ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  exit(1);
438ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov}
448ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov
458ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovvoid Test(bool main) {
468ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  uint64_t *obj = objs[0];
478ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  for (int off = 0; off < 8; off++) {
488ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    for (int sz1 = 0; sz1 < 3; sz1++) {
498ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov      for (int sz2 = 0; sz2 < 3; sz2++) {
508ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov        for (int rw = 0; rw < 2; rw++) {
518ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov          char *p = (char*)obj + off;
528ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov          if (main) {
538ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov            // printf("thr=%d off=%d sz1=%d sz2=%d rw=%d p=%p\n",
548ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov            //        main, off, sz1, sz2, rw, p);
558ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov            access(p, sz1, true);
568ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov          } else {
578ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov            p += accesssize(sz1);
588ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov            // printf("thr=%d off=%d sz1=%d sz2=%d rw=%d p=%p\n",
598ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov            //        main, off, sz1, sz2, rw, p);
608ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov            access(p, sz2, rw);
618ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov          }
628ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov          obj += 3;
638ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov        }
648ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov      }
658ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov    }
668ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  }
678ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov}
688ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov
698ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovvoid *Thread(void *p) {
708ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  (void)p;
718ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  Test(false);
728ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  return 0;
738ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov}
748ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov
758ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukovint main() {
768ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  pthread_t th;
778ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  pthread_create(&th, 0, Thread, 0);
788ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  Test(true);
798ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  pthread_join(th, 0);
808ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov  printf("OK\n");
818ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov}
828ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov
838ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov// CHECK-NOT: WARNING: ThreadSanitizer:
848ecd0e5d9f389d18653892851c6ffb2f235de4b7Dmitry Vyukov// CHECK: OK
85