1  /* { dg-options "--param=tsan-distinguish-volatile=1 -fdump-tree-optimized" } */
       2  
       3  #include <assert.h>
       4  #include <stdint.h>
       5  #include <stdio.h>
       6  
       7  int32_t Global4;
       8  volatile int32_t VolatileGlobal4;
       9  volatile int64_t VolatileGlobal8;
      10  
      11  static int nvolatile_reads;
      12  static int nvolatile_writes;
      13  
      14  #ifdef __cplusplus
      15  extern "C" {
      16  #endif
      17  
      18  __attribute__((no_sanitize_thread))
      19  void __tsan_volatile_read4(void *addr) {
      20    assert(addr == &VolatileGlobal4);
      21    nvolatile_reads++;
      22  }
      23  __attribute__((no_sanitize_thread))
      24  void __tsan_volatile_write4(void *addr) {
      25    assert(addr == &VolatileGlobal4);
      26    nvolatile_writes++;
      27  }
      28  __attribute__((no_sanitize_thread))
      29  void __tsan_volatile_read8(void *addr) {
      30    assert(addr == &VolatileGlobal8);
      31    nvolatile_reads++;
      32  }
      33  __attribute__((no_sanitize_thread))
      34  void __tsan_volatile_write8(void *addr) {
      35    assert(addr == &VolatileGlobal8);
      36    nvolatile_writes++;
      37  }
      38  
      39  #ifdef __cplusplus
      40  }
      41  #endif
      42  
      43  __attribute__((no_sanitize_thread))
      44  static void check() {
      45    assert(nvolatile_reads == 4);
      46    assert(nvolatile_writes == 4);
      47  }
      48  
      49  int main() {
      50    Global4 = 1;
      51  
      52    VolatileGlobal4 = 1;
      53    Global4 = VolatileGlobal4;
      54    VolatileGlobal4 = 1 + VolatileGlobal4;
      55  
      56    VolatileGlobal8 = 1;
      57    Global4 = (int32_t)VolatileGlobal8;
      58    VolatileGlobal8 = 1 + VolatileGlobal8;
      59  
      60    check();
      61    return 0;
      62  }
      63  
      64  // { dg-final { scan-tree-dump-times "__tsan_volatile_read4 \\(&VolatileGlobal4" 2 "optimized" } }
      65  // { dg-final { scan-tree-dump-times "__tsan_volatile_read8 \\(&VolatileGlobal8" 2 "optimized" } }
      66  // { dg-final { scan-tree-dump-times "__tsan_volatile_write4 \\(&VolatileGlobal4" 2 "optimized" } }
      67  // { dg-final { scan-tree-dump-times "__tsan_volatile_write8 \\(&VolatileGlobal8" 2 "optimized" } }