Author: ctopper Date: Thu Jun 14 11:43:52 2018 New Revision: 334751 URL: http://llvm.org/viewvc/llvm-project?rev=334751&view=rev Log: [X86] Add inline assembly versions of _InterlockedExchange_HLEAcquire/Release and _InterlockedCompareExchange_HLEAcquire/Release for MSVC compatibility.
Clang/LLVM doesn't have a way to pass an HLE hint through to the X86 backend to emit HLE prefixed instructions. So this is a good short term fix. Differential Revision: https://reviews.llvm.org/D47672 Modified: cfe/trunk/lib/Headers/immintrin.h cfe/trunk/lib/Headers/intrin.h cfe/trunk/test/CodeGen/bitscan-builtins.c cfe/trunk/test/CodeGen/ms-intrinsics.c Modified: cfe/trunk/lib/Headers/immintrin.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/immintrin.h?rev=334751&r1=334750&r2=334751&view=diff ============================================================================== --- cfe/trunk/lib/Headers/immintrin.h (original) +++ cfe/trunk/lib/Headers/immintrin.h Thu Jun 14 11:43:52 2018 @@ -380,4 +380,88 @@ _writegsbase_u64(unsigned long long __V) #include <invpcidintrin.h> #endif +#ifdef _MSC_VER +/* Define the default attributes for these intrinsics */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) +#ifdef __cplusplus +extern "C" { +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked Exchange HLE +\*----------------------------------------------------------------------------*/ +#if defined(__i386__) || defined(__x86_64__) +static __inline__ long __DEFAULT_FN_ATTRS +_InterlockedExchange_HLEAcquire(long volatile *_Target, long _Value) { + __asm__ __volatile__(".byte 0xf2 ; lock ; xchg %0, %1" + : "+r" (_Value), "+m" (*_Target) :: "memory"); + return _Value; +} +static __inline__ long __DEFAULT_FN_ATTRS +_InterlockedExchange_HLERelease(long volatile *_Target, long _Value) { + __asm__ __volatile__(".byte 0xf3 ; lock ; xchg %0, %1" + : "+r" (_Value), "+m" (*_Target) :: "memory"); + return _Value; +} +#endif +#if defined(__x86_64__) +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedExchange64_HLEAcquire(__int64 volatile *_Target, __int64 _Value) { + __asm__ __volatile__(".byte 0xf2 ; lock ; xchg %0, %1" + : "+r" (_Value), "+m" (*_Target) :: "memory"); + return _Value; +} +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedExchange64_HLERelease(__int64 volatile *_Target, __int64 _Value) { + __asm__ __volatile__(".byte 0xf3 ; lock ; xchg %0, %1" + : "+r" (_Value), "+m" (*_Target) :: "memory"); + return _Value; +} +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked Compare Exchange HLE +\*----------------------------------------------------------------------------*/ +#if defined(__i386__) || defined(__x86_64__) +static __inline__ long __DEFAULT_FN_ATTRS +_InterlockedCompareExchange_HLEAcquire(long volatile *_Destination, + long _Exchange, long _Comparand) { + __asm__ __volatile__(".byte 0xf2 ; lock ; cmpxchg %2, %1" + : "+a" (_Comparand), "+m" (*_Destination) + : "r" (_Exchange) : "memory"); + return _Comparand; +} +static __inline__ long __DEFAULT_FN_ATTRS +_InterlockedCompareExchange_HLERelease(long volatile *_Destination, + long _Exchange, long _Comparand) { + __asm__ __volatile__(".byte 0xf3 ; lock ; cmpxchg %2, %1" + : "+a" (_Comparand), "+m" (*_Destination) + : "r" (_Exchange) : "memory"); + return _Comparand; +} +#endif +#if defined(__x86_64__) +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedCompareExchange64_HLEAcquire(__int64 volatile *_Destination, + __int64 _Exchange, __int64 _Comparand) { + __asm__ __volatile__(".byte 0xf2 ; lock ; cmpxchg %2, %1" + : "+a" (_Comparand), "+m" (*_Destination) + : "r" (_Exchange) : "memory"); + return _Comparand; +} +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedCompareExchange64_HLERelease(__int64 volatile *_Destination, + __int64 _Exchange, __int64 _Comparand) { + __asm__ __volatile__(".byte 0xf3 ; lock ; cmpxchg %2, %1" + : "+a" (_Comparand), "+m" (*_Destination) + : "r" (_Exchange) : "memory"); + return _Comparand; +} +#endif +#ifdef __cplusplus +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif /* _MSC_VER */ + #endif /* __IMMINTRIN_H */ Modified: cfe/trunk/lib/Headers/intrin.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/intrin.h?rev=334751&r1=334750&r2=334751&view=diff ============================================================================== --- cfe/trunk/lib/Headers/intrin.h (original) +++ cfe/trunk/lib/Headers/intrin.h Thu Jun 14 11:43:52 2018 @@ -170,12 +170,6 @@ void __cdecl _enable(void); long _InterlockedAddLargeStatistic(__int64 volatile *_Addend, long _Value); unsigned char _interlockedbittestandreset(long volatile *, long); unsigned char _interlockedbittestandset(long volatile *, long); -long _InterlockedCompareExchange_HLEAcquire(long volatile *, long, long); -long _InterlockedCompareExchange_HLERelease(long volatile *, long, long); -__int64 _InterlockedcompareExchange64_HLEAcquire(__int64 volatile *, __int64, - __int64); -__int64 _InterlockedCompareExchange64_HLERelease(__int64 volatile *, __int64, - __int64); void *_InterlockedCompareExchangePointer_HLEAcquire(void *volatile *, void *, void *); void *_InterlockedCompareExchangePointer_HLERelease(void *volatile *, void *, @@ -278,10 +272,6 @@ unsigned char _InterlockedCompareExchang __int64 *_ComparandResult); short _InterlockedCompareExchange16_np(short volatile *_Destination, short _Exchange, short _Comparand); -__int64 _InterlockedCompareExchange64_HLEAcquire(__int64 volatile *, __int64, - __int64); -__int64 _InterlockedCompareExchange64_HLERelease(__int64 volatile *, __int64, - __int64); __int64 _InterlockedCompareExchange64_np(__int64 volatile *_Destination, __int64 _Exchange, __int64 _Comparand); void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination, Modified: cfe/trunk/test/CodeGen/bitscan-builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/bitscan-builtins.c?rev=334751&r1=334750&r2=334751&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/bitscan-builtins.c (original) +++ cfe/trunk/test/CodeGen/bitscan-builtins.c Thu Jun 14 11:43:52 2018 @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s // PR33722 -// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-unknown -D_MSC_VER -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - %s | FileCheck %s #include <immintrin.h> Modified: cfe/trunk/test/CodeGen/ms-intrinsics.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-intrinsics.c?rev=334751&r1=334750&r2=334751&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/ms-intrinsics.c (original) +++ cfe/trunk/test/CodeGen/ms-intrinsics.c Thu Jun 14 11:43:52 2018 @@ -455,6 +455,55 @@ __int64 test_InterlockedDecrement64(__in #endif +#if defined(__i386__) || defined(__x86_64__) +long test_InterlockedExchange_HLEAcquire(long volatile *Target, long Value) { +// CHECK-INTEL: define{{.*}} i32 @test_InterlockedExchange_HLEAcquire(i32*{{[a-z_ ]*}}%Target, i32{{[a-z_ ]*}}%Value) +// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf2 ; lock ; xchg $0, $1", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Target, i32 %Value, i32* %Target) + return _InterlockedExchange_HLEAcquire(Target, Value); +} +long test_InterlockedExchange_HLERelease(long volatile *Target, long Value) { +// CHECK-INTEL: define{{.*}} i32 @test_InterlockedExchange_HLERelease(i32*{{[a-z_ ]*}}%Target, i32{{[a-z_ ]*}}%Value) +// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf3 ; lock ; xchg $0, $1", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Target, i32 %Value, i32* %Target) + return _InterlockedExchange_HLERelease(Target, Value); +} +long test_InterlockedCompareExchange_HLEAcquire(long volatile *Destination, + long Exchange, long Comparand) { +// CHECK-INTEL: define{{.*}} i32 @test_InterlockedCompareExchange_HLEAcquire(i32*{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comparand) +// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf2 ; lock ; cmpxchg $2, $1", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Destination, i32 %Exchange, i32 %Comparand, i32* %Destination) + return _InterlockedCompareExchange_HLEAcquire(Destination, Exchange, Comparand); +} +long test_InterlockedCompareExchange_HLERelease(long volatile *Destination, + long Exchange, long Comparand) { +// CHECK-INTEL: define{{.*}} i32 @test_InterlockedCompareExchange_HLERelease(i32*{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comparand) +// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf3 ; lock ; cmpxchg $2, $1", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Destination, i32 %Exchange, i32 %Comparand, i32* %Destination) + return _InterlockedCompareExchange_HLERelease(Destination, Exchange, Comparand); +} +#endif +#if defined(__x86_64__) +__int64 test_InterlockedExchange64_HLEAcquire(__int64 volatile *Target, __int64 Value) { +// CHECK-X64: define{{.*}} i64 @test_InterlockedExchange64_HLEAcquire(i64*{{[a-z_ ]*}}%Target, i64{{[a-z_ ]*}}%Value) +// CHECK-X64: call i64 asm sideeffect ".byte 0xf2 ; lock ; xchg $0, $1", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %Target, i64 %Value, i64* %Target) + return _InterlockedExchange64_HLEAcquire(Target, Value); +} +__int64 test_InterlockedExchange64_HLERelease(__int64 volatile *Target, __int64 Value) { +// CHECK-X64: define{{.*}} i64 @test_InterlockedExchange64_HLERelease(i64*{{[a-z_ ]*}}%Target, i64{{[a-z_ ]*}}%Value) +// CHECK-X64: call i64 asm sideeffect ".byte 0xf3 ; lock ; xchg $0, $1", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %Target, i64 %Value, i64* %Target) + return _InterlockedExchange64_HLERelease(Target, Value); +} +__int64 test_InterlockedCompareExchange64_HLEAcquire(__int64 volatile *Destination, + __int64 Exchange, __int64 Comparand) { +// CHECK-X64: define{{.*}} i64 @test_InterlockedCompareExchange64_HLEAcquire(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comparand) +// CHECK-X64: call i64 asm sideeffect ".byte 0xf2 ; lock ; cmpxchg $2, $1", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %Destination, i64 %Exchange, i64 %Comparand, i64* %Destination) + return _InterlockedCompareExchange64_HLEAcquire(Destination, Exchange, Comparand); +} +__int64 test_InterlockedCompareExchange64_HLERelease(__int64 volatile *Destination, + __int64 Exchange, __int64 Comparand) { +// CHECK-X64: define{{.*}} i64 @test_InterlockedCompareExchange64_HLERelease(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comparand) +// CHECK-X64: call i64 asm sideeffect ".byte 0xf3 ; lock ; cmpxchg $2, $1", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %Destination, i64 %Exchange, i64 %Comparand, i64* %Destination) + return _InterlockedCompareExchange64_HLERelease(Destination, Exchange, Comparand); +} +#endif + void test__fastfail() { __fastfail(42); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits