From 8001a781cbce8ac202aaffcfd16c60f962be073f Mon Sep 17 00:00:00 2001 From: Albert Gutowski Date: Mon, 10 Oct 2016 19:40:51 +0000 Subject: [PATCH] Implement MS read/write barriers and __faststorefence intrinsic Reviewers: hans, rnk, majnemer Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25442 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@283793 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/BuiltinsX86.def | 4 +++ include/clang/Basic/BuiltinsX86_64.def | 3 ++ lib/CodeGen/CGBuiltin.cpp | 11 ++++++++ lib/Headers/intrin.h | 39 ++++++-------------------- test/CodeGen/ms-barriers-intrinsics.c | 39 ++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 test/CodeGen/ms-barriers-intrinsics.c diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index 6154b8cb6e..243ad01043 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -2071,6 +2071,10 @@ TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "", "") TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx") TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx") +TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_ReadBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_WriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + TARGET_HEADER_BUILTIN(__emul, "LLiii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") diff --git a/include/clang/Basic/BuiltinsX86_64.def b/include/clang/Basic/BuiltinsX86_64.def index 8836e68bfd..d10388663e 100644 --- a/include/clang/Basic/BuiltinsX86_64.def +++ b/include/clang/Basic/BuiltinsX86_64.def @@ -23,5 +23,8 @@ TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAG TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_umul128, "ULLiULLiULLiULLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + + #undef BUILTIN #undef TARGET_HEADER_BUILTIN diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 5cbb6a2338..f9b38fa585 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -7612,6 +7612,17 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, Builder.CreateStore(HigherBits, HighBitsAddress); return Builder.CreateIntCast(MulResult, ResType, IsSigned); } + + case X86::BI__faststorefence: { + return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, + llvm::CrossThread); + } + case X86::BI_ReadWriteBarrier: + case X86::BI_ReadBarrier: + case X86::BI_WriteBarrier: { + return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, + llvm::SingleThread); + } } } diff --git a/lib/Headers/intrin.h b/lib/Headers/intrin.h index 100da0b0d7..5a73ecec1c 100644 --- a/lib/Headers/intrin.h +++ b/lib/Headers/intrin.h @@ -256,10 +256,12 @@ static __inline__ unsigned long __cdecl _lrotl(unsigned long, int); static __inline__ unsigned long __cdecl _lrotr(unsigned long, int); -static __inline__ -void _ReadBarrier(void); -static __inline__ -void _ReadWriteBarrier(void); +static __inline__ void +__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead"))) +_ReadBarrier(void); +static __inline__ void +__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead"))) +_ReadWriteBarrier(void); static __inline__ void *_ReturnAddress(void); unsigned int _rorx_u32(unsigned int, const unsigned int); @@ -288,8 +290,9 @@ unsigned int _shrx_u32(unsigned int, unsigned int); void _Store_HLERelease(long volatile *, long); void _Store64_HLERelease(__int64 volatile *, __int64); void _StorePointer_HLERelease(void *volatile *, void *); -static __inline__ -void _WriteBarrier(void); +static __inline__ void +__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead"))) +_WriteBarrier(void); unsigned __int32 xbegin(void); void _xend(void); static __inline__ @@ -1045,30 +1048,6 @@ _InterlockedCompareExchange64_rel(__int64 volatile *_Destination, } #endif /*----------------------------------------------------------------------------*\ -|* Barriers -\*----------------------------------------------------------------------------*/ -static __inline__ void __DEFAULT_FN_ATTRS -__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead"))) -_ReadWriteBarrier(void) { - __atomic_signal_fence(__ATOMIC_SEQ_CST); -} -static __inline__ void __DEFAULT_FN_ATTRS -__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead"))) -_ReadBarrier(void) { - __atomic_signal_fence(__ATOMIC_SEQ_CST); -} -static __inline__ void __DEFAULT_FN_ATTRS -__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead"))) -_WriteBarrier(void) { - __atomic_signal_fence(__ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ void __DEFAULT_FN_ATTRS -__faststorefence(void) { - __atomic_thread_fence(__ATOMIC_SEQ_CST); -} -#endif -/*----------------------------------------------------------------------------*\ |* readfs, readgs |* (Pointers in address space #256 and #257 are relative to the GS and FS |* segment registers, respectively.) diff --git a/test/CodeGen/ms-barriers-intrinsics.c b/test/CodeGen/ms-barriers-intrinsics.c new file mode 100644 index 0000000000..b0dfc3042a --- /dev/null +++ b/test/CodeGen/ms-barriers-intrinsics.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ +// RUN: -triple i686--windows -emit-llvm %s -o - \ +// RUN: | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-I386 +// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ +// RUN: -triple x86_64--windows -emit-llvm %s -o - \ +// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X64 + +// intrin.h needs size_t, but -ffreestanding prevents us from getting it from +// stddef.h. Work around it with this typedef. +typedef __SIZE_TYPE__ size_t; + +#include + +void test_ReadWriteBarrier() { _ReadWriteBarrier(); } +// CHECK-LABEL: define void @test_ReadWriteBarrier +// CHECK: fence singlethread seq_cst +// CHECK: ret void +// CHECK: } + +void test_ReadBarrier() { _ReadBarrier(); } +// CHECK-LABEL: define void @test_ReadBarrier +// CHECK: fence singlethread seq_cst +// CHECK: ret void +// CHECK: } + +void test_WriteBarrier() { _WriteBarrier(); } +// CHECK-LABEL: define void @test_WriteBarrier +// CHECK: fence singlethread seq_cst +// CHECK: ret void +// CHECK: } + +#if defined(__x86_64__) +void test__faststorefence() { __faststorefence(); } +// CHECK-X64-LABEL: define void @test__faststorefence +// CHECK-X64: fence seq_cst +// CHECK-X64: ret void +// CHECK-X64: } +#endif + -- 2.40.0