From a25fbef08857ff0991877bb11e69a25943406915 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Wed, 29 Oct 2014 16:35:41 +0000 Subject: [PATCH] CodeGen: add __readfsdword builtin The Windows NT SDK uses __readfsdword and declares it as a compiler provided builtin (#pragma intrinsic(__readfsword). Because intrin.h is not referenced by winnt.h, it is not possible to provide an out-of-line definition for the intrinsic. Provide a proper compiler builtin definition. llvm-svn: 220859 --- clang/include/clang/Basic/Builtins.def | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 8 ++++++++ clang/lib/Headers/Intrin.h | 4 ---- clang/test/CodeGen/ms-intrinsics.c | 15 ++++++++++++++- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index 72843f1fb6a6..dc668a161cb1 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -703,6 +703,7 @@ LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES) // C99 library functions // C99 stdlib.h diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index c4f92edc8a86..5cacfa12a47e 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1624,6 +1624,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, RMWI->setVolatile(true); return RValue::get(RMWI); } + case Builtin::BI__readfsdword: { + Value *IntToPtr = + Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)), + llvm::PointerType::get(CGM.Int32Ty, 257)); + LoadInst *Load = + Builder.CreateAlignedLoad(IntToPtr, /*Align=*/4, /*isVolatile=*/true); + return RValue::get(Load); + } } // If this is an alias for a lib function (e.g. __builtin_sin), emit diff --git a/clang/lib/Headers/Intrin.h b/clang/lib/Headers/Intrin.h index 13e105ec1782..d5c334b2da16 100644 --- a/clang/lib/Headers/Intrin.h +++ b/clang/lib/Headers/Intrin.h @@ -861,10 +861,6 @@ static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__)) __readfsbyte(unsigned long __offset) { return *__ptr_to_addr_space(257, unsigned char, __offset); } -static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__)) -__readfsdword(unsigned long __offset) { - return *__ptr_to_addr_space(257, unsigned long, __offset); -} static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__)) __readfsqword(unsigned long __offset) { return *__ptr_to_addr_space(257, unsigned __int64, __offset); diff --git a/clang/test/CodeGen/ms-intrinsics.c b/clang/test/CodeGen/ms-intrinsics.c index fb0f62c61c4b..c952c00be97c 100644 --- a/clang/test/CodeGen/ms-intrinsics.c +++ b/clang/test/CodeGen/ms-intrinsics.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i686--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple i686--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK -check-prefix CHECK-I386 // RUN: %clang_cc1 -triple thumbv7--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) { @@ -36,3 +36,16 @@ long test_InterlockedExchange(long *Target, long Value) { // CHECK: %[[EXCHANGE:[0-9]+]] = atomicrmw xchg i32* %Target, i32 %Value seq_cst // CHECK: ret i32 %[[EXCHANGE:[0-9]+]] // CHECK: } + +#if defined(__i386__) +long test__readfsdword(unsigned long Offset) { + return __readfsdword(Offset); +} + +// CHECK-I386: define i32 @test__readfsdword(i32 %Offset){{.*}}{ +// CHECK-I386: %0 = inttoptr i32 %Offset to i32 addrspace(257)* +// CHECK-I386: %1 = load volatile i32 addrspace(257)* %0, align 4 +// CHECK-I386: ret i32 %1 +// CHECK-I386: } +#endif +