r298538 - [X86] Implement __readgsqword (and the rest) as builtins (PR32373)

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 22 12:13:13 PDT 2017


Author: hans
Date: Wed Mar 22 14:13:13 2017
New Revision: 298538

URL: http://llvm.org/viewvc/llvm-project?rev=298538&view=rev
Log:
[X86] Implement __readgsqword (and the rest) as builtins (PR32373)

It seems MS headers have started using __readgsqword, and since it's
used in a header that doesn't include intrin.h, we can't implement it as
an inline function anymore.

That was already the case for __readfsdword, which Saleem added support
for in r220859. This patch reuses that codegen to implement all of
__read[fg]s{byte,word,dword,qword}.

Differential Revision: https://reviews.llvm.org/D31248

Modified:
    cfe/trunk/include/clang/Basic/Builtins.def
    cfe/trunk/include/clang/Basic/BuiltinsX86.def
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/lib/Headers/intrin.h
    cfe/trunk/test/CodeGen/ms-x86-intrinsics.c

Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=298538&r1=298537&r2=298538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Wed Mar 22 14:13:13 2017
@@ -766,7 +766,6 @@ LANGBUILTIN(__noop,           "i.",  "n"
 LANGBUILTIN(__popcnt16, "UsUs",     "nc", ALL_MS_LANGUAGES)
 LANGBUILTIN(__popcnt,   "UiUi",     "nc", ALL_MS_LANGUAGES)
 LANGBUILTIN(__popcnt64, "ULLiULLi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__readfsdword,    "ULiULi", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_rotl8,  "UcUcUc",    "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_rotl16, "UsUsUc",    "n", ALL_MS_LANGUAGES)

Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=298538&r1=298537&r2=298538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original)
+++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Wed Mar 22 14:13:13 2017
@@ -1832,6 +1832,16 @@ TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz"
 TARGET_HEADER_BUILTIN(__int2c, "v",       "nr", "intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(__ud2,   "v",       "nr", "intrin.h", ALL_MS_LANGUAGES, "")
 
+TARGET_HEADER_BUILTIN(__readfsbyte,  "UcULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readfsword,  "UsULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readfsdword, "ULiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readfsqword, "ULLiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__readgsbyte,  "UcULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readgsword,  "UsULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readgsdword, "ULiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readgsqword, "ULLiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
 #undef BUILTIN
 #undef TARGET_BUILTIN
 #undef TARGET_HEADER_BUILTIN

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=298538&r1=298537&r2=298538&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Wed Mar 22 14:13:13 2017
@@ -2238,16 +2238,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(
   case Builtin::BI_InterlockedXor16:
   case Builtin::BI_InterlockedXor:
     return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E));
-  case Builtin::BI__readfsdword: {
-    llvm::Type *IntTy = ConvertType(E->getType());
-    Value *IntToPtr =
-      Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
-                             llvm::PointerType::get(IntTy, 257));
-    LoadInst *Load = Builder.CreateAlignedLoad(
-        IntTy, IntToPtr, getContext().getTypeAlignInChars(E->getType()));
-    Load->setVolatile(true);
-    return RValue::get(Load);
-  }
 
   case Builtin::BI__exception_code:
   case Builtin::BI_exception_code:
@@ -8005,6 +7995,30 @@ Value *CodeGenFunction::EmitX86BuiltinEx
     CS.setAttributes(NoReturnAttr);
     return CS.getInstruction();
   }
+  case X86::BI__readfsbyte:
+  case X86::BI__readfsword:
+  case X86::BI__readfsdword:
+  case X86::BI__readfsqword: {
+    llvm::Type *IntTy = ConvertType(E->getType());
+    Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
+                                        llvm::PointerType::get(IntTy, 257));
+    LoadInst *Load = Builder.CreateAlignedLoad(
+        IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
+    Load->setVolatile(true);
+    return Load;
+  }
+  case X86::BI__readgsbyte:
+  case X86::BI__readgsword:
+  case X86::BI__readgsdword:
+  case X86::BI__readgsqword: {
+    llvm::Type *IntTy = ConvertType(E->getType());
+    Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
+                                        llvm::PointerType::get(IntTy, 256));
+    LoadInst *Load = Builder.CreateAlignedLoad(
+        IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
+    Load->setVolatile(true);
+    return Load;
+  }
   }
 }
 

Modified: cfe/trunk/lib/Headers/intrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/intrin.h?rev=298538&r1=298537&r2=298538&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/intrin.h (original)
+++ cfe/trunk/lib/Headers/intrin.h Wed Mar 22 14:13:13 2017
@@ -869,50 +869,7 @@ _InterlockedCompareExchange64_rel(__int6
   return _Comparand;
 }
 #endif
-/*----------------------------------------------------------------------------*\
-|* readfs, readgs
-|* (Pointers in address space #256 and #257 are relative to the GS and FS
-|* segment registers, respectively.)
-\*----------------------------------------------------------------------------*/
-#define __ptr_to_addr_space(__addr_space_nbr, __type, __offset)              \
-    ((volatile __type __attribute__((__address_space__(__addr_space_nbr)))*) \
-    (__offset))
 
-#ifdef __i386__
-static __inline__ unsigned char __DEFAULT_FN_ATTRS
-__readfsbyte(unsigned long __offset) {
-  return *__ptr_to_addr_space(257, unsigned char, __offset);
-}
-static __inline__ unsigned short __DEFAULT_FN_ATTRS
-__readfsword(unsigned long __offset) {
-  return *__ptr_to_addr_space(257, unsigned short, __offset);
-}
-static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS
-__readfsqword(unsigned long __offset) {
-  return *__ptr_to_addr_space(257, unsigned __int64, __offset);
-}
-#endif
-#ifdef __x86_64__
-static __inline__ unsigned char __DEFAULT_FN_ATTRS
-__readgsbyte(unsigned long __offset) {
-  return *__ptr_to_addr_space(256, unsigned char, (unsigned long long)__offset);
-}
-static __inline__ unsigned short __DEFAULT_FN_ATTRS
-__readgsword(unsigned long __offset) {
-  return *__ptr_to_addr_space(256, unsigned short,
-                              (unsigned long long)__offset);
-}
-static __inline__ unsigned long __DEFAULT_FN_ATTRS
-__readgsdword(unsigned long __offset) {
-  return *__ptr_to_addr_space(256, unsigned long, (unsigned long long)__offset);
-}
-static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS
-__readgsqword(unsigned long __offset) {
-  return *__ptr_to_addr_space(256, unsigned __int64,
-                              (unsigned long long)__offset);
-}
-#endif
-#undef __ptr_to_addr_space
 /*----------------------------------------------------------------------------*\
 |* movs, stos
 \*----------------------------------------------------------------------------*/

Modified: cfe/trunk/test/CodeGen/ms-x86-intrinsics.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-x86-intrinsics.c?rev=298538&r1=298537&r2=298538&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ms-x86-intrinsics.c (original)
+++ cfe/trunk/test/CodeGen/ms-x86-intrinsics.c Wed Mar 22 14:13:13 2017
@@ -6,15 +6,37 @@
 // RUN:         | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X64
 
 #if defined(__i386__)
+char test__readfsbyte(unsigned long Offset) {
+  return __readfsbyte(Offset);
+}
+// CHECK-I386-LABEL: define signext i8 @test__readfsbyte(i32 %Offset)
+// CHECK-I386:   [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i8 addrspace(257)*
+// CHECK-I386:   [[VALUE:%[0-9]+]] = load volatile i8, i8 addrspace(257)* [[PTR]], align 1
+// CHECK-I386:   ret i8 [[VALUE:%[0-9]+]]
+
+short test__readfsword(unsigned long Offset) {
+  return __readfsword(Offset);
+}
+// CHECK-I386-LABEL: define signext i16 @test__readfsword(i32 %Offset)
+// CHECK-I386:   [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i16 addrspace(257)*
+// CHECK-I386:   [[VALUE:%[0-9]+]] = load volatile i16, i16 addrspace(257)* [[PTR]], align 2
+// CHECK-I386:   ret i16 [[VALUE:%[0-9]+]]
+
 long test__readfsdword(unsigned long Offset) {
   return __readfsdword(Offset);
 }
-
-// CHECK-I386-LABEL: define i32 @test__readfsdword(i32 %Offset){{.*}}{
+// CHECK-I386-LABEL: define i32 @test__readfsdword(i32 %Offset)
 // CHECK-I386:   [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i32 addrspace(257)*
 // CHECK-I386:   [[VALUE:%[0-9]+]] = load volatile i32, i32 addrspace(257)* [[PTR]], align 4
 // CHECK-I386:   ret i32 [[VALUE:%[0-9]+]]
-// CHECK-I386: }
+
+long long test__readfsqword(unsigned long Offset) {
+  return __readfsqword(Offset);
+}
+// CHECK-I386-LABEL: define i64 @test__readfsqword(i32 %Offset)
+// CHECK-I386:   [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i64 addrspace(257)*
+// CHECK-I386:   [[VALUE:%[0-9]+]] = load volatile i64, i64 addrspace(257)* [[PTR]], align 8
+// CHECK-I386:   ret i64 [[VALUE:%[0-9]+]]
 #endif
 
 __int64 test__emul(int a, int b) {
@@ -36,6 +58,43 @@ unsigned __int64 test__emulu(unsigned in
 // CHECK: ret i64 [[RES]]
 
 #if defined(__x86_64__)
+
+char test__readgsbyte(unsigned long Offset) {
+  return __readgsbyte(Offset);
+}
+// CHECK-X64-LABEL: define i8 @test__readgsbyte(i32 %Offset)
+// CHECK-X64:   [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
+// CHECK-X64:   [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i8 addrspace(256)*
+// CHECK-X64:   [[VALUE:%[0-9]+]] = load volatile i8, i8 addrspace(256)* [[PTR]], align 1
+// CHECK-X64:   ret i8 [[VALUE:%[0-9]+]]
+
+short test__readgsword(unsigned long Offset) {
+  return __readgsword(Offset);
+}
+// CHECK-X64-LABEL: define i16 @test__readgsword(i32 %Offset)
+// CHECK-X64:   [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
+// CHECK-X64:   [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i16 addrspace(256)*
+// CHECK-X64:   [[VALUE:%[0-9]+]] = load volatile i16, i16 addrspace(256)* [[PTR]], align 2
+// CHECK-X64:   ret i16 [[VALUE:%[0-9]+]]
+
+long test__readgsdword(unsigned long Offset) {
+  return __readgsdword(Offset);
+}
+// CHECK-X64-LABEL: define i32 @test__readgsdword(i32 %Offset)
+// CHECK-X64:   [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
+// CHECK-X64:   [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i32 addrspace(256)*
+// CHECK-X64:   [[VALUE:%[0-9]+]] = load volatile i32, i32 addrspace(256)* [[PTR]], align 4
+// CHECK-X64:   ret i32 [[VALUE:%[0-9]+]]
+
+long long test__readgsqword(unsigned long Offset) {
+  return __readgsqword(Offset);
+}
+// CHECK-X64-LABEL: define i64 @test__readgsqword(i32 %Offset)
+// CHECK-X64:   [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
+// CHECK-X64:   [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i64 addrspace(256)*
+// CHECK-X64:   [[VALUE:%[0-9]+]] = load volatile i64, i64 addrspace(256)* [[PTR]], align 8
+// CHECK-X64:   ret i64 [[VALUE:%[0-9]+]]
+
 __int64 test__mulh(__int64 a, __int64 b) {
   return __mulh(a, b);
 }




More information about the cfe-commits mailing list