1 // RUN: %clangxx_tsan %s -o %t 2 // RUN: %run %t 2>&1 | FileCheck %s 3 4 // bench.h needs pthread barriers which are not available on OS X 5 // UNSUPPORTED: darwin 6 7 #include "bench.h" 8 #include <memory.h> 9 10 void thread(int tid) { 11 volatile long x = 0; 12 switch (bench_mode) { 13 case 0: 14 for (int i = 0; i < bench_niter; i++) 15 *(volatile char *)&x = 1; 16 break; 17 case 1: 18 for (int i = 0; i < bench_niter; i++) 19 *(volatile short *)&x = 1; 20 break; 21 case 2: 22 for (int i = 0; i < bench_niter; i++) 23 *(volatile int *)&x = 1; 24 break; 25 case 3: 26 for (int i = 0; i < bench_niter; i++) 27 *(volatile long *)&x = 1; 28 break; 29 case 4: 30 for (int i = 0; i < bench_niter; i++) 31 *(volatile char *)&x; 32 break; 33 case 5: 34 for (int i = 0; i < bench_niter; i++) 35 *(volatile short *)&x; 36 break; 37 case 6: 38 for (int i = 0; i < bench_niter; i++) 39 *(volatile int *)&x; 40 break; 41 case 7: 42 for (int i = 0; i < bench_niter; i++) 43 *(volatile long *)&x; 44 case 8: 45 for (int i = 0; i < bench_niter / 10; i++) { 46 ((volatile long *)&x)[0]; 47 ((volatile int *)&x)[0]; 48 ((volatile short *)&x)[2]; 49 ((volatile char *)&x)[6]; 50 ((volatile char *)&x)[7]; 51 ((volatile long *)&x)[0] = 1; 52 ((volatile int *)&x)[0] = 1; 53 ((volatile short *)&x)[2] = 1; 54 ((volatile char *)&x)[6] = 1; 55 ((volatile char *)&x)[7] = 1; 56 } 57 break; 58 case 9: { 59 volatile long size = sizeof(x); 60 for (int i = 0; i < bench_niter; i++) 61 memset((void *)&x, i, size); 62 break; 63 } 64 case 10: { 65 volatile long data[2] = {}; 66 volatile long size = sizeof(data) - 2; 67 for (int i = 0; i < bench_niter; i++) 68 memset(((char *)data) + 1, i, size); 69 break; 70 } 71 case 11: { 72 volatile long data[2] = {}; 73 for (int i = 0; i < bench_niter / 8 / 3; i++) { 74 for (int off = 0; off < 8; off++) { 75 __sanitizer_unaligned_store16(((char *)data) + off, i); 76 __sanitizer_unaligned_store32(((char *)data) + off, i); 77 __sanitizer_unaligned_store64(((char *)data) + off, i); 78 } 79 } 80 break; 81 } 82 #if TSAN_VECTORIZE 83 case 12: { 84 // The compiler wants to optimize all this away. 85 // Use volatile to prevent optimization, but then use kBlock 86 // to avoid the additional non-vector load in the inner loop. 87 // Also use only even indexes to prevent compiler from 88 // inserting memset. 89 const int kBlock = 128; 90 __m128i data[kBlock * 2]; 91 __m128i *volatile vptr = data; 92 for (int i = 0; i < bench_niter / kBlock; i++) { 93 __m128i *ptr = vptr; 94 for (int j = 0; j < kBlock; j++) 95 _mm_store_si128(&ptr[j * 2], _mm_setzero_si128()); 96 } 97 break; 98 } 99 #endif 100 } 101 } 102 103 void bench() { 104 start_thread_group(bench_nthread, thread); 105 } 106 107 // CHECK: DONE 108