From 00d33a5cb115b82c19ed4cfb2e4bc94a10bfd752 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 17 Oct 2013 01:29:48 +0000 Subject: [PATCH] Add implementations of the MSVC barrier intrinsics Summary: These are deprecated in VS 2012 according to MSDN. They don't actually compile down to any code. They prevent the compiler from reordering memory accesses across the barrier, which is what a memory-clobbering volatile asm does. Reviewers: echristo CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1954 llvm-svn: 192860 --- clang/lib/Headers/Intrin.h | 21 +++++++++++++++++++++ clang/test/Headers/ms-intrin.cpp | 13 ++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/clang/lib/Headers/Intrin.h b/clang/lib/Headers/Intrin.h index 5b00e3c8fe49..437646471dab 100644 --- a/clang/lib/Headers/Intrin.h +++ b/clang/lib/Headers/Intrin.h @@ -243,7 +243,9 @@ static __inline__ unsigned long __cdecl _lrotr(unsigned long, int); static __inline__ unsigned int _lzcnt_u32(unsigned int); +static __inline__ void _ReadBarrier(void); +static __inline__ void _ReadWriteBarrier(void); static __inline__ void *_ReturnAddress(void); @@ -280,6 +282,7 @@ unsigned int _t1mskc_u32(unsigned int); unsigned int _tzcnt_u32(unsigned int); unsigned int _tzcnt_u32(unsigned int); unsigned int _tzmsk_u32(unsigned int); +static __inline__ void _WriteBarrier(void); void _xabort(const unsigned int imm); unsigned __int32 xbegin(void); @@ -744,6 +747,24 @@ _InterlockedCompareExchange64(__int64 volatile *_Destination, } #endif /*----------------------------------------------------------------------------*\ +|* Barriers +\*----------------------------------------------------------------------------*/ +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +__attribute__((deprecated("use other intrinsics or C++11 atomics instead"))) +_ReadWriteBarrier(void) { + __asm__ volatile ("" : : : "memory"); +} +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +__attribute__((deprecated("use other intrinsics or C++11 atomics instead"))) +_ReadBarrier(void) { + __asm__ volatile ("" : : : "memory"); +} +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +__attribute__((deprecated("use other intrinsics or C++11 atomics instead"))) +_WriteBarrier(void) { + __asm__ volatile ("" : : : "memory"); +} +/*----------------------------------------------------------------------------*\ |* Misc \*----------------------------------------------------------------------------*/ static __inline__ void * __attribute__((__always_inline__, __nodebug__)) diff --git a/clang/test/Headers/ms-intrin.cpp b/clang/test/Headers/ms-intrin.cpp index 58ad5a2449ca..1bf134e7eac6 100644 --- a/clang/test/Headers/ms-intrin.cpp +++ b/clang/test/Headers/ms-intrin.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple i386-pc-win32 -target-cpu pentium4 \ // RUN: -fms-extensions -fms-compatibility -fmsc-version=1700 \ -// RUN: -ffreestanding -fsyntax-only %s +// RUN: -ffreestanding -verify %s // Intrin.h needs size_t, but -ffreestanding prevents us from getting it from // stddef.h. Work around it with this typedef. @@ -11,3 +11,14 @@ typedef __SIZE_TYPE__ size_t; // Use some C++ to make sure we closed the extern "C" brackets. template void foo(T V) {} + +void bar() { + _ReadWriteBarrier(); // expected-warning {{is deprecated: use other intrinsics or C++11 atomics instead}} + _ReadBarrier(); // expected-warning {{is deprecated: use other intrinsics or C++11 atomics instead}} + _WriteBarrier(); // expected-warning {{is deprecated: use other intrinsics or C++11 atomics instead}} + // FIXME: It'd be handy if we didn't have to hardcode the line number in + // intrin.h. + // expected-note@Intrin.h:754 {{declared here}} + // expected-note@Intrin.h:759 {{declared here}} + // expected-note@Intrin.h:764 {{declared here}} +}