r284253 - Implement __stosb intrinsic as a volatile memset
Author: agutowski Date: Fri Oct 14 12:33:05 2016 New Revision: 284253 URL: http://llvm.org/viewvc/llvm-project?rev=284253=rev Log: Implement __stosb intrinsic as a volatile memset Summary: We need `__stosb` to be an intrinsic, because SecureZeroMemory function uses it without including intrin.h. Implementing it as a volatile memset is not consistent with MSDN specification, but it gives us target-independent IR while keeping the most important properties of `__stosb`. Reviewers: rnk, hans, thakis, majnemer Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25334 Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/intrin.h cfe/trunk/test/CodeGen/ms-intrinsics.c cfe/trunk/test/Headers/ms-intrin.cpp Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=284253=284252=284253=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Fri Oct 14 12:33:05 2016 @@ -2041,6 +2041,8 @@ TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "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=284253=284252=284253=diff == --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Fri Oct 14 12:33:05 2016 @@ -7770,6 +7770,11 @@ Value *CodeGenFunction::EmitX86BuiltinEx Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); return Builder.CreateCall(F); } + case X86::BI__stosb: { +// We treat __stosb as a volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized away. +return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true); + } } } Modified: cfe/trunk/lib/Headers/intrin.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/intrin.h?rev=284253=284252=284253=diff == --- cfe/trunk/lib/Headers/intrin.h (original) +++ cfe/trunk/lib/Headers/intrin.h Fri Oct 14 12:33:05 2016 @@ -1024,11 +1024,6 @@ __movsw(unsigned short *__dst, unsigned : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Modified: cfe/trunk/test/CodeGen/ms-intrinsics.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-intrinsics.c?rev=284253=284252=284253=diff == --- cfe/trunk/test/CodeGen/ms-intrinsics.c (original) +++ cfe/trunk/test/CodeGen/ms-intrinsics.c Fri Oct 14 12:33:05 2016 @@ -14,6 +14,22 @@ typedef __SIZE_TYPE__ size_t; #include +#if defined(__i386__) || defined(__x86_64__) +void test__stosb(unsigned char *Dest, unsigned char Data, size_t Count) { + return __stosb(Dest, Data, Count); +} + +// CHECK-I386: define{{.*}}void @test__stosb +// CHECK-I386: tail call void @llvm.memset.p0i8.i32(i8* %Dest, i8 %Data, i32 %Count, i32 1, i1 true) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64: define{{.*}}void @test__stosb +// CHECK-X64: tail call void @llvm.memset.p0i8.i64(i8* %Dest, i8 %Data, i64 %Count, i32 1, i1 true) +// CHECK-X64: ret void +// CHECK-X64: } +#endif + void *test_ReturnAddress() { return _ReturnAddress(); } Modified: cfe/trunk/test/Headers/ms-intrin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Headers/ms-intrin.cpp?rev=284253=284252=284253=diff == --- cfe/trunk/test/Headers/ms-intrin.cpp (original) +++ cfe/trunk/test/Headers/ms-intrin.cpp Fri Oct 14 12:33:05 2016 @@ -38,7 +38,6 @@ void f() { __movsd(0, 0, 0); __movsw(0, 0, 0); - __stosb(0, 0, 0); __stosd(0, 0, 0); __stosw(0, 0, 0); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25334: Implement __stosb intrinsic as a volatile memset
agutowski updated this revision to Diff 74603. agutowski added a comment. force the alignment to 1 https://reviews.llvm.org/D25334 Files: include/clang/Basic/BuiltinsX86.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c test/Headers/ms-intrin.cpp Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1024,11 +1024,6 @@ : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7770,7 +7770,12 @@ Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); return Builder.CreateCall(F); } + case X86::BI__stosb: { +// We treat __stosb as a volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized away. +return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true); } + } } Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2041,6 +2041,8 @@ TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Index: test/CodeGen/ms-intrinsics.c === --- test/CodeGen/ms-intrinsics.c +++ test/CodeGen/ms-intrinsics.c @@ -14,6 +14,22 @@ #include +#if defined(__i386__) || defined(__x86_64__) +void test__stosb(unsigned char *Dest, unsigned char Data, size_t Count) { + return __stosb(Dest, Data, Count); +} + +// CHECK-I386: define{{.*}}void @test__stosb +// CHECK-I386: tail call void @llvm.memset.p0i8.i32(i8* %Dest, i8 %Data, i32 %Count, i32 1, i1 true) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64: define{{.*}}void @test__stosb +// CHECK-X64: tail call void @llvm.memset.p0i8.i64(i8* %Dest, i8 %Data, i64 %Count, i32 1, i1 true) +// CHECK-X64: ret void +// CHECK-X64: } +#endif + void *test_ReturnAddress() { return _ReturnAddress(); } Index: test/Headers/ms-intrin.cpp === --- test/Headers/ms-intrin.cpp +++ test/Headers/ms-intrin.cpp @@ -38,7 +38,6 @@ __movsd(0, 0, 0); __movsw(0, 0, 0); - __stosb(0, 0, 0); __stosd(0, 0, 0); __stosw(0, 0, 0); Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1024,11 +1024,6 @@ : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7770,7 +7770,12 @@ Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); return Builder.CreateCall(F); } + case X86::BI__stosb: { +// We treat __stosb as a volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized away. +return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true); } + } } Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2041,6 +2041,8 @@ TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Index: test/CodeGen/ms-intrinsics.c === --- test/CodeGen/ms-intrinsics.c +++ test/CodeGen/ms-intrinsics.c @@ -14,6 +14,22 @@ #include +#if defined(__i386__) ||
[PATCH] D25334: Implement __stosb intrinsic as a volatile memset
agutowski updated this revision to Diff 74596. agutowski added a comment. rebase https://reviews.llvm.org/D25334 Files: include/clang/Basic/BuiltinsX86.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c test/Headers/ms-intrin.cpp Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1024,11 +1024,6 @@ : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7770,7 +7770,13 @@ Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); return Builder.CreateCall(F); } + case X86::BI__stosb: { +// We treat __stosb as a volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized away. +Address Dest = EmitPointerWithAlignment(E->getArg(0)); +return Builder.CreateMemSet(Dest, Ops[1], Ops[2], true); } + } } Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2041,6 +2041,8 @@ TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Index: test/CodeGen/ms-intrinsics.c === --- test/CodeGen/ms-intrinsics.c +++ test/CodeGen/ms-intrinsics.c @@ -14,6 +14,22 @@ #include +#if defined(__i386__) || defined(__x86_64__) +void test__stosb(unsigned char *Dest, unsigned char Data, size_t Count) { + return __stosb(Dest, Data, Count); +} + +// CHECK-I386: define{{.*}}void @test__stosb +// CHECK-I386: tail call void @llvm.memset.p0i8.i32(i8* %Dest, i8 %Data, i32 %Count, i32 1, i1 true) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64: define{{.*}}void @test__stosb +// CHECK-X64: tail call void @llvm.memset.p0i8.i64(i8* %Dest, i8 %Data, i64 %Count, i32 1, i1 true) +// CHECK-X64: ret void +// CHECK-X64: } +#endif + void *test_ReturnAddress() { return _ReturnAddress(); } Index: test/Headers/ms-intrin.cpp === --- test/Headers/ms-intrin.cpp +++ test/Headers/ms-intrin.cpp @@ -38,7 +38,6 @@ __movsd(0, 0, 0); __movsw(0, 0, 0); - __stosb(0, 0, 0); __stosd(0, 0, 0); __stosw(0, 0, 0); Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1024,11 +1024,6 @@ : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7770,7 +7770,13 @@ Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); return Builder.CreateCall(F); } + case X86::BI__stosb: { +// We treat __stosb as a volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized away. +Address Dest = EmitPointerWithAlignment(E->getArg(0)); +return Builder.CreateMemSet(Dest, Ops[1], Ops[2], true); } + } } Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2041,6 +2041,8 @@ TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Index: test/CodeGen/ms-intrinsics.c === --- test/CodeGen/ms-intrinsics.c +++
r284172 - Add 64-bit MS _Interlocked functions as builtins again
Author: agutowski Date: Thu Oct 13 17:35:07 2016 New Revision: 284172 URL: http://llvm.org/viewvc/llvm-project?rev=284172=rev Log: Add 64-bit MS _Interlocked functions as builtins again Summary: Previously global 64-bit versions of _Interlocked functions broke buildbots on i386, so now I'm adding them as builtins for x86-64 and ARM only (should they be also on AArch64? I had problems with testing it for AArch64, so I left it) Reviewers: hans, majnemer, mstorsjo, rnk Subscribers: cfe-commits, aemerson Differential Revision: https://reviews.llvm.org/D25576 Modified: cfe/trunk/include/clang/Basic/BuiltinsARM.def cfe/trunk/include/clang/Basic/BuiltinsX86_64.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/intrin.h cfe/trunk/test/CodeGen/ms-intrinsics.c Modified: cfe/trunk/include/clang/Basic/BuiltinsARM.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsARM.def?rev=284172=284171=284172=diff == --- cfe/trunk/include/clang/Basic/BuiltinsARM.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsARM.def Thu Oct 13 17:35:07 2016 @@ -138,6 +138,15 @@ TARGET_HEADER_BUILTIN(_BitScanReverse, " TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*","nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchange64,"LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*","nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef LANGBUILTIN #undef TARGET_HEADER_BUILTIN Modified: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86_64.def?rev=284172=284171=284172=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86_64.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86_64.def Thu Oct 13 17:35:07 2016 @@ -32,6 +32,15 @@ TARGET_HEADER_BUILTIN(_umul128, "ULLiULL TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*","nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchange64,"LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*","nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "") TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "") TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse") Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=284172=284171=284172=diff == --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Thu Oct 13 17:35:07 2016 @@ -463,6 +463,107 @@ CodeGenFunction::emitBuiltinObjectSize(c return Builder.CreateCall(F, {EmitScalarExpr(E), CI}); } +// Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we +// handle them here. +enum class CodeGenFunction::MSVCIntrin { + _BitScanForward, + _BitScanReverse, + _InterlockedAnd, + _InterlockedDecrement, + _InterlockedExchange, + _InterlockedExchangeAdd, + _InterlockedExchangeSub, + _InterlockedIncrement, + _InterlockedOr, + _InterlockedXor, +}; + +Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, + const CallExpr *E) { + switch (BuiltinID) { + case MSVCIntrin::_BitScanForward: + case
r284167 - fix _BitScan intrinsics missing header warnings; fix some line endings
Author: agutowski Date: Thu Oct 13 16:55:16 2016 New Revision: 284167 URL: http://llvm.org/viewvc/llvm-project?rev=284167=rev Log: fix _BitScan intrinsics missing header warnings; fix some line endings Modified: cfe/trunk/include/clang/Basic/BuiltinsARM.def cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/include/clang/Basic/BuiltinsX86_64.def cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Modified: cfe/trunk/include/clang/Basic/BuiltinsARM.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsARM.def?rev=284167=284166=284167=diff == --- cfe/trunk/include/clang/Basic/BuiltinsARM.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsARM.def Thu Oct 13 16:55:16 2016 @@ -18,8 +18,8 @@ # define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS) #endif -#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) -# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) +# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif // In libgcc @@ -133,10 +133,10 @@ LANGBUILTIN(_MoveFromCoprocessor2, "UiIU LANGBUILTIN(_MoveToCoprocessor, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES) LANGBUILTIN(_MoveToCoprocessor2, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES) -TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "n", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "n", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "n", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "n", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") #undef BUILTIN #undef LANGBUILTIN Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=284167=284166=284167=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Thu Oct 13 16:55:16 2016 @@ -2029,8 +2029,8 @@ TARGET_BUILTIN(__builtin_ia32_monitorx, TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx") // MSVC -TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "n", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "n", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_ReadBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") Modified: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86_64.def?rev=284167=284166=284167=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86_64.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86_64.def Thu Oct 13 16:55:16 2016 @@ -1,81 +1,81 @@ -//===--- BuiltinsX86_64.def - X86-64 Builtin function database --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===--===// -// -// This file defines the X86-64-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===--===// - -// The format of this database matches clang/Basic/Builtins.def. - -#if defined(BUILTIN) && !defined(TARGET_BUILTIN) -# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif - -#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) -# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif - -TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "n", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "n", "intrin.h", ALL_MS_LANGUAGES, "") - -TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi","nch",
[PATCH] D25576: Add 64-bit MS _Interlocked functions as builtins again
agutowski updated this revision to Diff 74586. agutowski added a comment. make target-independent Interlocked builtins use EmitMSVCBuiltinExpr https://reviews.llvm.org/D25576 Files: include/clang/Basic/BuiltinsARM.def include/clang/Basic/BuiltinsX86_64.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -387,25 +387,13 @@ void *_Exchange, void *_Comparand); void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination, void *_Exchange, void *_Comparand); -static __inline__ -__int64 _InterlockedDecrement64(__int64 volatile *_Addend); -static __inline__ -__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value); -static __inline__ -__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value); void *_InterlockedExchangePointer(void *volatile *_Target, void *_Value); -static __inline__ -__int64 _InterlockedIncrement64(__int64 volatile *_Addend); long _InterlockedOr_np(long volatile *_Value, long _Mask); short _InterlockedOr16_np(short volatile *_Value, short _Mask); -static __inline__ -__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask); __int64 _InterlockedOr64_np(__int64 volatile *_Value, __int64 _Mask); char _InterlockedOr8_np(char volatile *_Value, char _Mask); long _InterlockedXor_np(long volatile *_Value, long _Mask); short _InterlockedXor16_np(short volatile *_Value, short _Mask); -static __inline__ -__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask); __int64 _InterlockedXor64_np(__int64 volatile *_Value, __int64 _Mask); char _InterlockedXor8_np(char volatile *_Value, char _Mask); unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int); @@ -428,6 +416,27 @@ #endif /* __x86_64__ */ +#if defined(__x86_64__) || defined(__arm__) + +static __inline__ +__int64 _InterlockedDecrement64(__int64 volatile *_Addend); +static __inline__ +__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value); +static __inline__ +__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value); +static __inline__ +__int64 _InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value); +static __inline__ +__int64 _InterlockedIncrement64(__int64 volatile *_Addend); +static __inline__ +__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask); +static __inline__ +__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask); +static __inline__ +__int64 _InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask); + +#endif + /**\ |* Bit Counting and Testing \**/ @@ -545,15 +554,7 @@ _InterlockedExchangeAdd_rel(long volatile *_Addend, long _Value) { return __atomic_fetch_add(_Addend, _Value, __ATOMIC_RELEASE); } -#endif -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); -} -#endif -#if defined(__arm__) || defined(__aarch64__) -static __inline__ __int64 __DEFAULT_FN_ATTRS _InterlockedExchangeAdd64_acq(__int64 volatile *_Addend, __int64 _Value) { return __atomic_fetch_add(_Addend, _Value, __ATOMIC_ACQUIRE); } @@ -567,15 +568,6 @@ } #endif /**\ -|* Interlocked Exchange Sub -\**/ -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -} -#endif -/**\ |* Interlocked Increment \**/ #if defined(__arm__) || defined(__aarch64__) @@ -603,15 +595,7 @@ _InterlockedIncrement_rel(long volatile *_Value) { return __atomic_add_fetch(_Value, 1, __ATOMIC_RELEASE); } -#endif -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedIncrement64(__int64 volatile *_Value) { - return __atomic_add_fetch(_Value, 1, __ATOMIC_SEQ_CST); -} -#endif -#if defined(__arm__) || defined(__aarch64__) -static __inline__ __int64 __DEFAULT_FN_ATTRS _InterlockedIncrement64_acq(__int64 volatile *_Value) { return __atomic_add_fetch(_Value, 1, __ATOMIC_ACQUIRE); } @@ -652,15 +636,7 @@ _InterlockedDecrement_rel(long volatile
[PATCH] D25576: Add 64-bit MS _Interlocked functions as builtins again
agutowski added inline comments. Comment at: lib/CodeGen/CGBuiltin.cpp:2730 +llvm::AtomicOrdering::SequentiallyConsistent); +return Builder.CreateSub(RMWI, ConstantInt::get(IntTy, 1)); } rnk wrote: > Can you make a helper similar to MakeBinaryAtomicValue for inc/dec and share > this code with the 16 and 32-bit atomic increment implementations? You can do > something like `Builder.CreateBinOp(Inc ? Instruction::Add : > Instruction::Sub, ...)` I thought about putting all the _Interlocked intrinsics here. Or do we want all the others to remain target-independent? https://reviews.llvm.org/D25576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25576: Add 64-bit MS _Interlocked functions as builtins again
agutowski created this revision. agutowski added reviewers: rnk, hans, majnemer, mstorsjo. agutowski added a subscriber: cfe-commits. Herald added a subscriber: aemerson. Previously global 64-bit versions of _Interlocked functions broke buildbots on i386, so now I'm adding them as builtins for x86-64 and ARM only (should they be also on AArch64? I had problems with testing it for AArch64, so I left it) https://reviews.llvm.org/D25576 Files: include/clang/Basic/BuiltinsARM.def include/clang/Basic/BuiltinsX86_64.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -387,25 +387,13 @@ void *_Exchange, void *_Comparand); void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination, void *_Exchange, void *_Comparand); -static __inline__ -__int64 _InterlockedDecrement64(__int64 volatile *_Addend); -static __inline__ -__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value); -static __inline__ -__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value); void *_InterlockedExchangePointer(void *volatile *_Target, void *_Value); -static __inline__ -__int64 _InterlockedIncrement64(__int64 volatile *_Addend); long _InterlockedOr_np(long volatile *_Value, long _Mask); short _InterlockedOr16_np(short volatile *_Value, short _Mask); -static __inline__ -__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask); __int64 _InterlockedOr64_np(__int64 volatile *_Value, __int64 _Mask); char _InterlockedOr8_np(char volatile *_Value, char _Mask); long _InterlockedXor_np(long volatile *_Value, long _Mask); short _InterlockedXor16_np(short volatile *_Value, short _Mask); -static __inline__ -__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask); __int64 _InterlockedXor64_np(__int64 volatile *_Value, __int64 _Mask); char _InterlockedXor8_np(char volatile *_Value, char _Mask); unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int); @@ -428,6 +416,27 @@ #endif /* __x86_64__ */ +#if defined(__x86_64__) || defined(__arm__) + +static __inline__ +__int64 _InterlockedDecrement64(__int64 volatile *_Addend); +static __inline__ +__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value); +static __inline__ +__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value); +static __inline__ +__int64 _InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value); +static __inline__ +__int64 _InterlockedIncrement64(__int64 volatile *_Addend); +static __inline__ +__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask); +static __inline__ +__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask); +static __inline__ +__int64 _InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask); + +#endif + /**\ |* Bit Counting and Testing \**/ @@ -545,15 +554,7 @@ _InterlockedExchangeAdd_rel(long volatile *_Addend, long _Value) { return __atomic_fetch_add(_Addend, _Value, __ATOMIC_RELEASE); } -#endif -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); -} -#endif -#if defined(__arm__) || defined(__aarch64__) -static __inline__ __int64 __DEFAULT_FN_ATTRS _InterlockedExchangeAdd64_acq(__int64 volatile *_Addend, __int64 _Value) { return __atomic_fetch_add(_Addend, _Value, __ATOMIC_ACQUIRE); } @@ -567,15 +568,6 @@ } #endif /**\ -|* Interlocked Exchange Sub -\**/ -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -} -#endif -/**\ |* Interlocked Increment \**/ #if defined(__arm__) || defined(__aarch64__) @@ -603,15 +595,7 @@ _InterlockedIncrement_rel(long volatile *_Value) { return __atomic_add_fetch(_Value, 1, __ATOMIC_RELEASE); } -#endif -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedIncrement64(__int64 volatile *_Value) { - return __atomic_add_fetch(_Value, 1, __ATOMIC_SEQ_CST); -} -#endif -#if
r284131 - Implement MS _ReturnAddress and _AddressOfReturnAddress intrinsics
Author: agutowski Date: Thu Oct 13 11:03:42 2016 New Revision: 284131 URL: http://llvm.org/viewvc/llvm-project?rev=284131=rev Log: Implement MS _ReturnAddress and _AddressOfReturnAddress intrinsics Reviewers: rnk, thakis, majnemer, hans Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25540 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-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=284131=284130=284131=diff == --- cfe/trunk/include/clang/Basic/Builtins.def (original) +++ cfe/trunk/include/clang/Basic/Builtins.def Thu Oct 13 11:03:42 2016 @@ -753,6 +753,7 @@ LANGBUILTIN(__popcnt16, "UsUs", "nc" 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) LANGBUILTIN(_rotl, "UiUii", "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=284131=284130=284131=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Thu Oct 13 11:03:42 2016 @@ -2039,6 +2039,8 @@ TARGET_HEADER_BUILTIN(_WriteBarrier, TARGET_HEADER_BUILTIN(__emul, "LLiii","nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "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=284131=284130=284131=diff == --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Thu Oct 13 11:03:42 2016 @@ -1147,6 +1147,10 @@ RValue CodeGenFunction::EmitBuiltinExpr( Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); return RValue::get(Builder.CreateCall(F, Depth)); } + case Builtin::BI_ReturnAddress: { +Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); +return RValue::get(Builder.CreateCall(F, Builder.getInt32(0))); + } case Builtin::BI__builtin_frame_address: { Value *Depth = CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this); @@ -7697,6 +7701,10 @@ Value *CodeGenFunction::EmitX86BuiltinEx case X86::BI_BitScanReverse: case X86::BI_BitScanReverse64: return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); + case X86::BI_AddressOfReturnAddress: { +Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); +return Builder.CreateCall(F); + } } } Modified: cfe/trunk/lib/Headers/intrin.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/intrin.h?rev=284131=284130=284131=diff == --- cfe/trunk/lib/Headers/intrin.h (original) +++ cfe/trunk/lib/Headers/intrin.h Thu Oct 13 11:03:42 2016 @@ -1112,14 +1112,6 @@ __stosq(unsigned __int64 *__dst, unsigne /**\ |* Misc \**/ -static __inline__ void * __DEFAULT_FN_ATTRS -_AddressOfReturnAddress(void) { - return (void*)((char*)__builtin_frame_address(0) + sizeof(void*)); -} -static __inline__ void * __DEFAULT_FN_ATTRS -_ReturnAddress(void) { - return __builtin_return_address(0); -} #if defined(__i386__) || defined(__x86_64__) static __inline__ void __DEFAULT_FN_ATTRS __cpuid(int __info[4], int __level) { Modified: cfe/trunk/test/CodeGen/ms-intrinsics.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-intrinsics.c?rev=284131=284130=284131=diff == --- cfe/trunk/test/CodeGen/ms-intrinsics.c (original) +++ cfe/trunk/test/CodeGen/ms-intrinsics.c Thu Oct 13 11:03:42 2016 @@ -1,12 +1,12 @@ // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple i686--windows -Oz -emit-llvm %s -o - \ -// RUN: | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-I386 +// RUN:
[PATCH] D25540: Implement MS _ReturnAddress and _AddressOfReturnAddress intrinsics
agutowski updated this revision to Diff 74533. agutowski added a comment. change checking prefix for x86 tests; use Int32 instead of UnsignedIntTy https://reviews.llvm.org/D25540 Files: include/clang/Basic/Builtins.def include/clang/Basic/BuiltinsX86.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1112,14 +1112,6 @@ /**\ |* Misc \**/ -static __inline__ void * __DEFAULT_FN_ATTRS -_AddressOfReturnAddress(void) { - return (void*)((char*)__builtin_frame_address(0) + sizeof(void*)); -} -static __inline__ void * __DEFAULT_FN_ATTRS -_ReturnAddress(void) { - return __builtin_return_address(0); -} #if defined(__i386__) || defined(__x86_64__) static __inline__ void __DEFAULT_FN_ATTRS __cpuid(int __info[4], int __level) { Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -1147,6 +1147,10 @@ Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); return RValue::get(Builder.CreateCall(F, Depth)); } + case Builtin::BI_ReturnAddress: { +Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); +return RValue::get(Builder.CreateCall(F, Builder.getInt32(0))); + } case Builtin::BI__builtin_frame_address: { Value *Depth = CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this); @@ -7697,7 +7701,11 @@ case X86::BI_BitScanReverse: case X86::BI_BitScanReverse64: return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); + case X86::BI_AddressOfReturnAddress: { +Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); +return Builder.CreateCall(F); } + } } Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2039,6 +2039,8 @@ TARGET_HEADER_BUILTIN(__emul, "LLiii","nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Index: include/clang/Basic/Builtins.def === --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -753,6 +753,7 @@ 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) LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES) Index: test/CodeGen/ms-intrinsics.c === --- test/CodeGen/ms-intrinsics.c +++ test/CodeGen/ms-intrinsics.c @@ -1,12 +1,12 @@ // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple i686--windows -Oz -emit-llvm %s -o - \ -// RUN: | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-I386 +// RUN: | FileCheck %s -check-prefixes CHECK,CHECK-I386,CHECK-INTEL // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple thumbv7--windows -Oz -emit-llvm %s -o - \ -// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM-X64 +// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-ARM-X64 // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple x86_64--windows -Oz -emit-llvm %s -o - \ -// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X64 --check-prefix=CHECK-ARM-X64 +// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-X64,CHECK-ARM-X64,CHECK-INTEL // intrin.h needs size_t, but -ffreestanding prevents us from getting it from // stddef.h. Work around it with this typedef. @@ -14,6 +14,22 @@ #include +void *test_ReturnAddress() { + return _ReturnAddress(); +} +// CHECK-LABEL: define{{.*}}i8* @test_ReturnAddress() +// CHECK: = tail call i8* @llvm.returnaddress(i32 0) +// CHECK: ret i8* + +#if defined(__i386__) || defined(__x86_64__) +void *test_AddressOfReturnAddress() { + return _AddressOfReturnAddress(); +} +// CHECK-INTEL-LABEL: define i8* @test_AddressOfReturnAddress() +// CHECK-INTEL: = tail call i8* @llvm.addressofreturnaddress() +//
[PATCH] D25540: Implement MS _ReturnAddress and _AddressOfReturnAddress intrinsics
agutowski created this revision. agutowski added reviewers: rnk, hans, thakis, majnemer. agutowski added a subscriber: cfe-commits. https://reviews.llvm.org/D25540 Files: include/clang/Basic/Builtins.def include/clang/Basic/BuiltinsX86.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1112,14 +1112,6 @@ /**\ |* Misc \**/ -static __inline__ void * __DEFAULT_FN_ATTRS -_AddressOfReturnAddress(void) { - return (void*)((char*)__builtin_frame_address(0) + sizeof(void*)); -} -static __inline__ void * __DEFAULT_FN_ATTRS -_ReturnAddress(void) { - return __builtin_return_address(0); -} #if defined(__i386__) || defined(__x86_64__) static __inline__ void __DEFAULT_FN_ATTRS __cpuid(int __info[4], int __level) { Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -1147,6 +1147,12 @@ Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); return RValue::get(Builder.CreateCall(F, Depth)); } + case Builtin::BI_ReturnAddress: { +Value *Depth = +Constant::getNullValue(ConvertType(getContext().UnsignedIntTy)); +Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); +return RValue::get(Builder.CreateCall(F, Depth)); + } case Builtin::BI__builtin_frame_address: { Value *Depth = CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this); @@ -7697,7 +7703,11 @@ case X86::BI_BitScanReverse: case X86::BI_BitScanReverse64: return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); + case X86::BI_AddressOfReturnAddress: { +Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); +return Builder.CreateCall(F); } + } } Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2039,6 +2039,8 @@ TARGET_HEADER_BUILTIN(__emul, "LLiii","nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Index: include/clang/Basic/Builtins.def === --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -753,6 +753,7 @@ 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) LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES) Index: test/CodeGen/ms-intrinsics.c === --- test/CodeGen/ms-intrinsics.c +++ test/CodeGen/ms-intrinsics.c @@ -1,12 +1,12 @@ // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple i686--windows -Oz -emit-llvm %s -o - \ -// RUN: | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-I386 +// RUN: | FileCheck %s -check-prefixes CHECK,CHECK-I386,CHECK-X86 // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple thumbv7--windows -Oz -emit-llvm %s -o - \ -// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM-X64 +// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-ARM-X64 // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple x86_64--windows -Oz -emit-llvm %s -o - \ -// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X64 --check-prefix=CHECK-ARM-X64 +// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-X64,CHECK-ARM-X64,CHECK-X86 // intrin.h needs size_t, but -ffreestanding prevents us from getting it from // stddef.h. Work around it with this typedef. @@ -14,6 +14,22 @@ #include +void *test_ReturnAddress() { + return _ReturnAddress(); +} +// CHECK-LABEL: define{{.*}}i8* @test_ReturnAddress() +// CHECK: = tail call i8* @llvm.returnaddress(i32 0) +// CHECK: ret i8* + +#if defined(__i386__) || defined(__x86_64__) +void *test_AddressOfReturnAddress() { + return _AddressOfReturnAddress(); +} +// CHECK-X86-LABEL: define i8* @test_AddressOfReturnAddress() +//
r284083 - fix ms-intrinsics labels code to work with builds with assertions
Author: agutowski Date: Wed Oct 12 18:52:38 2016 New Revision: 284083 URL: http://llvm.org/viewvc/llvm-project?rev=284083=rev Log: fix ms-intrinsics labels code to work with builds with assertions Modified: cfe/trunk/test/CodeGen/ms-intrinsics.c Modified: cfe/trunk/test/CodeGen/ms-intrinsics.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-intrinsics.c?rev=284083=284082=284083=diff == --- cfe/trunk/test/CodeGen/ms-intrinsics.c (original) +++ cfe/trunk/test/CodeGen/ms-intrinsics.c Wed Oct 12 18:52:38 2016 @@ -20,10 +20,10 @@ unsigned char test_BitScanForward(unsign // CHECK: define{{.*}}i8 @test_BitScanForward(i32* {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i32 %Mask, 0 // CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] -// CHECK: ; :[[END_LABEL]]: +// CHECK: [[END_LABEL]]: // CHECK: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] // CHECK: ret i8 [[RESULT]] -// CHECK: ; :[[ISNOTZERO_LABEL]]: +// CHECK: [[ISNOTZERO_LABEL]]: // CHECK: [[INDEX:%[0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %Mask, i1 true) // CHECK: store i32 [[INDEX]], i32* %Index, align 4 // CHECK: br label %[[END_LABEL]] @@ -34,10 +34,10 @@ unsigned char test_BitScanReverse(unsign // CHECK: define{{.*}}i8 @test_BitScanReverse(i32* {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK: [[ISNOTZERO:%[0-9]+]] = icmp eq i32 %Mask, 0 // CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] -// CHECK: ; :[[END_LABEL]]: +// CHECK: [[END_LABEL]]: // CHECK: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] // CHECK: ret i8 [[RESULT]] -// CHECK: ; :[[ISNOTZERO_LABEL]]: +// CHECK: [[ISNOTZERO_LABEL]]: // CHECK: [[REVINDEX:%[0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %Mask, i1 true) // CHECK: [[INDEX:%[0-9]+]] = xor i32 [[REVINDEX]], 31 // CHECK: store i32 [[INDEX]], i32* %Index, align 4 @@ -50,10 +50,10 @@ unsigned char test_BitScanForward64(unsi // CHECK-ARM-X64: define{{.*}}i8 @test_BitScanForward64(i32* {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK-ARM-X64: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i64 %Mask, 0 // CHECK-ARM-X64: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] -// CHECK-ARM-X64: ; :[[END_LABEL]]: +// CHECK-ARM-X64: [[END_LABEL]]: // CHECK-ARM-X64: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] // CHECK-ARM-X64: ret i8 [[RESULT]] -// CHECK-ARM-X64: ; :[[ISNOTZERO_LABEL]]: +// CHECK-ARM-X64: [[ISNOTZERO_LABEL]]: // CHECK-ARM-X64: [[INDEX:%[0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %Mask, i1 true) // CHECK-ARM-X64: [[TRUNC_INDEX:%[0-9]+]] = trunc i64 [[INDEX]] to i32 // CHECK-ARM-X64: store i32 [[TRUNC_INDEX]], i32* %Index, align 4 @@ -65,10 +65,10 @@ unsigned char test_BitScanReverse64(unsi // CHECK-ARM-X64: define{{.*}}i8 @test_BitScanReverse64(i32* {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK-ARM-X64: [[ISNOTZERO:%[0-9]+]] = icmp eq i64 %Mask, 0 // CHECK-ARM-X64: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] -// CHECK-ARM-X64: ; :[[END_LABEL]]: +// CHECK-ARM-X64: [[END_LABEL]]: // CHECK-ARM-X64: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] // CHECK-ARM-X64: ret i8 [[RESULT]] -// CHECK-ARM-X64: ; :[[ISNOTZERO_LABEL]]: +// CHECK-ARM-X64: [[ISNOTZERO_LABEL]]: // CHECK-ARM-X64: [[REVINDEX:%[0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %Mask, i1 true) // CHECK-ARM-X64: [[TRUNC_REVINDEX:%[0-9]+]] = trunc i64 [[REVINDEX]] to i32 // CHECK-ARM-X64: [[INDEX:%[0-9]+]] = xor i32 [[TRUNC_REVINDEX]], 63 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r284062 - fix regexes for label names in ms-intrinsics test
Author: agutowski Date: Wed Oct 12 17:22:34 2016 New Revision: 284062 URL: http://llvm.org/viewvc/llvm-project?rev=284062=rev Log: fix regexes for label names in ms-intrinsics test Modified: cfe/trunk/test/CodeGen/ms-intrinsics.c Modified: cfe/trunk/test/CodeGen/ms-intrinsics.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-intrinsics.c?rev=284062=284061=284062=diff == --- cfe/trunk/test/CodeGen/ms-intrinsics.c (original) +++ cfe/trunk/test/CodeGen/ms-intrinsics.c Wed Oct 12 17:22:34 2016 @@ -19,9 +19,9 @@ unsigned char test_BitScanForward(unsign } // CHECK: define{{.*}}i8 @test_BitScanForward(i32* {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i32 %Mask, 0 -// CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9.]+]], label %[[ISNOTZERO_LABEL:[0-9]+]] +// CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK: ; :[[END_LABEL]]: -// CHECK: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[0-9]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] +// CHECK: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] // CHECK: ret i8 [[RESULT]] // CHECK: ; :[[ISNOTZERO_LABEL]]: // CHECK: [[INDEX:%[0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %Mask, i1 true) @@ -33,9 +33,9 @@ unsigned char test_BitScanReverse(unsign } // CHECK: define{{.*}}i8 @test_BitScanReverse(i32* {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK: [[ISNOTZERO:%[0-9]+]] = icmp eq i32 %Mask, 0 -// CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9.]+]], label %[[ISNOTZERO_LABEL:[0-9]+]] +// CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK: ; :[[END_LABEL]]: -// CHECK: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[0-9]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] +// CHECK: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] // CHECK: ret i8 [[RESULT]] // CHECK: ; :[[ISNOTZERO_LABEL]]: // CHECK: [[REVINDEX:%[0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %Mask, i1 true) @@ -49,9 +49,9 @@ unsigned char test_BitScanForward64(unsi } // CHECK-ARM-X64: define{{.*}}i8 @test_BitScanForward64(i32* {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK-ARM-X64: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i64 %Mask, 0 -// CHECK-ARM-X64: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9.]+]], label %[[ISNOTZERO_LABEL:[0-9]+]] +// CHECK-ARM-X64: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK-ARM-X64: ; :[[END_LABEL]]: -// CHECK-ARM-X64: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[0-9]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] +// CHECK-ARM-X64: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] // CHECK-ARM-X64: ret i8 [[RESULT]] // CHECK-ARM-X64: ; :[[ISNOTZERO_LABEL]]: // CHECK-ARM-X64: [[INDEX:%[0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %Mask, i1 true) @@ -64,9 +64,9 @@ unsigned char test_BitScanReverse64(unsi } // CHECK-ARM-X64: define{{.*}}i8 @test_BitScanReverse64(i32* {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK-ARM-X64: [[ISNOTZERO:%[0-9]+]] = icmp eq i64 %Mask, 0 -// CHECK-ARM-X64: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9.]+]], label %[[ISNOTZERO_LABEL:[0-9]+]] +// CHECK-ARM-X64: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK-ARM-X64: ; :[[END_LABEL]]: -// CHECK-ARM-X64: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[0-9]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] +// CHECK-ARM-X64: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] // CHECK-ARM-X64: ret i8 [[RESULT]] // CHECK-ARM-X64: ; :[[ISNOTZERO_LABEL]]: // CHECK-ARM-X64: [[REVINDEX:%[0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %Mask, i1 true) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r284060 - Implement MS _BitScan intrinsics
Author: agutowski Date: Wed Oct 12 17:01:05 2016 New Revision: 284060 URL: http://llvm.org/viewvc/llvm-project?rev=284060=rev Log: Implement MS _BitScan intrinsics Summary: _BitScan intrinsics (and some others, for example _Interlocked and _bittest) are supposed to work on both ARM and x86. This is an attempt to isolate them, avoiding repeating their code or writing separate function for each builtin. Reviewers: hans, thakis, rnk, majnemer Subscribers: RKSimon, cfe-commits, aemerson Differential Revision: https://reviews.llvm.org/D25264 Modified: cfe/trunk/include/clang/Basic/BuiltinsARM.def cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/include/clang/Basic/BuiltinsX86_64.def cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/lib/Headers/intrin.h cfe/trunk/test/CodeGen/ms-intrinsics.c Modified: cfe/trunk/include/clang/Basic/BuiltinsARM.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsARM.def?rev=284060=284059=284060=diff == --- cfe/trunk/include/clang/Basic/BuiltinsARM.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsARM.def Wed Oct 12 17:01:05 2016 @@ -18,6 +18,10 @@ # define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS) #endif +#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) +# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + // In libgcc BUILTIN(__clear_cache, "vv*v*", "i") @@ -129,5 +133,11 @@ LANGBUILTIN(_MoveFromCoprocessor2, "UiIU LANGBUILTIN(_MoveToCoprocessor, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES) LANGBUILTIN(_MoveToCoprocessor2, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES) +TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "n", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "n", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "n", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "n", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef LANGBUILTIN +#undef TARGET_HEADER_BUILTIN Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=284060=284059=284060=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Wed Oct 12 17:01:05 2016 @@ -2028,6 +2028,10 @@ TARGET_BUILTIN(__builtin_ia32_selectpd_5 TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx") TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx") +// MSVC +TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "n", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "n", "intrin.h", ALL_MS_LANGUAGES, "") + 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, "") Modified: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86_64.def?rev=284060=284059=284060=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86_64.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86_64.def Wed Oct 12 17:01:05 2016 @@ -22,6 +22,9 @@ # define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif +TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "n", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "n", "intrin.h", ALL_MS_LANGUAGES, "") + TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi","nch", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") Modified: cfe/trunk/lib/Basic/Targets.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=284060=284059=284060=diff == --- cfe/trunk/lib/Basic/Targets.cpp (original) +++ cfe/trunk/lib/Basic/Targets.cpp Wed Oct 12 17:01:05 2016 @@ -5588,6 +5588,8 @@ const Builtin::Info ARMTargetInfo::Built { #ID, TYPE, ATTRS, nullptr, LANG, nullptr }, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER,
[PATCH] D25264: Implement MS _BitScan intrinsics
agutowski updated this revision to Diff 74435. agutowski added a comment. rebase https://reviews.llvm.org/D25264 Files: include/clang/Basic/BuiltinsARM.def include/clang/Basic/BuiltinsX86.def include/clang/Basic/BuiltinsX86_64.def lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -432,20 +432,6 @@ |* Bit Counting and Testing \**/ static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanForward(unsigned long *_Index, unsigned long _Mask) { - if (!_Mask) -return 0; - *_Index = __builtin_ctzl(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanReverse(unsigned long *_Index, unsigned long _Mask) { - if (!_Mask) -return 0; - *_Index = 31 - __builtin_clzl(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest(long const *_BitBase, long _BitPos) { return (*_BitBase >> _BitPos) & 1; } @@ -491,20 +477,6 @@ #endif #ifdef __x86_64__ static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask) { - if (!_Mask) -return 0; - *_Index = __builtin_ctzll(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask) { - if (!_Mask) -return 0; - *_Index = 63 - __builtin_clzll(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest64(__int64 const *_BitBase, __int64 _BitPos) { return (*_BitBase >> _BitPos) & 1; } Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -2637,6 +2637,68 @@ } } +// Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we +// handle them here. +enum class CodeGenFunction::MSVCIntrin { + _BitScanForward, + _BitScanReverse +}; + +Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, +const CallExpr *E) { + switch (BuiltinID) { + case MSVCIntrin::_BitScanForward: + case MSVCIntrin::_BitScanReverse: { +Value *ArgValue = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = ArgValue->getType(); +llvm::Type *IndexType = +EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType(); +llvm::Type *ResultType = ConvertType(E->getType()); + +Value *ArgZero = llvm::Constant::getNullValue(ArgType); +Value *ResZero = llvm::Constant::getNullValue(ResultType); +Value *ResOne = llvm::ConstantInt::get(ResultType, 1); + +BasicBlock *Begin = Builder.GetInsertBlock(); +BasicBlock *End = createBasicBlock("bitscan_end", this->CurFn); +Builder.SetInsertPoint(End); +PHINode *Result = Builder.CreatePHI(ResultType, 2, "bitscan_result"); + +Builder.SetInsertPoint(Begin); +Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero); +BasicBlock *NotZero = createBasicBlock("bitscan_not_zero", this->CurFn); +Builder.CreateCondBr(IsZero, End, NotZero); +Result->addIncoming(ResZero, Begin); + +Builder.SetInsertPoint(NotZero); +Address IndexAddress = EmitPointerWithAlignment(E->getArg(0)); + +if (BuiltinID == MSVCIntrin::_BitScanForward) { + Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); + Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); + ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); + Builder.CreateStore(ZeroCount, IndexAddress, false); +} else { + unsigned ArgWidth = cast(ArgType)->getBitWidth(); + Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1); + + Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); + Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); + ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); + Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount); + Builder.CreateStore(Index, IndexAddress, false); +} +Builder.CreateBr(End); +Result->addIncoming(ResOne, NotZero); + +Builder.SetInsertPoint(End); +return Result; + } + } + llvm_unreachable("Incorrect MSVC intrinsic!"); +} + Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) { @@ -4561,6 +4623,12 @@ return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0], Ops[3], Ops[4], Ops[5]}); } + case ARM::BI_BitScanForward: + case ARM::BI_BitScanForward64: +return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); + case
r284026 - Move x86-64 builtins from SemaChecking.cpp to BuiltinsX86_64.def
Author: agutowski Date: Wed Oct 12 12:28:44 2016 New Revision: 284026 URL: http://llvm.org/viewvc/llvm-project?rev=284026=rev Log: Move x86-64 builtins from SemaChecking.cpp to BuiltinsX86_64.def Summary: Follow-up to https://reviews.llvm.org/D24598 (separating builtins for x84-64 and i386). Reviewers: hans, thakis, rnk Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25494 Added: cfe/trunk/test/Sema/builtins-x86_64.c Removed: cfe/trunk/test/CodeGen/builtins-x86-disabled.c Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/include/clang/Basic/BuiltinsX86_64.def cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/lib/Sema/SemaChecking.cpp Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=284026=284025=284026=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Wed Oct 12 12:28:44 2016 @@ -48,9 +48,7 @@ TARGET_BUILTIN(__builtin_ia32_undef512, // FLAGS // TARGET_BUILTIN(__builtin_ia32_readeflags_u32, "Ui", "n", "") -TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "") TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "") -TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "") // 3DNow! // @@ -310,8 +308,6 @@ TARGET_BUILTIN(__builtin_ia32_stmxcsr, " TARGET_HEADER_BUILTIN(_mm_getcsr, "Ui", "h", "xmmintrin.h", ALL_LANGUAGES, "sse") TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "", "sse") -TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse") -TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "", "sse") @@ -338,8 +334,6 @@ TARGET_BUILTIN(__builtin_ia32_cvtpd2ps, TARGET_BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvttsd2si, "iV2d", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtsd2ss, "V4fV4fV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "", "sse2") @@ -424,7 +418,6 @@ TARGET_BUILTIN(__builtin_ia32_pcmpestriz TARGET_BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "", "sse4.2") TARGET_BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "", "sse4.2") TARGET_BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "", "sse4.2") -TARGET_BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "", "sse4.2") // SSE4a TARGET_BUILTIN(__builtin_ia32_extrqi, "V2LLiV2LLiIcIc", "", "sse4a") @@ -638,65 +631,44 @@ TARGET_BUILTIN(__builtin_ia32_rdrand64_s // FSGSBASE TARGET_BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "", "fsgsbase") // FXSR TARGET_BUILTIN(__builtin_ia32_fxrstor, "vv*", "", "fxsr") -TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "", "fxsr") TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "", "fxsr") -TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "", "fxsr") // XSAVE TARGET_BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "", "xsave") -TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "", "xsave") TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "", "xsave") -TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "", "xsave") TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "", "xsaveopt") -TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "", "xsaveopt") TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "", "xsaves") -TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "", "xsaves") TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "", "xsavec") -TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec") TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves") -TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves") //CLFLUSHOPT TARGET_BUILTIN(__builtin_ia32_clflushopt, "vc*", "", "clflushopt") // ADX TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx") -TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx") TARGET_BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "", "")
[PATCH] D25494: Move x86-64 builtins from SemaChecking.cpp to BuiltinsX86_64.def
agutowski updated this revision to Diff 74398. agutowski added a comment. add -fno-spell-checking to tests https://reviews.llvm.org/D25494 Files: include/clang/Basic/BuiltinsX86.def include/clang/Basic/BuiltinsX86_64.def lib/Basic/Targets.cpp lib/Sema/SemaChecking.cpp test/CodeGen/builtins-x86-disabled.c test/Sema/builtins-x86_64.c Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -1590,58 +1590,6 @@ return false; } -static bool isX86_64Builtin(unsigned BuiltinID) { - // These builtins only work on x86-64 targets. - switch (BuiltinID) { - case X86::BI__builtin_ia32_addcarryx_u64: - case X86::BI__builtin_ia32_addcarry_u64: - case X86::BI__builtin_ia32_subborrow_u64: - case X86::BI__builtin_ia32_readeflags_u64: - case X86::BI__builtin_ia32_writeeflags_u64: - case X86::BI__builtin_ia32_bextr_u64: - case X86::BI__builtin_ia32_bextri_u64: - case X86::BI__builtin_ia32_bzhi_di: - case X86::BI__builtin_ia32_pdep_di: - case X86::BI__builtin_ia32_pext_di: - case X86::BI__builtin_ia32_crc32di: - case X86::BI__builtin_ia32_fxsave64: - case X86::BI__builtin_ia32_fxrstor64: - case X86::BI__builtin_ia32_xsave64: - case X86::BI__builtin_ia32_xrstor64: - case X86::BI__builtin_ia32_xsaveopt64: - case X86::BI__builtin_ia32_xrstors64: - case X86::BI__builtin_ia32_xsavec64: - case X86::BI__builtin_ia32_xsaves64: - case X86::BI__builtin_ia32_rdfsbase64: - case X86::BI__builtin_ia32_rdgsbase64: - case X86::BI__builtin_ia32_wrfsbase64: - case X86::BI__builtin_ia32_wrgsbase64: - case X86::BI__builtin_ia32_pbroadcastq512_gpr_mask: - case X86::BI__builtin_ia32_pbroadcastq256_gpr_mask: - case X86::BI__builtin_ia32_pbroadcastq128_gpr_mask: - case X86::BI__builtin_ia32_vcvtsd2si64: - case X86::BI__builtin_ia32_vcvtsd2usi64: - case X86::BI__builtin_ia32_vcvtss2si64: - case X86::BI__builtin_ia32_vcvtss2usi64: - case X86::BI__builtin_ia32_vcvttsd2si64: - case X86::BI__builtin_ia32_vcvttsd2usi64: - case X86::BI__builtin_ia32_vcvttss2si64: - case X86::BI__builtin_ia32_vcvttss2usi64: - case X86::BI__builtin_ia32_cvtss2si64: - case X86::BI__builtin_ia32_cvttss2si64: - case X86::BI__builtin_ia32_cvtsd2si64: - case X86::BI__builtin_ia32_cvttsd2si64: - case X86::BI__builtin_ia32_cvtsi2sd64: - case X86::BI__builtin_ia32_cvtsi2ss64: - case X86::BI__builtin_ia32_cvtusi2sd64: - case X86::BI__builtin_ia32_cvtusi2ss64: - case X86::BI__builtin_ia32_rdseed64_step: -return true; - } - - return false; -} - // Check if the rounding mode is legal. bool Sema::CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) { // Indicates if this instruction has rounding control or just SAE. @@ -1838,12 +1786,6 @@ if (BuiltinID == X86::BI__builtin_ms_va_start) return SemaBuiltinMSVAStart(TheCall); - // Check for 64-bit only builtins on a 32-bit target. - const llvm::Triple = Context.getTargetInfo().getTriple(); - if (TT.getArch() != llvm::Triple::x86_64 && isX86_64Builtin(BuiltinID)) -return Diag(TheCall->getCallee()->getLocStart(), -diag::err_x86_builtin_32_bit_tgt); - // If the intrinsic has rounding or SAE make sure its valid. if (CheckX86BuiltinRoundingOrSAE(BuiltinID, TheCall)) return true; Index: lib/Basic/Targets.cpp === --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -2362,6 +2362,8 @@ #define BUILTIN(ID, TYPE, ATTRS) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, #include "clang/Basic/BuiltinsX86_64.def" Index: include/clang/Basic/BuiltinsX86_64.def === --- include/clang/Basic/BuiltinsX86_64.def +++ include/clang/Basic/BuiltinsX86_64.def @@ -14,6 +14,10 @@ // The format of this database matches clang/Basic/Builtins.def. +#if defined(BUILTIN) && !defined(TARGET_BUILTIN) +# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + #if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) # define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif @@ -25,6 +29,50 @@ TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "") +TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "") +TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "", "sse2")
[PATCH] D25494: Move x86-64 builtins from SemaChecking.cpp to BuiltinsX86_64.def
agutowski added inline comments. Comment at: test/Sema/builtins-x86_64.c:17 + v8ll vec8longlongs; + (void)__builtin_ia32_readeflags_u64(); // expected-error{{use of unknown builtin}} expected-note 0+ {{}} + (void)__builtin_ia32_writeeflags_u64(4); // expected-error{{use of unknown builtin}} expected-note 0+ {{}} Is there some way to ignore all notes? I needed to handle typo-correction notes (like: `did you mean '__builtin_ia32_readeflags_u32'`). https://reviews.llvm.org/D25494 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25494: Move x86-64 builtins from SemaChecking.cpp to BuiltinsX86_64.def
agutowski created this revision. agutowski added reviewers: rnk, hans, thakis. agutowski added a subscriber: cfe-commits. Follow-up to https://reviews.llvm.org/D24598 (separating builtins for x84-64 and i386). https://reviews.llvm.org/D25494 Files: include/clang/Basic/BuiltinsX86.def include/clang/Basic/BuiltinsX86_64.def lib/Basic/Targets.cpp lib/Sema/SemaChecking.cpp test/CodeGen/builtins-x86-disabled.c test/Sema/builtins-x86_64.c Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -1590,58 +1590,6 @@ return false; } -static bool isX86_64Builtin(unsigned BuiltinID) { - // These builtins only work on x86-64 targets. - switch (BuiltinID) { - case X86::BI__builtin_ia32_addcarryx_u64: - case X86::BI__builtin_ia32_addcarry_u64: - case X86::BI__builtin_ia32_subborrow_u64: - case X86::BI__builtin_ia32_readeflags_u64: - case X86::BI__builtin_ia32_writeeflags_u64: - case X86::BI__builtin_ia32_bextr_u64: - case X86::BI__builtin_ia32_bextri_u64: - case X86::BI__builtin_ia32_bzhi_di: - case X86::BI__builtin_ia32_pdep_di: - case X86::BI__builtin_ia32_pext_di: - case X86::BI__builtin_ia32_crc32di: - case X86::BI__builtin_ia32_fxsave64: - case X86::BI__builtin_ia32_fxrstor64: - case X86::BI__builtin_ia32_xsave64: - case X86::BI__builtin_ia32_xrstor64: - case X86::BI__builtin_ia32_xsaveopt64: - case X86::BI__builtin_ia32_xrstors64: - case X86::BI__builtin_ia32_xsavec64: - case X86::BI__builtin_ia32_xsaves64: - case X86::BI__builtin_ia32_rdfsbase64: - case X86::BI__builtin_ia32_rdgsbase64: - case X86::BI__builtin_ia32_wrfsbase64: - case X86::BI__builtin_ia32_wrgsbase64: - case X86::BI__builtin_ia32_pbroadcastq512_gpr_mask: - case X86::BI__builtin_ia32_pbroadcastq256_gpr_mask: - case X86::BI__builtin_ia32_pbroadcastq128_gpr_mask: - case X86::BI__builtin_ia32_vcvtsd2si64: - case X86::BI__builtin_ia32_vcvtsd2usi64: - case X86::BI__builtin_ia32_vcvtss2si64: - case X86::BI__builtin_ia32_vcvtss2usi64: - case X86::BI__builtin_ia32_vcvttsd2si64: - case X86::BI__builtin_ia32_vcvttsd2usi64: - case X86::BI__builtin_ia32_vcvttss2si64: - case X86::BI__builtin_ia32_vcvttss2usi64: - case X86::BI__builtin_ia32_cvtss2si64: - case X86::BI__builtin_ia32_cvttss2si64: - case X86::BI__builtin_ia32_cvtsd2si64: - case X86::BI__builtin_ia32_cvttsd2si64: - case X86::BI__builtin_ia32_cvtsi2sd64: - case X86::BI__builtin_ia32_cvtsi2ss64: - case X86::BI__builtin_ia32_cvtusi2sd64: - case X86::BI__builtin_ia32_cvtusi2ss64: - case X86::BI__builtin_ia32_rdseed64_step: -return true; - } - - return false; -} - // Check if the rounding mode is legal. bool Sema::CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) { // Indicates if this instruction has rounding control or just SAE. @@ -1838,12 +1786,6 @@ if (BuiltinID == X86::BI__builtin_ms_va_start) return SemaBuiltinMSVAStart(TheCall); - // Check for 64-bit only builtins on a 32-bit target. - const llvm::Triple = Context.getTargetInfo().getTriple(); - if (TT.getArch() != llvm::Triple::x86_64 && isX86_64Builtin(BuiltinID)) -return Diag(TheCall->getCallee()->getLocStart(), -diag::err_x86_builtin_32_bit_tgt); - // If the intrinsic has rounding or SAE make sure its valid. if (CheckX86BuiltinRoundingOrSAE(BuiltinID, TheCall)) return true; Index: lib/Basic/Targets.cpp === --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -2362,6 +2362,8 @@ #define BUILTIN(ID, TYPE, ATTRS) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, #include "clang/Basic/BuiltinsX86_64.def" Index: include/clang/Basic/BuiltinsX86_64.def === --- include/clang/Basic/BuiltinsX86_64.def +++ include/clang/Basic/BuiltinsX86_64.def @@ -14,6 +14,10 @@ // The format of this database matches clang/Basic/Builtins.def. +#if defined(BUILTIN) && !defined(TARGET_BUILTIN) +# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + #if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) # define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif @@ -25,6 +29,50 @@ TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "") +TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "") +TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f",
[PATCH] D25458: Don't create builtin declaration when looking for typo corrections in C++
agutowski added a comment. In https://reviews.llvm.org/D25458#567697, @rnk wrote: > Can you provide a more complete motivating example where our diagnostics were > bad? I'm having a hard time figuring it out from the test Sure, compiling the following program in C++ for i386 emits warnings about implicit declarations of __emul and __emulu: int main() { __umul(1, 2); return 0; } https://reviews.llvm.org/D25458 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25458: Don't create builtin declaration when looking for typo corrections in C++
agutowski added inline comments. Comment at: lib/CodeGen/CGBuiltin.cpp:800 + case Builtin::BI_byteswap_ulong: + case Builtin::BI_byteswap_uint64: case Builtin::BI__builtin_bswap16: thakis wrote: > Is this an unrelated change? Yeah, mostly - I had to fix this for tests to work properly. Comment at: lib/Sema/SemaLookup.cpp:2013 - if (LookupDirect(*this, R, LookupCtx)) { + if (LookupDirect(*this, R, LookupCtx, /*AllowBuiltinCreation=*/true)) { R.resolveKind(); thakis wrote: > Are you passing `false` anywhere? I can't find it (but I'm probably just > blind) :-) Yes, it's not visible in the changelist - in line ~4305, in "LookupPotentialTypoResult": ``` SemaRef.LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false, EnteringContext); ``` https://reviews.llvm.org/D25458 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25458: Don't create builtin declaration when looking for typo corrections in C++
agutowski created this revision. agutowski added reviewers: rnk, hans, majnemer, thakis. agutowski added a subscriber: cfe-commits. Declarations for the builtins were created when suspected of being corrections for a typo. That could trigger some absurd warnings about missing headers. https://reviews.llvm.org/D25458 Files: include/clang/Sema/Sema.h lib/CodeGen/CGBuiltin.cpp lib/Sema/SemaLookup.cpp test/Sema/implicit-ms-builtin-decl.cpp Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -795,6 +795,9 @@ Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume); return RValue::get(Builder.CreateCall(FnAssume, ArgValue)); } + case Builtin::BI_byteswap_ushort: + case Builtin::BI_byteswap_ulong: + case Builtin::BI_byteswap_uint64: case Builtin::BI__builtin_bswap16: case Builtin::BI__builtin_bswap32: case Builtin::BI__builtin_bswap64: { Index: lib/Sema/SemaLookup.cpp === --- lib/Sema/SemaLookup.cpp +++ lib/Sema/SemaLookup.cpp @@ -665,7 +665,7 @@ /// \brief Lookup a builtin function, when name lookup would otherwise /// fail. -static bool LookupBuiltin(Sema , LookupResult ) { +static bool LookupBuiltin(Sema , LookupResult , bool AllowBuiltinCreation) { Sema::LookupNameKind NameKind = R.getLookupKind(); // If we didn't find a use of this identifier, and if the identifier @@ -687,6 +687,9 @@ // If this is a builtin on this (or all) targets, create the decl. if (unsigned BuiltinID = II->getBuiltinID()) { +if (!AllowBuiltinCreation) + return false; + // In C++ and OpenCL (spec v1.2 s6.9.f), we don't have any predefined // library functions like 'malloc'. Instead, we'll just error. if ((S.getLangOpts().CPlusPlus || S.getLangOpts().OpenCL) && @@ -820,7 +823,8 @@ // Adds all qualifying matches for a name within a decl context to the // given lookup result. Returns true if any matches were found. -static bool LookupDirect(Sema , LookupResult , const DeclContext *DC) { +static bool LookupDirect(Sema , LookupResult , const DeclContext *DC, + bool AllowBuiltinCreation) { bool Found = false; // Lazily declare C++ special member functions. @@ -838,7 +842,8 @@ } } - if (!Found && DC->isTranslationUnit() && LookupBuiltin(S, R)) + if (!Found && DC->isTranslationUnit() && + LookupBuiltin(S, R, AllowBuiltinCreation)) return true; if (R.getLookupName().getNameKind() @@ -912,19 +917,19 @@ } // Performs C++ unqualified lookup into the given file context. -static bool -CppNamespaceLookup(Sema , LookupResult , ASTContext , - DeclContext *NS, UnqualUsingDirectiveSet ) { +static bool CppNamespaceLookup(Sema , LookupResult , ASTContext , + DeclContext *NS, UnqualUsingDirectiveSet , + bool AllowBuiltinCreation) { assert(NS && NS->isFileContext() && "CppNamespaceLookup() requires namespace!"); // Perform direct name lookup into the LookupCtx. - bool Found = LookupDirect(S, R, NS); + bool Found = LookupDirect(S, R, NS, AllowBuiltinCreation); // Perform direct name lookup into the namespaces nominated by the // using directives whose common ancestor is this namespace. for (const UnqualUsingEntry : UDirs.getNamespacesFor(NS)) -if (LookupDirect(S, R, UUE.getNominatedNamespace())) +if (LookupDirect(S, R, UUE.getNominatedNamespace(), AllowBuiltinCreation)) Found = true; R.resolveKind(); @@ -1027,7 +1032,7 @@ }; } // end anonymous namespace -bool Sema::CppLookupName(LookupResult , Scope *S) { +bool Sema::CppLookupName(LookupResult , Scope *S, bool AllowBuiltinCreation) { assert(getLangOpts().CPlusPlus && "Can perform only C++ lookup"); DeclarationName Name = R.getLookupName(); @@ -1198,7 +1203,8 @@ VisitedUsingDirectives = true; } - if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs)) { + if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs, + AllowBuiltinCreation)) { R.resolveKind(); return true; } @@ -1298,7 +1304,8 @@ "We should have been looking only at file context here already."); // Look into context considering using-directives. - if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs)) + if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs, + AllowBuiltinCreation)) Found = true; } @@ -1787,14 +1794,14 @@ } } else { // Perform C++ unqualified name lookup. -if (CppLookupName(R, S)) +if (CppLookupName(R, S, AllowBuiltinCreation)) return true; } // If we didn't find a use of this identifier, and if the identifier
r283793 - Implement MS read/write barriers and __faststorefence intrinsic
Author: agutowski Date: Mon Oct 10 14:40:51 2016 New Revision: 283793 URL: http://llvm.org/viewvc/llvm-project?rev=283793=rev Log: Implement MS read/write barriers and __faststorefence intrinsic Reviewers: hans, rnk, majnemer Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25442 Added: cfe/trunk/test/CodeGen/ms-barriers-intrinsics.c Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/include/clang/Basic/BuiltinsX86_64.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/intrin.h Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=283793=283792=283793=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Mon Oct 10 14:40:51 2016 @@ -2071,6 +2071,10 @@ TARGET_BUILTIN(__builtin_ia32_selectpd_5 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, "") Modified: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86_64.def?rev=283793=283792=283793=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86_64.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86_64.def Mon Oct 10 14:40:51 2016 @@ -23,5 +23,8 @@ TARGET_HEADER_BUILTIN(__umulh, "ULLiULLi 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 Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=283793=283792=283793=diff == --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Mon Oct 10 14:40:51 2016 @@ -7612,6 +7612,17 @@ Value *CodeGenFunction::EmitX86BuiltinEx 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); + } } } Modified: cfe/trunk/lib/Headers/intrin.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/intrin.h?rev=283793=283792=283793=diff == --- cfe/trunk/lib/Headers/intrin.h (original) +++ cfe/trunk/lib/Headers/intrin.h Mon Oct 10 14:40:51 2016 @@ -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, uns 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(__int6 } #endif /**\ -|* Barriers
[PATCH] D25334: Implement __stosb intrinsic as a volatile memset
agutowski marked 2 inline comments as done. agutowski added inline comments. Comment at: lib/CodeGen/CGBuiltin.cpp:7610 +Value *SizeVal = EmitScalarExpr(E->getArg(2)); +EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), +E->getArg(0)->getExprLoc(), FD, 0); hans wrote: > Hmm, does the __stosb intrinsic require Dest to be non-null (e.g. would > Dest=NULL, Count=0 be OK?) I'm not even sure what llvm's memset requires > actually. I can't find any guarantee that memset accepts Dest=NULL and Count=0. So I guess we can either add a branch here, checking if the pointer is NULL (and that Count=0?) or assume that memset won't do anything strange. I vote for the latter (the current code does it). https://reviews.llvm.org/D25334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25334: Implement __stosb intrinsic as a volatile memset
agutowski updated this revision to Diff 74157. agutowski added a comment. remove nullptr check; don't repeat EmitScalarExpr https://reviews.llvm.org/D25334 Files: include/clang/Basic/BuiltinsX86.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c test/Headers/ms-intrin.cpp Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1148,11 +1148,6 @@ : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7599,7 +7599,14 @@ HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); return HigherBits; } + + case X86::BI__stosb: { +// We treat __stosb as a volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized away. +Address Dest = EmitPointerWithAlignment(E->getArg(0)); +return Builder.CreateMemSet(Dest, Ops[1], Ops[2], true); } + } } Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2071,6 +2071,8 @@ TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx") TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx") +TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Index: test/CodeGen/ms-intrinsics.c === --- test/CodeGen/ms-intrinsics.c +++ test/CodeGen/ms-intrinsics.c @@ -14,6 +14,22 @@ #include +#if defined(__i386__) || defined(__x86_64__) +void test__stosb(unsigned char *Dest, unsigned char Data, size_t Count) { + return __stosb(Dest, Data, Count); +} + +// CHECK-I386: define{{.*}}void @test__stosb +// CHECK-I386: tail call void @llvm.memset.p0i8.i32(i8* %Dest, i8 %Data, i32 %Count, i32 1, i1 true) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64: define{{.*}}void @test__stosb +// CHECK-X64: tail call void @llvm.memset.p0i8.i64(i8* %Dest, i8 %Data, i64 %Count, i32 1, i1 true) +// CHECK-X64: ret void +// CHECK-X64: } +#endif + void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) { return _InterlockedExchangePointer(Target, Value); } Index: test/Headers/ms-intrin.cpp === --- test/Headers/ms-intrin.cpp +++ test/Headers/ms-intrin.cpp @@ -38,7 +38,6 @@ __movsd(0, 0, 0); __movsw(0, 0, 0); - __stosb(0, 0, 0); __stosd(0, 0, 0); __stosw(0, 0, 0); Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1148,11 +1148,6 @@ : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7599,7 +7599,14 @@ HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); return HigherBits; } + + case X86::BI__stosb: { +// We treat __stosb as a volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized away. +Address Dest = EmitPointerWithAlignment(E->getArg(0)); +return Builder.CreateMemSet(Dest, Ops[1], Ops[2], true); } + } } Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2071,6 +2071,8 @@ TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx") TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx") +TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN
[PATCH] D25442: Implement MS read/write barriers and __faststorefence intrinsic
agutowski created this revision. agutowski added reviewers: majnemer, hans, rnk. agutowski added a subscriber: cfe-commits. https://reviews.llvm.org/D25442 Files: include/clang/Basic/BuiltinsX86.def include/clang/Basic/BuiltinsX86_64.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-barriers-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -254,11 +254,13 @@ unsigned long __cdecl _lrotl(unsigned long, int); static __inline__ unsigned long __cdecl _lrotr(unsigned long, int); +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 _ReadBarrier(void); -static __inline__ -void _ReadWriteBarrier(void); -static __inline__ void *_ReturnAddress(void); unsigned int _rorx_u32(unsigned int, const unsigned int); static __inline__ @@ -286,8 +288,9 @@ 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__ @@ -1063,30 +1066,6 @@ } #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.) Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7599,7 +7599,18 @@ HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); return HigherBits; } + + 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); + } + } } Index: include/clang/Basic/BuiltinsX86_64.def === --- include/clang/Basic/BuiltinsX86_64.def +++ include/clang/Basic/BuiltinsX86_64.def @@ -21,5 +21,8 @@ TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi","nch", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + + #undef BUILTIN #undef TARGET_HEADER_BUILTIN Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2071,6 +2071,10 @@ 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, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Index: test/CodeGen/ms-barriers-intrinsics.c === --- /dev/null +++ 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
r283785 - Implement __emul, __emulu, _mul128 and _umul128 MS intrinsics
Author: agutowski Date: Mon Oct 10 13:09:27 2016 New Revision: 283785 URL: http://llvm.org/viewvc/llvm-project?rev=283785=rev Log: Implement __emul, __emulu, _mul128 and _umul128 MS intrinsics Reviewers: rnk, thakis, majnemer, hans Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25353 Added: cfe/trunk/test/CodeGen/ms-x86-intrinsics.c Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/include/clang/Basic/BuiltinsX86_64.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/intrin.h cfe/trunk/test/CodeGen/ms-intrinsics.c Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=283785=283784=283785=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Mon Oct 10 13:09:27 2016 @@ -2071,6 +2071,9 @@ TARGET_BUILTIN(__builtin_ia32_selectpd_5 TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx") TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx") +TARGET_HEADER_BUILTIN(__emul, "LLiii","nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Modified: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86_64.def?rev=283785=283784=283785=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86_64.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86_64.def Mon Oct 10 13:09:27 2016 @@ -20,6 +20,8 @@ TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi","nch", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_umul128, "ULLiULLiULLiULLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") #undef 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=283785=283784=283785=diff == --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Mon Oct 10 13:09:27 2016 @@ -7576,16 +7576,24 @@ Value *CodeGenFunction::EmitX86BuiltinEx case X86::BI__builtin_ia32_cmpordsd: return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7); + case X86::BI__emul: + case X86::BI__emulu: { +llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64); +bool isSigned = (BuiltinID == X86::BI__emul); +Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned); +Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned); +return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned); + } case X86::BI__mulh: - case X86::BI__umulh: { -Value *LHS = EmitScalarExpr(E->getArg(0)); -Value *RHS = EmitScalarExpr(E->getArg(1)); + case X86::BI__umulh: + case X86::BI_mul128: + case X86::BI_umul128: { llvm::Type *ResType = ConvertType(E->getType()); llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); -bool IsSigned = (BuiltinID == X86::BI__mulh); -LHS = Builder.CreateIntCast(LHS, Int128Ty, IsSigned); -RHS = Builder.CreateIntCast(RHS, Int128Ty, IsSigned); +bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128); +Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned); +Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned); Value *MulResult, *HigherBits; if (IsSigned) { @@ -7595,9 +7603,14 @@ Value *CodeGenFunction::EmitX86BuiltinEx MulResult = Builder.CreateNUWMul(LHS, RHS); HigherBits = Builder.CreateLShr(MulResult, 64); } - HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); -return HigherBits; + +if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh) + return HigherBits; + +Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2)); +Builder.CreateStore(HigherBits, HighBitsAddress); +return Builder.CreateIntCast(MulResult, ResType, IsSigned); } } } Modified: cfe/trunk/lib/Headers/intrin.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/intrin.h?rev=283785=283784=283785=diff == --- cfe/trunk/lib/Headers/intrin.h (original) +++ cfe/trunk/lib/Headers/intrin.h Mon Oct 10 13:09:27 2016 @@ -66,7 +66,9 @@ void __cpuid(int[4], int); static __inline__ void __cpuidex(int[4], int, int); void
[PATCH] D25353: Implement __emul, __emulu, _mul128 and _umul128 MS intrinsics
agutowski updated this revision to Diff 74147. agutowski added a comment. address comments https://reviews.llvm.org/D25353 Files: include/clang/Basic/BuiltinsX86.def include/clang/Basic/BuiltinsX86_64.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c test/CodeGen/ms-x86-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -66,7 +66,9 @@ static __inline__ void __cpuidex(int[4], int, int); void __debugbreak(void); +static __inline__ __int64 __emul(int, int); +static __inline__ unsigned __int64 __emulu(unsigned int, unsigned int); void __cdecl __fastfail(unsigned int); unsigned int __getcallerseflags(void); @@ -313,8 +315,6 @@ static __inline__ void __movsq(unsigned long long *, unsigned long long const *, size_t); static __inline__ -__int64 __mulh(__int64, __int64); -static __inline__ unsigned __int64 __popcnt64(unsigned __int64); static __inline__ unsigned char __readgsbyte(unsigned long); @@ -405,9 +405,6 @@ __int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask); __int64 _InterlockedXor64_np(__int64 volatile *_Value, __int64 _Mask); char _InterlockedXor8_np(char volatile *_Value, char _Mask); -static __inline__ -__int64 _mul128(__int64 _Multiplier, __int64 _Multiplicand, -__int64 *_HighProduct); unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int); __int64 _sarx_i64(__int64, unsigned int); #if __STDC_HOSTED__ @@ -415,35 +412,20 @@ #endif unsigned __int64 _shlx_u64(unsigned __int64, unsigned int); unsigned __int64 _shrx_u64(unsigned __int64, unsigned int); -/* - * Multiply two 64-bit integers and obtain a 64-bit result. - * The low-half is returned directly and the high half is in an out parameter. - */ -static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS -_umul128(unsigned __int64 _Multiplier, unsigned __int64 _Multiplicand, - unsigned __int64 *_HighProduct) { - unsigned __int128 _FullProduct = - (unsigned __int128)_Multiplier * (unsigned __int128)_Multiplicand; - *_HighProduct = _FullProduct >> 64; - return _FullProduct; -} static __inline__ +__int64 __mulh(__int64, __int64); +static __inline__ unsigned __int64 __umulh(unsigned __int64, unsigned __int64); +static __inline__ +__int64 _mul128(__int64, __int64, __int64*); +static __inline__ +unsigned __int64 _umul128(unsigned __int64, + unsigned __int64, + unsigned __int64*); #endif /* __x86_64__ */ /**\ -|* Multiplication -\**/ -static __inline__ __int64 __DEFAULT_FN_ATTRS -__emul(int __in1, int __in2) { - return (__int64)__in1 * (__int64)__in2; -} -static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS -__emulu(unsigned int __in1, unsigned int __in2) { - return (unsigned __int64)__in1 * (unsigned __int64)__in2; -} -/**\ |* Bit Counting and Testing \**/ static __inline__ unsigned char __DEFAULT_FN_ATTRS Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7576,16 +7576,24 @@ case X86::BI__builtin_ia32_cmpordsd: return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7); + case X86::BI__emul: + case X86::BI__emulu: { +llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64); +bool isSigned = (BuiltinID == X86::BI__emul); +Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned); +Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned); +return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned); + } case X86::BI__mulh: - case X86::BI__umulh: { -Value *LHS = EmitScalarExpr(E->getArg(0)); -Value *RHS = EmitScalarExpr(E->getArg(1)); + case X86::BI__umulh: + case X86::BI_mul128: + case X86::BI_umul128: { llvm::Type *ResType = ConvertType(E->getType()); llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); -bool IsSigned = (BuiltinID == X86::BI__mulh); -LHS = Builder.CreateIntCast(LHS, Int128Ty, IsSigned); -RHS = Builder.CreateIntCast(RHS, Int128Ty, IsSigned); +bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128); +Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned); +Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned); Value *MulResult, *HigherBits; if (IsSigned) { @@ -7595,9 +7603,14 @@ MulResult = Builder.CreateNUWMul(LHS, RHS); HigherBits = Builder.CreateLShr(MulResult, 64); } +HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); -HigherBits
[PATCH] D25334: Implement __stosb intrinsic as a volatile memset
agutowski marked an inline comment as done. agutowski added inline comments. > hans wrote in CGBuiltin.cpp:7613 > Why is it returning Dest here, and not the result of Builder.CreateMemSet? My mistake (that's what memset returns), thanks! https://reviews.llvm.org/D25334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25334: Implement __stosb intrinsic as a volatile memset
agutowski updated this revision to Diff 73828. agutowski marked an inline comment as done. agutowski added a comment. fix return value and comment https://reviews.llvm.org/D25334 Files: include/clang/Basic/BuiltinsX86.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c test/Headers/ms-intrin.cpp Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1148,11 +1148,6 @@ : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7599,7 +7599,19 @@ HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); return HigherBits; } + + case X86::BI__stosb: { +// We treat __stosb as a volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized away. +const FunctionDecl *FD = E->getDirectCallee(); +Address Dest = EmitPointerWithAlignment(E->getArg(0)); +Value *ByteVal = EmitScalarExpr(E->getArg(1)); +Value *SizeVal = EmitScalarExpr(E->getArg(2)); +EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), +E->getArg(0)->getExprLoc(), FD, 0); +return Builder.CreateMemSet(Dest, ByteVal, SizeVal, true); } + } } Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2071,6 +2071,8 @@ TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx") TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx") +TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Index: test/CodeGen/ms-intrinsics.c === --- test/CodeGen/ms-intrinsics.c +++ test/CodeGen/ms-intrinsics.c @@ -14,6 +14,22 @@ #include +#if defined(__i386__) || defined(__x86_64__) +void test__stosb(unsigned char *Dest, unsigned char Data, size_t Count) { + return __stosb(Dest, Data, Count); +} + +// CHECK-I386: define{{.*}}void @test__stosb +// CHECK-I386: tail call void @llvm.memset.p0i8.i32(i8* %Dest, i8 %Data, i32 %Count, i32 1, i1 true) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64: define{{.*}}void @test__stosb +// CHECK-X64: tail call void @llvm.memset.p0i8.i64(i8* %Dest, i8 %Data, i64 %Count, i32 1, i1 true) +// CHECK-X64: ret void +// CHECK-X64: } +#endif + void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) { return _InterlockedExchangePointer(Target, Value); } Index: test/Headers/ms-intrin.cpp === --- test/Headers/ms-intrin.cpp +++ test/Headers/ms-intrin.cpp @@ -38,7 +38,6 @@ __movsd(0, 0, 0); __movsw(0, 0, 0); - __stosb(0, 0, 0); __stosd(0, 0, 0); __stosw(0, 0, 0); Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1148,11 +1148,6 @@ : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7599,7 +7599,19 @@ HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); return HigherBits; } + + case X86::BI__stosb: { +// We treat __stosb as a volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized away. +const FunctionDecl *FD = E->getDirectCallee(); +Address Dest = EmitPointerWithAlignment(E->getArg(0)); +Value *ByteVal = EmitScalarExpr(E->getArg(1)); +Value *SizeVal = EmitScalarExpr(E->getArg(2)); +EmitNonNullArgCheck(RValue::get(Dest.getPointer()),
[PATCH] D25334: Implement __stosb intrinsic as a volatile memset
agutowski created this revision. agutowski added reviewers: rnk, hans, thakis, majnemer. agutowski added a subscriber: cfe-commits. We need __stosb to be an intrinsic, because SecureZeroMemory function uses it without including intrin.h. Implementing it as a volatile memset is not consistent with MSDN specification, but it gives us target-independent IR while keeping the most important properties of __stosb. https://reviews.llvm.org/D25334 Files: include/clang/Basic/BuiltinsX86.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c test/Headers/ms-intrin.cpp Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1148,11 +1148,6 @@ : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7599,7 +7599,20 @@ HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); return HigherBits; } + + case X86::BI__stosb: { +// we treat __stosb as volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized away +const FunctionDecl *FD = E->getDirectCallee(); +Address Dest = EmitPointerWithAlignment(E->getArg(0)); +Value *ByteVal = EmitScalarExpr(E->getArg(1)); +Value *SizeVal = EmitScalarExpr(E->getArg(2)); +EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), +E->getArg(0)->getExprLoc(), FD, 0); +Builder.CreateMemSet(Dest, ByteVal, SizeVal, true); +return Dest.getPointer(); } + } } Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -2071,6 +2071,8 @@ TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx") TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx") +TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN Index: test/CodeGen/ms-intrinsics.c === --- test/CodeGen/ms-intrinsics.c +++ test/CodeGen/ms-intrinsics.c @@ -14,6 +14,22 @@ #include +#if defined(__i386__) || defined(__x86_64__) +void test__stosb(unsigned char *Dest, unsigned char Data, size_t Count) { + return __stosb(Dest, Data, Count); +} + +// CHECK-I386: define{{.*}}void @test__stosb +// CHECK-I386: tail call void @llvm.memset.p0i8.i32(i8* %Dest, i8 %Data, i32 %Count, i32 1, i1 true) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64: define{{.*}}void @test__stosb +// CHECK-X64: tail call void @llvm.memset.p0i8.i64(i8* %Dest, i8 %Data, i64 %Count, i32 1, i1 true) +// CHECK-X64: ret void +// CHECK-X64: } +#endif + void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) { return _InterlockedExchangePointer(Target, Value); } Index: test/Headers/ms-intrin.cpp === --- test/Headers/ms-intrin.cpp +++ test/Headers/ms-intrin.cpp @@ -38,7 +38,6 @@ __movsd(0, 0, 0); __movsw(0, 0, 0); - __stosb(0, 0, 0); __stosd(0, 0, 0); __stosw(0, 0, 0); Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -1148,11 +1148,6 @@ : "%edi", "%esi", "%ecx"); } static __inline__ void __DEFAULT_FN_ATTRS -__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { - __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) -: "%edi", "%ecx"); -} -static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, size_t __n) { __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) : "%edi", "%ecx"); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7599,7 +7599,20 @@ HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); return HigherBits; } + + case X86::BI__stosb: { +// we treat __stosb as volatile memset - it may not generate "rep stosb" +// instruction, but it will create a memset that won't be optimized
[PATCH] D25264: Implement MS _BitScan intrinsics
agutowski added inline comments. > CGBuiltin.cpp:2665 > +BasicBlock *End = createBasicBlock("bitscan_end", this->CurFn); > +Builder.SetInsertPoint(End); > +PHINode *Result = Builder.CreatePHI(ResultType, 2, "bitscan_result"); Is this line needed? I took it from __builtin_fpclassify, but I don't know what could be its purpose (it's repeated below, where the "bitscan_end" block really starts). https://reviews.llvm.org/D25264 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25264: Implement MS _BitScan intrinsics
agutowski updated this revision to Diff 73685. agutowski added a comment. make _BitScan intrinsics compatible with Intel specification when the mask is zero https://reviews.llvm.org/D25264 Files: include/clang/Basic/BuiltinsARM.def include/clang/Basic/BuiltinsX86.def include/clang/Basic/BuiltinsX86_64.def lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -447,20 +447,6 @@ |* Bit Counting and Testing \**/ static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanForward(unsigned long *_Index, unsigned long _Mask) { - if (!_Mask) -return 0; - *_Index = __builtin_ctzl(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanReverse(unsigned long *_Index, unsigned long _Mask) { - if (!_Mask) -return 0; - *_Index = 31 - __builtin_clzl(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest(long const *_BitBase, long _BitPos) { return (*_BitBase >> _BitPos) & 1; } @@ -506,20 +492,6 @@ #endif #ifdef __x86_64__ static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask) { - if (!_Mask) -return 0; - *_Index = __builtin_ctzll(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask) { - if (!_Mask) -return 0; - *_Index = 63 - __builtin_clzll(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest64(__int64 const *_BitBase, __int64 _BitPos) { return (*_BitBase >> _BitPos) & 1; } Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -2637,6 +2637,68 @@ } } +// Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we +// handle them here. +enum class CodeGenFunction::MSVCIntrin { + _BitScanForward, + _BitScanReverse +}; + +Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, +const CallExpr *E) { + switch (BuiltinID) { + case MSVCIntrin::_BitScanForward: + case MSVCIntrin::_BitScanReverse: { +Value *ArgValue = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = ArgValue->getType(); +llvm::Type *IndexType = +EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType(); +llvm::Type *ResultType = ConvertType(E->getType()); + +Value *ArgZero = llvm::Constant::getNullValue(ArgType); +Value *ResZero = llvm::Constant::getNullValue(ResultType); +Value *ResOne = llvm::ConstantInt::get(ResultType, 1); + +BasicBlock *Begin = Builder.GetInsertBlock(); +BasicBlock *End = createBasicBlock("bitscan_end", this->CurFn); +Builder.SetInsertPoint(End); +PHINode *Result = Builder.CreatePHI(ResultType, 2, "bitscan_result"); + +Builder.SetInsertPoint(Begin); +Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero); +BasicBlock *NotZero = createBasicBlock("bitscan_not_zero", this->CurFn); +Builder.CreateCondBr(IsZero, End, NotZero); +Result->addIncoming(ResZero, Begin); + +Builder.SetInsertPoint(NotZero); +Address IndexAddress = EmitPointerWithAlignment(E->getArg(0)); + +if (BuiltinID == MSVCIntrin::_BitScanForward) { + Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); + Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); + ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); + Builder.CreateStore(ZeroCount, IndexAddress, false); +} else { + unsigned ArgWidth = cast(ArgType)->getBitWidth(); + Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1); + + Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); + Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); + ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); + Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount); + Builder.CreateStore(Index, IndexAddress, false); +} +Builder.CreateBr(End); +Result->addIncoming(ResOne, NotZero); + +Builder.SetInsertPoint(End); +return Result; + } + } + llvm_unreachable("Incorrect MSVC intrinsic!"); +} + Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) { @@ -4561,6 +4623,12 @@ return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0], Ops[3], Ops[4], Ops[5]}); } + case ARM::BI_BitScanForward: + case ARM::BI_BitScanForward64: +
[PATCH] D25264: Implement MS _BitScan intrinsics
agutowski updated this revision to Diff 73668. agutowski added a comment. change enum in MSVC namespace to enum class MSVCIntrin in CodeGenFunction; cover all control paths https://reviews.llvm.org/D25264 Files: include/clang/Basic/BuiltinsARM.def include/clang/Basic/BuiltinsX86.def include/clang/Basic/BuiltinsX86_64.def lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -447,20 +447,6 @@ |* Bit Counting and Testing \**/ static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanForward(unsigned long *_Index, unsigned long _Mask) { - if (!_Mask) -return 0; - *_Index = __builtin_ctzl(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanReverse(unsigned long *_Index, unsigned long _Mask) { - if (!_Mask) -return 0; - *_Index = 31 - __builtin_clzl(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest(long const *_BitBase, long _BitPos) { return (*_BitBase >> _BitPos) & 1; } @@ -506,20 +492,6 @@ #endif #ifdef __x86_64__ static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask) { - if (!_Mask) -return 0; - *_Index = __builtin_ctzll(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask) { - if (!_Mask) -return 0; - *_Index = 63 - __builtin_clzll(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest64(__int64 const *_BitBase, __int64 _BitPos) { return (*_BitBase >> _BitPos) & 1; } Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -2637,6 +2637,56 @@ } } +// Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we +// handle them here. +enum class CodeGenFunction::MSVCIntrin { + _BitScanForward, + _BitScanReverse +}; + +Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, +const CallExpr *E) { + switch (BuiltinID) { + case MSVCIntrin::_BitScanForward: + case MSVCIntrin::_BitScanReverse: { +Value *ArgValue = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = ArgValue->getType(); +llvm::Type *IndexType = +EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType(); +llvm::Type *ResultType = ConvertType(E->getType()); + +Value *ArgZero = llvm::Constant::getNullValue(ArgType); +Value *ResZero = llvm::Constant::getNullValue(ResultType); +Value *ResOne = llvm::ConstantInt::get(ResultType, 1); + +Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero); +Value *Result = Builder.CreateSelect(IsZero, ResZero, ResOne); + +Address IndexAddress = EmitPointerWithAlignment(E->getArg(0)); + +if (BuiltinID == MSVCIntrin::_BitScanForward) { + Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); + Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); + ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); + Builder.CreateStore(ZeroCount, IndexAddress, false); +} else { + unsigned ArgWidth = cast(ArgType)->getBitWidth(); + Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1); + + Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); + Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); + ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); + Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount); + Builder.CreateStore(Index, IndexAddress, false); +} + +return Result; + } + } + llvm_unreachable("Incorrect MSVC intrinsic!"); +} + Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) { @@ -4561,6 +4611,12 @@ return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0], Ops[3], Ops[4], Ops[5]}); } + case ARM::BI_BitScanForward: + case ARM::BI_BitScanForward64: +return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); + case ARM::BI_BitScanReverse: + case ARM::BI_BitScanReverse64: +return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); } // Get the last argument, which specifies the vector type. @@ -7599,6 +7655,13 @@ HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); return HigherBits; } + + case X86::BI_BitScanForward: + case X86::BI_BitScanForward64: +return
[PATCH] D25264: Implement MS _BitScan intrinsics
agutowski added inline comments. > majnemer wrote in CGBuiltin.cpp:2640-2647 > This should be in an anonymous namespace. Also, consider using an `enum > class` instead of an `enum` nested inside a namespace. I can see three options: (1) put the existing code inside an anonymous namespace; (2) create a private enum class in CodeGenFunction; (3) pull EmitMSVCBuiltinExpr outside of CodeGenFunction and take CGF object as an argument (and then make enum class inside an anonymous namespace); I don't really like any of them. Enum class sounds nice as I can imagine someone trying to pass the global builtin ID (like X86::BI_BitScanForward) instead of the one from MSVCIntrin namespace (although it should fail on any test; still, it would compile without enum class). But builtins use CGF methods all of the time, so pulling it out will make the code of every bulitin uglier. So I guess I'll try to go with the private enum class inside the CodeGenFunction, but if you have any better ideas, I'm eager to listen. https://reviews.llvm.org/D25264 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25264: Implement MS _BitScan intrinsics
agutowski added inline comments. > majnemer wrote in CGBuiltin.cpp:2656-2684 > Does this do the right thing if the arg is zero? I think it would if you > gave the call to the intrinsic an operand of false instead of true. MSDN doesn't specify what should be put under the "Index" address when the argument is zero; as I checked, VS2015 with optimizations puts undefined value there, and I hope that's what I'm doing here. https://reviews.llvm.org/D25264 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25264: Implement MS _BitScan intrinsics
agutowski created this revision. agutowski added reviewers: rnk, hans, thakis, majnemer. agutowski added a subscriber: cfe-commits. Herald added a subscriber: aemerson. _BitScan intrinsics (and some others, for example _Interlocked and _bittest) are supposed to work on both ARM and x86. This is an attempt to isolate them, avoiding repeating their code or writing separate function for each builtin. https://reviews.llvm.org/D25264 Files: include/clang/Basic/BuiltinsARM.def include/clang/Basic/BuiltinsX86.def include/clang/Basic/BuiltinsX86_64.def lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -447,20 +447,6 @@ |* Bit Counting and Testing \**/ static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanForward(unsigned long *_Index, unsigned long _Mask) { - if (!_Mask) -return 0; - *_Index = __builtin_ctzl(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanReverse(unsigned long *_Index, unsigned long _Mask) { - if (!_Mask) -return 0; - *_Index = 31 - __builtin_clzl(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest(long const *_BitBase, long _BitPos) { return (*_BitBase >> _BitPos) & 1; } @@ -506,20 +492,6 @@ #endif #ifdef __x86_64__ static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask) { - if (!_Mask) -return 0; - *_Index = __builtin_ctzll(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask) { - if (!_Mask) -return 0; - *_Index = 63 - __builtin_clzll(_Mask); - return 1; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest64(__int64 const *_BitBase, __int64 _BitPos) { return (*_BitBase >> _BitPos) & 1; } Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -2637,6 +2637,57 @@ } } +// Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we +// handle them here. +namespace MSVC { + enum { +_BitScanForward, +_BitScanReverse + }; +} + +Value *CodeGenFunction::EmitMSVCBuiltinExpr(unsigned BuiltinID, +const CallExpr *E) { + switch (BuiltinID) { + case MSVC::_BitScanForward: + case MSVC::_BitScanReverse: { +Value *ArgValue = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = ArgValue->getType(); +llvm::Type *IndexType = +EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType(); +llvm::Type *ResultType = ConvertType(E->getType()); + +Value *ArgZero = llvm::Constant::getNullValue(ArgType); +Value *ResZero = llvm::Constant::getNullValue(ResultType); +Value *ResOne = llvm::ConstantInt::get(ResultType, 1); + +Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero); +Value *Result = Builder.CreateSelect(IsZero, ResZero, ResOne); + +Address IndexAddress = EmitPointerWithAlignment(E->getArg(0)); + +if (BuiltinID == MSVC::_BitScanForward) { + Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); + Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); + ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); + Builder.CreateStore(ZeroCount, IndexAddress, false); +} else { + unsigned ArgWidth = cast(ArgType)->getBitWidth(); + Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1); + + Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); + Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); + ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); + Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount); + Builder.CreateStore(Index, IndexAddress, false); +} + +return Result; + } + } +} + Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) { @@ -4561,6 +4612,12 @@ return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0], Ops[3], Ops[4], Ops[5]}); } + case ARM::BI_BitScanForward: + case ARM::BI_BitScanForward64: +return EmitMSVCBuiltinExpr(MSVC::_BitScanForward, E); + case ARM::BI_BitScanReverse: + case ARM::BI_BitScanReverse64: +return EmitMSVCBuiltinExpr(MSVC::_BitScanReverse, E); } // Get the last argument, which specifies the vector type. @@ -7599,6 +7656,13 @@ HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned);
[PATCH] D24598: Separate builtins for x84-64 and i386; implement __mulh and __umulh
This revision was automatically updated to reflect the committed changes. Closed by commit rL283264: Separate builtins for x84-64 and i386; implement __mulh and __umulh (authored by agutowski). Changed prior to commit: https://reviews.llvm.org/D24598?vs=73521=73570#toc Repository: rL LLVM https://reviews.llvm.org/D24598 Files: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def cfe/trunk/include/clang/Basic/TargetBuiltins.h cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/intrin.h cfe/trunk/test/CodeGen/ms-intrinsics.c cfe/trunk/test/Sema/implicit-ms-builtin-decl.c Index: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def === --- cfe/trunk/include/clang/Basic/BuiltinsX86_64.def +++ cfe/trunk/include/clang/Basic/BuiltinsX86_64.def @@ -0,0 +1,25 @@ +//===--- BuiltinsX86_64.def - X86-64 Builtin function database --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// This file defines the X86-64-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. +// +//===--===// + +// The format of this database matches clang/Basic/Builtins.def. + +#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) +# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + +TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi","nch", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "") + +#undef BUILTIN +#undef TARGET_HEADER_BUILTIN Index: cfe/trunk/include/clang/Basic/TargetBuiltins.h === --- cfe/trunk/include/clang/Basic/TargetBuiltins.h +++ cfe/trunk/include/clang/Basic/TargetBuiltins.h @@ -85,12 +85,16 @@ /// \brief X86 builtins namespace X86 { -enum { -LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, + enum { +LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, #define BUILTIN(ID, TYPE, ATTRS) BI##ID, #include "clang/Basic/BuiltinsX86.def" -LastTSBuiltin -}; +FirstX86_64Builtin, +LastX86CommonBuiltin = FirstX86_64Builtin - 1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsX86_64.def" +LastTSBuiltin + }; } /// \brief Flags to identify the types for overloaded Neon builtins. Index: cfe/trunk/test/CodeGen/ms-intrinsics.c === --- cfe/trunk/test/CodeGen/ms-intrinsics.c +++ cfe/trunk/test/CodeGen/ms-intrinsics.c @@ -54,12 +54,17 @@ #endif #if defined(__x86_64__) +__int64 test__mulh(__int64 a, __int64 b) { + return __mulh(a, b); +} +// CHECK-X64-LABEL: define i64 @test__mulh(i64 %a, i64 %b) +// CHECK-X64: = mul nsw i128 % + unsigned __int64 test__umulh(unsigned __int64 a, unsigned __int64 b) { return __umulh(a, b); } // CHECK-X64-LABEL: define i64 @test__umulh(i64 %a, i64 %b) // CHECK-X64: = mul nuw i128 % - #endif char test_InterlockedExchange8(char volatile *value, char mask) { Index: cfe/trunk/test/Sema/implicit-ms-builtin-decl.c === --- cfe/trunk/test/Sema/implicit-ms-builtin-decl.c +++ cfe/trunk/test/Sema/implicit-ms-builtin-decl.c @@ -1,9 +1,10 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -fms-extensions +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify %s -fms-extensions +// RUN: %clang_cc1 -triple i386-unknown-unknown -fsyntax-only -verify %s -fms-extensions void f() { - (void)_byteswap_ushort(42); // expected-warning{{implicitly declaring library function '_byteswap_ushort}} \ + (void)_byteswap_ushort(42); // expected-warning{{implicitly declaring library function '_byteswap_ushort'}} \ // expected-note{{include the header or explicitly provide a declaration for '_byteswap_ushort'}} - (void)_byteswap_uint64(42LL); // expected-warning{{implicitly declaring library function '_byteswap_uint64}} \ + (void)_byteswap_uint64(42LL); // expected-warning{{implicitly declaring library function '_byteswap_uint64'}} \ // expected-note{{include the header or explicitly provide a declaration for '_byteswap_uint64'}} } @@ -17,3 +18,27 @@ (void)_byteswap_ushort(42); (void)_byteswap_uint64(42LL); } + +#if defined(__x86_64__) +void h() { + (void)__mulh(21, 2); // expected-warning{{implicitly declaring library function '__mulh'}} \ + // expected-note{{include the header or explicitly provide a declaration for '__mulh'}} + (void)__umulh(21, 2); // expected-warning{{implicitly declaring library function
r283264 - Separate builtins for x84-64 and i386; implement __mulh and __umulh
Author: agutowski Date: Tue Oct 4 17:29:49 2016 New Revision: 283264 URL: http://llvm.org/viewvc/llvm-project?rev=283264=rev Log: Separate builtins for x84-64 and i386; implement __mulh and __umulh Summary: We need x86-64-specific builtins if we want to implement some of the MS intrinsics - winnt.h contains definitions of some functions for i386, but not for x86-64 (for example _InterlockedOr64), which means that we cannot treat them as builtins for both i386 and x86-64, because then we have definitions of builtin functions in winnt.h on i386. Reviewers: thakis, majnemer, hans, rnk Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D24598 Added: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def Modified: cfe/trunk/include/clang/Basic/TargetBuiltins.h cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/intrin.h cfe/trunk/test/CodeGen/ms-intrinsics.c cfe/trunk/test/Sema/implicit-ms-builtin-decl.c Added: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86_64.def?rev=283264=auto == --- cfe/trunk/include/clang/Basic/BuiltinsX86_64.def (added) +++ cfe/trunk/include/clang/Basic/BuiltinsX86_64.def Tue Oct 4 17:29:49 2016 @@ -0,0 +1,25 @@ +//===--- BuiltinsX86_64.def - X86-64 Builtin function database --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// This file defines the X86-64-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. +// +//===--===// + +// The format of this database matches clang/Basic/Builtins.def. + +#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) +# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + +TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi","nch", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "") + +#undef BUILTIN +#undef TARGET_HEADER_BUILTIN Modified: cfe/trunk/include/clang/Basic/TargetBuiltins.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetBuiltins.h?rev=283264=283263=283264=diff == --- cfe/trunk/include/clang/Basic/TargetBuiltins.h (original) +++ cfe/trunk/include/clang/Basic/TargetBuiltins.h Tue Oct 4 17:29:49 2016 @@ -85,12 +85,16 @@ namespace clang { /// \brief X86 builtins namespace X86 { -enum { -LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, + enum { +LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, #define BUILTIN(ID, TYPE, ATTRS) BI##ID, #include "clang/Basic/BuiltinsX86.def" -LastTSBuiltin -}; +FirstX86_64Builtin, +LastX86CommonBuiltin = FirstX86_64Builtin - 1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsX86_64.def" +LastTSBuiltin + }; } /// \brief Flags to identify the types for overloaded Neon builtins. Modified: cfe/trunk/lib/Basic/Targets.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=283264=283263=283264=diff == --- cfe/trunk/lib/Basic/Targets.cpp (original) +++ cfe/trunk/lib/Basic/Targets.cpp Tue Oct 4 17:29:49 2016 @@ -2329,19 +2329,23 @@ bool AMDGPUTargetInfo::initFeatureMap( return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); } -// Namespace for x86 abstract base class -const Builtin::Info BuiltinInfo[] = { +const Builtin::Info BuiltinInfoX86[] = { #define BUILTIN(ID, TYPE, ATTRS) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, #include "clang/Basic/BuiltinsX86.def" + +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, +#include "clang/Basic/BuiltinsX86_64.def" }; + static const char*
[PATCH] D24598: Separate builtins for x84-64 and i386; implement __mulh and __umulh
agutowski added inline comments. > agutowski wrote in TargetBuiltins.h:100 > Nice, thanks! > As far as I see, it creates some inconsistency in usage of the word "last", > because it's used wrong everywhere else - LastTSBuiltin is the number of the > last target-specific builtin **plus one**, while LastX86CommonBuiltin doesn't > have this additional one. I would leave it like that, but wanted to point > that out, in case you think it's not acceptable. Ah, now I see that LastTIBuiltin is also what its name suggests, so it's only LastTSBuiltin that's different. https://reviews.llvm.org/D24598 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D24598: Separate builtins for x84-64 and i386; implement __mulh and __umulh
agutowski added inline comments. > rnk wrote in TargetBuiltins.h:100 > I think this would be better with just one enum to reduce compilation time: > > /// \brief X86 builtins > namespace X86 { > enum { > LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, > #define BUILTIN(ID, TYPE, ATTRS) BI##ID, > #include "clang/Basic/BuiltinsX86.def" > FirstX86_64Builtin, > LastX86CommonBuiltin = FirstX86_64Builtin - 1, > #define BUILTIN(ID, TYPE, ATTRS) BI##ID, > #include "clang/Basic/BuiltinsX86_64.def" > LastTSBuiltin > }; > } Nice, thanks! As far as I see, it creates some inconsistency in usage of the word "last", because it's used wrong everywhere else - LastTSBuiltin is the number of the last target-specific builtin **plus one**, while LastX86CommonBuiltin doesn't have this additional one. I would leave it like that, but wanted to point that out, in case you think it's not acceptable. https://reviews.llvm.org/D24598 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D24598: Separate builtins for x84-64 and i386; implement __mulh and __umulh
agutowski updated this revision to Diff 73521. agutowski added a comment. merge enums https://reviews.llvm.org/D24598 Files: include/clang/Basic/BuiltinsX86_64.def include/clang/Basic/TargetBuiltins.h lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c test/Sema/implicit-ms-builtin-decl.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -312,6 +312,7 @@ unsigned __int64 __lzcnt64(unsigned __int64); static __inline__ void __movsq(unsigned long long *, unsigned long long const *, size_t); +static __inline__ __int64 __mulh(__int64, __int64); static __inline__ unsigned __int64 __popcnt64(unsigned __int64); @@ -426,12 +427,8 @@ *_HighProduct = _FullProduct >> 64; return _FullProduct; } -static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS -__umulh(unsigned __int64 _Multiplier, unsigned __int64 _Multiplicand) { - unsigned __int128 _FullProduct = - (unsigned __int128)_Multiplier * (unsigned __int128)_Multiplicand; - return _FullProduct >> 64; -} +static __inline__ +unsigned __int64 __umulh(unsigned __int64, unsigned __int64); #endif /* __x86_64__ */ Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7488,7 +7488,31 @@ return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6); case X86::BI__builtin_ia32_cmpordsd: return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7); + + case X86::BI__mulh: + case X86::BI__umulh: { +Value *LHS = EmitScalarExpr(E->getArg(0)); +Value *RHS = EmitScalarExpr(E->getArg(1)); +llvm::Type *ResType = ConvertType(E->getType()); +llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); + +bool IsSigned = (BuiltinID == X86::BI__mulh); +LHS = Builder.CreateIntCast(LHS, Int128Ty, IsSigned); +RHS = Builder.CreateIntCast(RHS, Int128Ty, IsSigned); + +Value *MulResult, *HigherBits; +if (IsSigned) { + MulResult = Builder.CreateNSWMul(LHS, RHS); + HigherBits = Builder.CreateAShr(MulResult, 64); +} else { + MulResult = Builder.CreateNUWMul(LHS, RHS); + HigherBits = Builder.CreateLShr(MulResult, 64); +} + +HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); +return HigherBits; } + } } Index: lib/Basic/Targets.cpp === --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -2295,19 +2295,23 @@ return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); } -// Namespace for x86 abstract base class -const Builtin::Info BuiltinInfo[] = { +const Builtin::Info BuiltinInfoX86[] = { #define BUILTIN(ID, TYPE, ATTRS) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)\ - { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, #include "clang/Basic/BuiltinsX86.def" + +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, +#include "clang/Basic/BuiltinsX86_64.def" }; + static const char* const GCCRegNames[] = { "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", @@ -2671,10 +2675,6 @@ // X87 evaluates with 80 bits "long double" precision. return SSELevel == NoSSE ? 2 : 0; } - ArrayRef getTargetBuiltins() const override { -return llvm::makeArrayRef(BuiltinInfo, - clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin); - } ArrayRef getGCCRegNames() const override { return llvm::makeArrayRef(GCCRegNames); } @@ -4093,6 +4093,10 @@ return X86TargetInfo::validateOperandSize(Constraint, Size); } + ArrayRef getTargetBuiltins() const override { +return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - + Builtin::FirstTSBuiltin + 1); + } }; class NetBSDI386TargetInfo : public NetBSDTargetInfo { @@ -4448,6 +4452,10 @@ return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize, HasSizeMismatch); } + ArrayRef getTargetBuiltins() const override { +return llvm::makeArrayRef(BuiltinInfoX86, +
[PATCH] D24598: Separate builtins for x84-64 and i386; implement __mulh and __umulh
agutowski updated this revision to Diff 73375. agutowski added a comment. remove BuiltinsX86_32.def; reduce redundancy in x86 builtins info https://reviews.llvm.org/D24598 Files: include/clang/Basic/BuiltinsX86_64.def include/clang/Basic/TargetBuiltins.h lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c test/Sema/implicit-ms-builtin-decl.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -312,6 +312,7 @@ unsigned __int64 __lzcnt64(unsigned __int64); static __inline__ void __movsq(unsigned long long *, unsigned long long const *, size_t); +static __inline__ __int64 __mulh(__int64, __int64); static __inline__ unsigned __int64 __popcnt64(unsigned __int64); @@ -426,12 +427,8 @@ *_HighProduct = _FullProduct >> 64; return _FullProduct; } -static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS -__umulh(unsigned __int64 _Multiplier, unsigned __int64 _Multiplicand) { - unsigned __int128 _FullProduct = - (unsigned __int128)_Multiplier * (unsigned __int128)_Multiplicand; - return _FullProduct >> 64; -} +static __inline__ +unsigned __int64 __umulh(unsigned __int64, unsigned __int64); #endif /* __x86_64__ */ Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7488,7 +7488,31 @@ return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6); case X86::BI__builtin_ia32_cmpordsd: return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7); + + case X86_64::BI__mulh: + case X86_64::BI__umulh: { +Value *LHS = EmitScalarExpr(E->getArg(0)); +Value *RHS = EmitScalarExpr(E->getArg(1)); +llvm::Type *ResType = ConvertType(E->getType()); +llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); + +bool IsSigned = (BuiltinID == X86_64::BI__mulh); +LHS = Builder.CreateIntCast(LHS, Int128Ty, IsSigned); +RHS = Builder.CreateIntCast(RHS, Int128Ty, IsSigned); + +Value *MulResult, *HigherBits; +if (IsSigned) { + MulResult = Builder.CreateNSWMul(LHS, RHS); + HigherBits = Builder.CreateAShr(MulResult, 64); +} else { + MulResult = Builder.CreateNUWMul(LHS, RHS); + HigherBits = Builder.CreateLShr(MulResult, 64); +} + +HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); +return HigherBits; } + } } Index: lib/Basic/Targets.cpp === --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -2295,19 +2295,23 @@ return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); } -// Namespace for x86 abstract base class -const Builtin::Info BuiltinInfo[] = { +const Builtin::Info BuiltinInfoX86[] = { #define BUILTIN(ID, TYPE, ATTRS) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)\ - { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, #include "clang/Basic/BuiltinsX86.def" + +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, +#include "clang/Basic/BuiltinsX86_64.def" }; + static const char* const GCCRegNames[] = { "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", @@ -2671,10 +2675,6 @@ // X87 evaluates with 80 bits "long double" precision. return SSELevel == NoSSE ? 2 : 0; } - ArrayRef getTargetBuiltins() const override { -return llvm::makeArrayRef(BuiltinInfo, - clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin); - } ArrayRef getGCCRegNames() const override { return llvm::makeArrayRef(GCCRegNames); } @@ -4093,6 +4093,10 @@ return X86TargetInfo::validateOperandSize(Constraint, Size); } + ArrayRef getTargetBuiltins() const override { +return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastTSBuiltin - + Builtin::FirstTSBuiltin); + } }; class NetBSDI386TargetInfo : public NetBSDTargetInfo { @@ -4448,6 +4452,10 @@ return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize, HasSizeMismatch); } + ArrayRef getTargetBuiltins() const override { +return
[PATCH] D24598: Separate builtins for x84-64 and i386; implement __mulh and __umulh
agutowski added inline comments. > BuiltinsX86_32.def:1 > +//===--- BuiltinsX86_32.def - X86-32 Builtin function database --*- C++ > -*-===// > +// Will we ever need that file? It seems to nicely complement the 64-bit one, but if it's going to be empty forever maybe it's better to remove it. https://reviews.llvm.org/D24598 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D24775: Add -Wignored-pragma-intrinsic flag
Thanks for clarification! You are right that it doesn't really fit in -Wignored-pragma, but I also don't like the idea of getting warning about ignored "#pragma intrinsic" after setting -Wno-ignored-pragma, so I think I'll leave it as it is. On Wed, Sep 21, 2016 at 1:35 PM, Nico Weberwrote: > On Tue, Sep 20, 2016 at 4:21 PM, Albert Gutowski > wrote: >> >> OK, thanks for the note about referring to Chromium, I fixed that. >> As to -Wunknown-pragma, I feel that it would be inconsistent with other >> pragmas unless I moved whole pragma to lexer instead of parser - I've just >> discovered that I can do that, how should I decide if it's supposed to be >> here or there? > > > Your commit reminds me that I forgot to reply to this thread. For the > lexer/parser split, I think about it like this: If clang doesn't know about > a certain pragma at all, it can't do anything with it, so all it does is > emit 'unknown pragma', skip it, and move on. If it does know the pragma, it > can parse it -- but then it might have to ignore it for some reason, which > is why the parser prints that diagnostic. > > So you're right that this doesn't fit in well in -Wunknown-pragma. > > But -Wignored-pragma doesn't quite fit either imho, since we're not ignoring > the pragma, we're looking at its context. > > Applying the same idea for pragmas to `#pragma intrinsic`, it feels to me > that we don't know some intrinsics at all, so they're more unknown than > ignored (as in -Wunkown-pragma-intrinsic, but in the sense of as "unknown > (pragma intrinsic)" not "(unknown pragma) intrinsic" -- but since this > shouldn't be in -Wunknown-pragma as you correctly say, that's not a good > name for this flag.) > > So I think -Wmicrosoft-pragma-intrinsic might be a better fit. (But as I > said, it's bikeshedding, and up to you.) > >> >> >> On Tue, Sep 20, 2016 at 12:30 PM, Nico Weber wrote: >>> >>> Thanks! Some bikesheddy comments, ignore as you see fit: >>> >>> - I think it's good to keep Chromium's bug tracker out of LLVM as far as >>> possible (most LLVM devs don't need to care about Chromium, and since >>> Chromium's bug tracker refers to LLVM's bug tracker frequently since >>> chromium depends on llvm, adding links the other way round adds a dependency >>> cycle of sorts), so maybe describe the motivation in your own words instead >>> of linking ("People might want to receive warnings about pragmas but not >>> about intrinsics we don't yet implement") >>> >>> - Should this be part of -Wunknown-pragma instead of -Wignored-pragma? >>> (Or maybe even in -Wmicrosoft somewhere?) That seems to fit a tiny bit >>> better imho (but as I said, feel free to disagree and ignore) >>> >>> On Tue, Sep 20, 2016 at 2:38 PM, Albert Gutowski >>> wrote: agutowski created this revision. agutowski added reviewers: thakis, hans. agutowski added a subscriber: cfe-commits. https://bugs.chromium.org/p/chromium/issues/detail?id=644841#c9 https://reviews.llvm.org/D24775 Files: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticParseKinds.td test/Preprocessor/pragma_microsoft.c Index: include/clang/Basic/DiagnosticParseKinds.td === --- include/clang/Basic/DiagnosticParseKinds.td +++ include/clang/Basic/DiagnosticParseKinds.td @@ -914,7 +914,7 @@ // - #pragma intrinsic def warn_pragma_intrinsic_builtin : Warning< "%0 is not a recognized builtin%select{|; consider including to access non-builtin intrinsics}1">, - InGroup; + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, Index: include/clang/Basic/DiagnosticGroups.td === --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -439,8 +439,9 @@ def UninitializedStaticSelfInit : DiagGroup<"static-self-init">; def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes, UninitializedStaticSelfInit]>; +def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">; def UnknownPragmas : DiagGroup<"unknown-pragmas">; -def IgnoredPragmas : DiagGroup<"ignored-pragmas">; +def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>; def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>; def UnknownWarningOption : DiagGroup<"unknown-warning-option">; def NSobjectAttribute : DiagGroup<"NSObject-attribute">; Index: test/Preprocessor/pragma_microsoft.c === --- test/Preprocessor/pragma_microsoft.c +++
Re: [PATCH] D24775: Add -Wignored-pragma-intrinsic flag
This revision was automatically updated to reflect the committed changes. Closed by commit rL282108: Add -Wignored-pragma-intrinsic flag (authored by agutowski). Changed prior to commit: https://reviews.llvm.org/D24775?vs=71960=72102#toc Repository: rL LLVM https://reviews.llvm.org/D24775 Files: cfe/trunk/include/clang/Basic/DiagnosticGroups.td cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td cfe/trunk/test/Preprocessor/pragma_microsoft.c Index: cfe/trunk/include/clang/Basic/DiagnosticGroups.td === --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td @@ -439,8 +439,9 @@ def UninitializedStaticSelfInit : DiagGroup<"static-self-init">; def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes, UninitializedStaticSelfInit]>; +def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">; def UnknownPragmas : DiagGroup<"unknown-pragmas">; -def IgnoredPragmas : DiagGroup<"ignored-pragmas">; +def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>; def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>; def UnknownWarningOption : DiagGroup<"unknown-warning-option">; def NSobjectAttribute : DiagGroup<"NSObject-attribute">; Index: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td === --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td @@ -914,7 +914,7 @@ // - #pragma intrinsic def warn_pragma_intrinsic_builtin : Warning< "%0 is not a recognized builtin%select{|; consider including to access non-builtin intrinsics}1">, - InGroup; + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, Index: cfe/trunk/test/Preprocessor/pragma_microsoft.c === --- cfe/trunk/test/Preprocessor/pragma_microsoft.c +++ cfe/trunk/test/Preprocessor/pragma_microsoft.c @@ -178,3 +178,15 @@ #pragma intrinsic(memset) // no-warning #undef __INTRIN_H #pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-pragma-intrinsic" +#pragma intrinsic(asdf) // no-warning +#pragma clang diagnostic pop +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-pragmas" +#pragma intrinsic(asdf) // no-warning +#pragma clang diagnostic pop +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} Index: cfe/trunk/include/clang/Basic/DiagnosticGroups.td === --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td @@ -439,8 +439,9 @@ def UninitializedStaticSelfInit : DiagGroup<"static-self-init">; def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes, UninitializedStaticSelfInit]>; +def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">; def UnknownPragmas : DiagGroup<"unknown-pragmas">; -def IgnoredPragmas : DiagGroup<"ignored-pragmas">; +def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>; def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>; def UnknownWarningOption : DiagGroup<"unknown-warning-option">; def NSobjectAttribute : DiagGroup<"NSObject-attribute">; Index: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td === --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td @@ -914,7 +914,7 @@ // - #pragma intrinsic def warn_pragma_intrinsic_builtin : Warning< "%0 is not a recognized builtin%select{|; consider including to access non-builtin intrinsics}1">, - InGroup; + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, Index: cfe/trunk/test/Preprocessor/pragma_microsoft.c === --- cfe/trunk/test/Preprocessor/pragma_microsoft.c +++ cfe/trunk/test/Preprocessor/pragma_microsoft.c @@ -178,3 +178,15 @@ #pragma intrinsic(memset) // no-warning #undef __INTRIN_H #pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-pragma-intrinsic" +#pragma intrinsic(asdf) // no-warning +#pragma clang
r282108 - Add -Wignored-pragma-intrinsic flag
Author: agutowski Date: Wed Sep 21 15:19:21 2016 New Revision: 282108 URL: http://llvm.org/viewvc/llvm-project?rev=282108=rev Log: Add -Wignored-pragma-intrinsic flag Summary: People might want to receive warnings about pragmas but not about intrinsics that are implemented in intrin.h. Reviewers: thakis, hans Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D24775 Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td cfe/trunk/test/Preprocessor/pragma_microsoft.c Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=282108=282107=282108=diff == --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Wed Sep 21 15:19:21 2016 @@ -439,8 +439,9 @@ def UninitializedSometimes : DiagGroup<" def UninitializedStaticSelfInit : DiagGroup<"static-self-init">; def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes, UninitializedStaticSelfInit]>; +def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">; def UnknownPragmas : DiagGroup<"unknown-pragmas">; -def IgnoredPragmas : DiagGroup<"ignored-pragmas">; +def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>; def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>; def UnknownWarningOption : DiagGroup<"unknown-warning-option">; def NSobjectAttribute : DiagGroup<"NSObject-attribute">; Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=282108=282107=282108=diff == --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed Sep 21 15:19:21 2016 @@ -914,7 +914,7 @@ def warn_pragma_pack_malformed : Warning // - #pragma intrinsic def warn_pragma_intrinsic_builtin : Warning< "%0 is not a recognized builtin%select{|; consider including to access non-builtin intrinsics}1">, - InGroup; + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, Modified: cfe/trunk/test/Preprocessor/pragma_microsoft.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/pragma_microsoft.c?rev=282108=282107=282108=diff == --- cfe/trunk/test/Preprocessor/pragma_microsoft.c (original) +++ cfe/trunk/test/Preprocessor/pragma_microsoft.c Wed Sep 21 15:19:21 2016 @@ -178,3 +178,15 @@ void g() {} #pragma intrinsic(memset) // no-warning #undef __INTRIN_H #pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-pragma-intrinsic" +#pragma intrinsic(asdf) // no-warning +#pragma clang diagnostic pop +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-pragmas" +#pragma intrinsic(asdf) // no-warning +#pragma clang diagnostic pop +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D24775: Add -Wignored-pragma-intrinsic flag
OK, thanks for the note about referring to Chromium, I fixed that. As to -Wunknown-pragma, I feel that it would be inconsistent with other pragmas unless I moved whole pragma to lexer instead of parser - I've just discovered that I can do that, how should I decide if it's supposed to be here or there? On Tue, Sep 20, 2016 at 12:30 PM, Nico Weberwrote: > Thanks! Some bikesheddy comments, ignore as you see fit: > > - I think it's good to keep Chromium's bug tracker out of LLVM as far as > possible (most LLVM devs don't need to care about Chromium, and since > Chromium's bug tracker refers to LLVM's bug tracker frequently since > chromium depends on llvm, adding links the other way round adds a > dependency cycle of sorts), so maybe describe the motivation in your own > words instead of linking ("People might want to receive warnings about > pragmas but not about intrinsics we don't yet implement") > > - Should this be part of -Wunknown-pragma instead of -Wignored-pragma? (Or > maybe even in -Wmicrosoft somewhere?) That seems to fit a tiny bit better > imho (but as I said, feel free to disagree and ignore) > > On Tue, Sep 20, 2016 at 2:38 PM, Albert Gutowski > wrote: > >> agutowski created this revision. >> agutowski added reviewers: thakis, hans. >> agutowski added a subscriber: cfe-commits. >> >> https://bugs.chromium.org/p/chromium/issues/detail?id=644841#c9 >> >> https://reviews.llvm.org/D24775 >> >> Files: >> include/clang/Basic/DiagnosticGroups.td >> include/clang/Basic/DiagnosticParseKinds.td >> test/Preprocessor/pragma_microsoft.c >> >> Index: include/clang/Basic/DiagnosticParseKinds.td >> === >> --- include/clang/Basic/DiagnosticParseKinds.td >> +++ include/clang/Basic/DiagnosticParseKinds.td >> @@ -914,7 +914,7 @@ >> // - #pragma intrinsic >> def warn_pragma_intrinsic_builtin : Warning< >>"%0 is not a recognized builtin%select{|; consider including >> to access non-builtin intrinsics}1">, >> - InGroup; >> + InGroup; >> // - #pragma unused >> def warn_pragma_unused_expected_var : Warning< >>"expected '#pragma unused' argument to be a variable name">, >> Index: include/clang/Basic/DiagnosticGroups.td >> === >> --- include/clang/Basic/DiagnosticGroups.td >> +++ include/clang/Basic/DiagnosticGroups.td >> @@ -439,8 +439,9 @@ >> def UninitializedStaticSelfInit : DiagGroup<"static-self-init">; >> def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes, >> >> UninitializedStaticSelfInit]>; >> +def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">; >> def UnknownPragmas : DiagGroup<"unknown-pragmas">; >> -def IgnoredPragmas : DiagGroup<"ignored-pragmas">; >> +def IgnoredPragmas : DiagGroup<"ignored-pragmas", >> [IgnoredPragmaIntrinsic]>; >> def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>; >> def UnknownWarningOption : DiagGroup<"unknown-warning-option">; >> def NSobjectAttribute : DiagGroup<"NSObject-attribute">; >> Index: test/Preprocessor/pragma_microsoft.c >> === >> --- test/Preprocessor/pragma_microsoft.c >> +++ test/Preprocessor/pragma_microsoft.c >> @@ -178,3 +178,15 @@ >> #pragma intrinsic(memset) // no-warning >> #undef __INTRIN_H >> #pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized >> builtin; consider including }} >> + >> +#pragma clang diagnostic push >> +#pragma clang diagnostic ignored "-Wignored-pragma-intrinsic" >> +#pragma intrinsic(asdf) // no-warning >> +#pragma clang diagnostic pop >> +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized >> builtin; consider including }} >> + >> +#pragma clang diagnostic push >> +#pragma clang diagnostic ignored "-Wignored-pragmas" >> +#pragma intrinsic(asdf) // no-warning >> +#pragma clang diagnostic pop >> +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized >> builtin; consider including }} >> >> >> > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D24775: Add -Wignored-pragma-intrinsic flag
agutowski created this revision. agutowski added reviewers: thakis, hans. agutowski added a subscriber: cfe-commits. https://bugs.chromium.org/p/chromium/issues/detail?id=644841#c9 https://reviews.llvm.org/D24775 Files: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticParseKinds.td test/Preprocessor/pragma_microsoft.c Index: include/clang/Basic/DiagnosticParseKinds.td === --- include/clang/Basic/DiagnosticParseKinds.td +++ include/clang/Basic/DiagnosticParseKinds.td @@ -914,7 +914,7 @@ // - #pragma intrinsic def warn_pragma_intrinsic_builtin : Warning< "%0 is not a recognized builtin%select{|; consider including to access non-builtin intrinsics}1">, - InGroup; + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, Index: include/clang/Basic/DiagnosticGroups.td === --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -439,8 +439,9 @@ def UninitializedStaticSelfInit : DiagGroup<"static-self-init">; def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes, UninitializedStaticSelfInit]>; +def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">; def UnknownPragmas : DiagGroup<"unknown-pragmas">; -def IgnoredPragmas : DiagGroup<"ignored-pragmas">; +def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>; def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>; def UnknownWarningOption : DiagGroup<"unknown-warning-option">; def NSobjectAttribute : DiagGroup<"NSObject-attribute">; Index: test/Preprocessor/pragma_microsoft.c === --- test/Preprocessor/pragma_microsoft.c +++ test/Preprocessor/pragma_microsoft.c @@ -178,3 +178,15 @@ #pragma intrinsic(memset) // no-warning #undef __INTRIN_H #pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-pragma-intrinsic" +#pragma intrinsic(asdf) // no-warning +#pragma clang diagnostic pop +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-pragmas" +#pragma intrinsic(asdf) // no-warning +#pragma clang diagnostic pop +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} Index: include/clang/Basic/DiagnosticParseKinds.td === --- include/clang/Basic/DiagnosticParseKinds.td +++ include/clang/Basic/DiagnosticParseKinds.td @@ -914,7 +914,7 @@ // - #pragma intrinsic def warn_pragma_intrinsic_builtin : Warning< "%0 is not a recognized builtin%select{|; consider including to access non-builtin intrinsics}1">, - InGroup; + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, Index: include/clang/Basic/DiagnosticGroups.td === --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -439,8 +439,9 @@ def UninitializedStaticSelfInit : DiagGroup<"static-self-init">; def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes, UninitializedStaticSelfInit]>; +def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">; def UnknownPragmas : DiagGroup<"unknown-pragmas">; -def IgnoredPragmas : DiagGroup<"ignored-pragmas">; +def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>; def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>; def UnknownWarningOption : DiagGroup<"unknown-warning-option">; def NSobjectAttribute : DiagGroup<"NSObject-attribute">; Index: test/Preprocessor/pragma_microsoft.c === --- test/Preprocessor/pragma_microsoft.c +++ test/Preprocessor/pragma_microsoft.c @@ -178,3 +178,15 @@ #pragma intrinsic(memset) // no-warning #undef __INTRIN_H #pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-pragma-intrinsic" +#pragma intrinsic(asdf) // no-warning +#pragma clang diagnostic pop +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-pragmas" +#pragma intrinsic(asdf) // no-warning +#pragma clang diagnostic pop +#pragma
[PATCH] D24598: Separate builtins for x84-64 and i386; implement __mulh and __umulh
agutowski created this revision. agutowski added reviewers: rnk, thakis, majnemer. agutowski added a subscriber: cfe-commits. We need x86-64-specific builtins if we want to implement some of the MS intrinsics - winnt.h contains definitions of some functions for i386, but not for x86-64 (for example _InterlockedOr64), which means that we cannot treat them as builtins for both i386 and x86-64, because then we have definitions of builtin functions in winnt.h on i386. https://reviews.llvm.org/D24598 Files: include/clang/Basic/BuiltinsX86_32.def include/clang/Basic/BuiltinsX86_64.def include/clang/Basic/TargetBuiltins.h lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c test/Sema/implicit-ms-builtin-decl.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -312,6 +312,7 @@ unsigned __int64 __lzcnt64(unsigned __int64); static __inline__ void __movsq(unsigned long long *, unsigned long long const *, size_t); +static __inline__ __int64 __mulh(__int64, __int64); static __inline__ unsigned __int64 __popcnt64(unsigned __int64); @@ -426,12 +427,8 @@ *_HighProduct = _FullProduct >> 64; return _FullProduct; } -static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS -__umulh(unsigned __int64 _Multiplier, unsigned __int64 _Multiplicand) { - unsigned __int128 _FullProduct = - (unsigned __int128)_Multiplier * (unsigned __int128)_Multiplicand; - return _FullProduct >> 64; -} +static __inline__ +unsigned __int64 __umulh(unsigned __int64, unsigned __int64); #endif /* __x86_64__ */ Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7488,7 +7488,31 @@ return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6); case X86::BI__builtin_ia32_cmpordsd: return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7); + + case X86_64::BI__mulh: + case X86_64::BI__umulh: { +Value *LHS = EmitScalarExpr(E->getArg(0)); +Value *RHS = EmitScalarExpr(E->getArg(1)); +llvm::Type *ResType = ConvertType(E->getType()); +llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); + +bool IsSigned = (BuiltinID == X86_64::BI__mulh); +LHS = Builder.CreateIntCast(LHS, Int128Ty, IsSigned); +RHS = Builder.CreateIntCast(RHS, Int128Ty, IsSigned); + +Value *MulResult, *HigherBits; +if (IsSigned) { + MulResult = Builder.CreateNSWMul(LHS, RHS); + HigherBits = Builder.CreateAShr(MulResult, 64); +} else { + MulResult = Builder.CreateNUWMul(LHS, RHS); + HigherBits = Builder.CreateLShr(MulResult, 64); +} + +HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); +return HigherBits; } + } } Index: lib/Basic/Targets.cpp === --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -2295,19 +2295,37 @@ return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); } -// Namespace for x86 abstract base class -const Builtin::Info BuiltinInfo[] = { +const Builtin::Info BuiltinInfoX86_32[] = { #define BUILTIN(ID, TYPE, ATTRS) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)\ - { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, #include "clang/Basic/BuiltinsX86.def" + +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, +#include "clang/Basic/BuiltinsX86_32.def" }; +const Builtin::Info BuiltinInfoX86_64[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, +#include "clang/Basic/BuiltinsX86.def" + +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, +#include "clang/Basic/BuiltinsX86_64.def" +}; + + static const char* const GCCRegNames[] = { "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", "st", "st(1)", "st(2)",
r281540 - Add some MS aliases for existing intrinsics
Author: agutowski Date: Wed Sep 14 16:19:43 2016 New Revision: 281540 URL: http://llvm.org/viewvc/llvm-project?rev=281540=rev Log: Add some MS aliases for existing intrinsics Reviewers: thakis, compnerd, majnemer, rsmith, rnk Subscribers: alexshap, cfe-commits Differential Revision: https://reviews.llvm.org/D24330 Added: cfe/trunk/test/Headers/x86intrin.cpp cfe/trunk/test/Sema/implicit-intel-builtin-decl.c cfe/trunk/test/Sema/implicit-ms-builtin-decl.c Modified: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/include/clang/Basic/Builtins.h cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/emmintrin.h cfe/trunk/lib/Headers/ia32intrin.h cfe/trunk/lib/Headers/intrin.h cfe/trunk/lib/Headers/xmmintrin.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/CodeGen/builtins-x86.c Modified: cfe/trunk/include/clang/Basic/Builtins.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=281540=281539=281540=diff == --- cfe/trunk/include/clang/Basic/Builtins.def (original) +++ cfe/trunk/include/clang/Basic/Builtins.def Wed Sep 14 16:19:43 2016 @@ -74,6 +74,7 @@ // f -> this is a libc/libm function without the '__builtin_' prefix. It can // be followed by ':headername:' to state which header this function // comes from. +// h -> this function requires a specific header or an explicit declaration. // i -> this is a runtime library implemented function without the // '__builtin_' prefix. It will be implemented in compiler-rt or libgcc. // p:N: -> this is a printf-like function whose Nth argument is the format @@ -708,6 +709,9 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn" // Microsoft builtins. These are only active with -fms-extensions. LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES) +LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES) +LIBBUILTIN(_byteswap_ulong, "ULiULi", "fnc", "stdlib.h", ALL_MS_LANGUAGES) +LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", "stdlib.h", ALL_MS_LANGUAGES) LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__exception_code, "ULi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_exception_code, "ULi", "n", ALL_MS_LANGUAGES) @@ -745,6 +749,9 @@ LANGBUILTIN(_InterlockedXor8, "ccD*c", LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedXor, "LiLiD*Li","n", ALL_MS_LANGUAGES) LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) +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(_rotl8, "UcUcUc","n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl16, "UsUsUc","n", ALL_MS_LANGUAGES) Modified: cfe/trunk/include/clang/Basic/Builtins.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.h?rev=281540=281539=281540=diff == --- cfe/trunk/include/clang/Basic/Builtins.h (original) +++ cfe/trunk/include/clang/Basic/Builtins.h Wed Sep 14 16:19:43 2016 @@ -139,6 +139,13 @@ public: return strchr(getRecord(ID).Attributes, 'f') != nullptr; } + /// \brief Returns true if this builtin requires appropriate header in other + /// compilers. In Clang it will work even without including it, but we can emit + /// a warning about missing header. + bool isHeaderDependentFunction(unsigned ID) const { +return strchr(getRecord(ID).Attributes, 'h') != nullptr; + } + /// \brief Determines whether this builtin is a predefined compiler-rt/libgcc /// function, such as "__clear_cache", where we know the signature a /// priori. Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=281540=281539=281540=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Wed Sep 14 16:19:43 2016 @@ -23,6 +23,10 @@ # define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif +#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) +# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + // FIXME: Are these nothrow/const? // Miscellaneous builtin for checking x86 cpu features. @@ -301,7 +305,9 @@ TARGET_BUILTIN(__builtin_ia32_pabsw128, TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "", "ssse3") TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi",
Re: [PATCH] D24330: Add some MS aliases for existing intrinsics
agutowski marked an inline comment as done. agutowski added a comment. https://reviews.llvm.org/D24330 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D24330: Add some MS aliases for existing intrinsics
agutowski updated this revision to Diff 71271. agutowski added a comment. Add extern "C" to Intel intrinsics declarations https://reviews.llvm.org/D24330 Files: include/clang/Basic/Builtins.def include/clang/Basic/Builtins.h include/clang/Basic/BuiltinsX86.def lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/Headers/emmintrin.h lib/Headers/ia32intrin.h lib/Headers/intrin.h lib/Headers/xmmintrin.h lib/Sema/SemaDecl.cpp test/CodeGen/builtins-x86.c test/Headers/x86intrin.cpp test/Sema/implicit-intel-builtin-decl.c test/Sema/implicit-ms-builtin-decl.c Index: lib/Headers/ia32intrin.h === --- lib/Headers/ia32intrin.h +++ lib/Headers/ia32intrin.h @@ -60,12 +60,6 @@ return __builtin_ia32_rdpmc(__A); } -/* __rdtsc */ -static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) -__rdtsc(void) { - return __builtin_ia32_rdtsc(); -} - /* __rdtscp */ static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) __rdtscp(unsigned int *__A) { Index: lib/Headers/emmintrin.h === --- lib/Headers/emmintrin.h +++ lib/Headers/emmintrin.h @@ -2447,6 +2447,10 @@ } #endif +#if defined(__cplusplus) +extern "C" { +#endif + /// \brief The cache line containing __p is flushed and invalidated from all ///caches in the coherency domain. /// @@ -2457,11 +2461,7 @@ /// \param __p ///A pointer to the memory location used to identify the cache line to be ///flushed. -static __inline__ void __DEFAULT_FN_ATTRS -_mm_clflush(void const *__p) -{ - __builtin_ia32_clflush(__p); -} +void _mm_clflush(void const *); /// \brief Forces strong memory ordering (serialization) between load ///instructions preceding this instruction and load instructions following @@ -2472,11 +2472,7 @@ /// /// This intrinsic corresponds to the \c LFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_lfence(void) -{ - __builtin_ia32_lfence(); -} +void _mm_lfence(void); /// \brief Forces strong memory ordering (serialization) between load and store ///instructions preceding this instruction and load and store instructions @@ -2487,12 +2483,12 @@ /// /// This intrinsic corresponds to the \c MFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_mfence(void) -{ - __builtin_ia32_mfence(); -} +void _mm_mfence(void); +#if defined(__cplusplus) +} // extern "C" +#endif + /// \brief Converts 16-bit signed integers from both 128-bit integer vector ///operands into 8-bit signed integers, and packs the results into the ///destination. Positive values greater than 0x7F are saturated to 0x7F. @@ -3213,11 +3209,10 @@ /// /// This intrinsic corresponds to the \c PAUSE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_pause(void) -{ - __builtin_ia32_pause(); -} +#if defined(__cplusplus) +extern "C" +#endif +void _mm_pause(void); #undef __DEFAULT_FN_ATTRS Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -463,14 +463,6 @@ *_Index = 31 - __builtin_clzl(_Mask); return 1; } -static __inline__ unsigned short __DEFAULT_FN_ATTRS -__popcnt16(unsigned short _Value) { - return __builtin_popcount((int)_Value); -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -__popcnt(unsigned int _Value) { - return __builtin_popcount(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest(long const *_BitBase, long _BitPos) { return (*_BitBase >> _BitPos) & 1; @@ -513,11 +505,6 @@ *_Index = 63 - __builtin_clzll(_Mask); return 1; } -static __inline__ -unsigned __int64 __DEFAULT_FN_ATTRS -__popcnt64(unsigned __int64 _Value) { - return __builtin_popcountll(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest64(__int64 const *_BitBase, __int64 _BitPos) { return (*_BitBase >> _BitPos) & 1; @@ -546,63 +533,63 @@ __atomic_fetch_or(_BitBase, 1ll << _BitPos, __ATOMIC_SEQ_CST); return (_PrevVal >> _BitPos) & 1; } -/**\ -|* Interlocked Exchange Add -\**/ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); -} -/**\ -|* Interlocked Exchange Sub -\**/ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -}
Re: [PATCH] D24330: Add some MS aliases for existing intrinsics
agutowski reopened this revision. agutowski added a comment. This revision is now accepted and ready to land. xmmintrin.h and emmintrin.h broke compilation when included inside extern "C++" block Repository: rL LLVM https://reviews.llvm.org/D24330 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r281401 - Temporary fix for MS _Interlocked intrinsics
Buildbot failure - http://lab.llvm.org:8011/builders/clang-x86-windows-msvc2015/builds/323 On Tue, Sep 13, 2016 at 3:05 PM, David Majnemer <david.majne...@gmail.com> wrote: > What issue is this addressing? > > On Tue, Sep 13, 2016 at 2:51 PM, Albert Gutowski via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> Author: agutowski >> Date: Tue Sep 13 16:51:37 2016 >> New Revision: 281401 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=281401=rev >> Log: >> Temporary fix for MS _Interlocked intrinsics >> >> Modified: >> cfe/trunk/include/clang/Basic/Builtins.def >> cfe/trunk/lib/CodeGen/CGBuiltin.cpp >> cfe/trunk/lib/Headers/intrin.h >> cfe/trunk/test/CodeGen/ms-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=281401=281400=281401=diff >> >> == >> --- cfe/trunk/include/clang/Basic/Builtins.def (original) >> +++ cfe/trunk/include/clang/Basic/Builtins.def Tue Sep 13 16:51:37 2016 >> @@ -719,7 +719,6 @@ LANGBUILTIN(__GetExceptionInfo, "v*.", " >> LANGBUILTIN(_InterlockedAnd8, "ccD*c","n", ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedAnd16, "ssD*s","n", ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedAnd,"LiLiD*Li", "n", ALL_MS_LANGUAGES) >> -LANGBUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedCompareExchange8, "ccD*cc", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedCompareExchange16, "ssD*ss", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedCompareExchange,"LiLiD*LiLi", "n", >> ALL_MS_LANGUAGES) >> @@ -727,31 +726,24 @@ LANGBUILTIN(_InterlockedCompareExchange6 >> LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedDecrement16,"ssD*", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", >> ALL_MS_LANGUAGES) >> -LANGBUILTIN(_InterlockedDecrement64,"LLiLLiD*", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedExchange8, "ccD*c","n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedExchange16, "ssD*s","n", >> ALL_MS_LANGUAGES) >> -LANGBUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedExchangeAdd8, "ccD*c", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedExchangeAdd16, "ssD*s", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedExchangeAdd,"LiLiD*Li", "n", >> ALL_MS_LANGUAGES) >> -LANGBUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi","n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedExchangePointer,"v*v*D*v*", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedExchangeSub8, "ccD*c","n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedExchangeSub16, "ssD*s","n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedExchangeSub,"LiLiD*Li", "n", >> ALL_MS_LANGUAGES) >> -LANGBUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedIncrement16,"ssD*", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", >> ALL_MS_LANGUAGES) >> -LANGBUILTIN(_InterlockedIncrement64,"LLiLLiD*", "n", >> ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedOr8, "ccD*c","n", ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedOr16, "ssD*s","n", ALL_MS_LANGUAGES) >> LANGBUILTIN(_InterlockedOr, "LiLiD*Li", "n", ALL_MS_LANGUAGES) >> -LANGBUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "n", ALL_MS_LA
r281401 - Temporary fix for MS _Interlocked intrinsics
Author: agutowski Date: Tue Sep 13 16:51:37 2016 New Revision: 281401 URL: http://llvm.org/viewvc/llvm-project?rev=281401=rev Log: Temporary fix for MS _Interlocked intrinsics Modified: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/intrin.h cfe/trunk/test/CodeGen/ms-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=281401=281400=281401=diff == --- cfe/trunk/include/clang/Basic/Builtins.def (original) +++ cfe/trunk/include/clang/Basic/Builtins.def Tue Sep 13 16:51:37 2016 @@ -719,7 +719,6 @@ LANGBUILTIN(__GetExceptionInfo, "v*.", " LANGBUILTIN(_InterlockedAnd8, "ccD*c","n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedAnd16, "ssD*s","n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedAnd,"LiLiD*Li", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedCompareExchange8, "ccD*cc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedCompareExchange16, "ssD*ss", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedCompareExchange,"LiLiD*LiLi", "n", ALL_MS_LANGUAGES) @@ -727,31 +726,24 @@ LANGBUILTIN(_InterlockedCompareExchange6 LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedDecrement16,"ssD*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedDecrement64,"LLiLLiD*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchange8, "ccD*c","n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchange16, "ssD*s","n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeAdd8, "ccD*c", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeAdd16, "ssD*s", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeAdd,"LiLiD*Li", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi","n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangePointer,"v*v*D*v*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeSub8, "ccD*c","n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeSub16, "ssD*s","n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeSub,"LiLiD*Li", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedIncrement16,"ssD*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedIncrement64,"LLiLLiD*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedOr8, "ccD*c","n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedOr16, "ssD*s","n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedOr, "LiLiD*Li", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedXor, "LiLiD*Li","n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__readfsdword,"ULiULi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl8, "UcUcUc","n", ALL_MS_LANGUAGES) Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=281401=281400=281401=diff == --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Tue Sep 13 16:51:37 2016 @@ -1963,7 +1963,6 @@ RValue CodeGenFunction::EmitBuiltinExpr( case Builtin::BI_InterlockedExchange8: case Builtin::BI_InterlockedExchange16: case Builtin::BI_InterlockedExchange: - case Builtin::BI_InterlockedExchange64: case Builtin::BI_InterlockedExchangePointer: return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); case Builtin::BI_InterlockedCompareExchangePointer: { @@ -2007,8 +2006,7 @@ RValue CodeGenFunction::EmitBuiltinExpr( return RValue::get(Builder.CreateExtractValue(CXI, 0)); } case Builtin::BI_InterlockedIncrement16: - case Builtin::BI_InterlockedIncrement: - case Builtin::BI_InterlockedIncrement64: { + case Builtin::BI_InterlockedIncrement: { llvm::Type *IntTy = ConvertType(E->getType()); AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( AtomicRMWInst::Add,
r281399 - Reverse commit 281375 (breaks building Chromium)
Author: agutowski Date: Tue Sep 13 16:24:51 2016 New Revision: 281399 URL: http://llvm.org/viewvc/llvm-project?rev=281399=rev Log: Reverse commit 281375 (breaks building Chromium) Removed: cfe/trunk/test/Sema/implicit-intel-builtin-decl.c cfe/trunk/test/Sema/implicit-ms-builtin-decl.c Modified: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/include/clang/Basic/Builtins.h cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/emmintrin.h cfe/trunk/lib/Headers/ia32intrin.h cfe/trunk/lib/Headers/intrin.h cfe/trunk/lib/Headers/xmmintrin.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/CodeGen/builtins-x86.c Modified: cfe/trunk/include/clang/Basic/Builtins.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=281399=281398=281399=diff == --- cfe/trunk/include/clang/Basic/Builtins.def (original) +++ cfe/trunk/include/clang/Basic/Builtins.def Tue Sep 13 16:24:51 2016 @@ -74,7 +74,6 @@ // f -> this is a libc/libm function without the '__builtin_' prefix. It can // be followed by ':headername:' to state which header this function // comes from. -// h -> this function requires a specific header or an explicit declaration. // i -> this is a runtime library implemented function without the // '__builtin_' prefix. It will be implemented in compiler-rt or libgcc. // p:N: -> this is a printf-like function whose Nth argument is the format @@ -709,9 +708,6 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn" // Microsoft builtins. These are only active with -fms-extensions. LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES) -LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES) -LIBBUILTIN(_byteswap_ulong, "ULiULi", "fnc", "stdlib.h", ALL_MS_LANGUAGES) -LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", "stdlib.h", ALL_MS_LANGUAGES) LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__exception_code, "ULi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_exception_code, "ULi", "n", ALL_MS_LANGUAGES) @@ -757,9 +753,6 @@ LANGBUILTIN(_InterlockedXor16, "ssD*s", LANGBUILTIN(_InterlockedXor, "LiLiD*Li","n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) -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(_rotl8, "UcUcUc","n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl16, "UsUsUc","n", ALL_MS_LANGUAGES) Modified: cfe/trunk/include/clang/Basic/Builtins.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.h?rev=281399=281398=281399=diff == --- cfe/trunk/include/clang/Basic/Builtins.h (original) +++ cfe/trunk/include/clang/Basic/Builtins.h Tue Sep 13 16:24:51 2016 @@ -139,13 +139,6 @@ public: return strchr(getRecord(ID).Attributes, 'f') != nullptr; } - // \brief Returns true if this builtin requires appropriate header in other - // compilers. In Clang it will work even without including it, but we can emit - // a warning about missing header. - bool isHeaderDependentFunction(unsigned ID) const { -return strchr(getRecord(ID).Attributes, 'h') != nullptr; - } - /// \brief Determines whether this builtin is a predefined compiler-rt/libgcc /// function, such as "__clear_cache", where we know the signature a /// priori. Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=281399=281398=281399=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Tue Sep 13 16:24:51 2016 @@ -23,10 +23,6 @@ # define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif -#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) -# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif - // FIXME: Are these nothrow/const? // Miscellaneous builtin for checking x86 cpu features. @@ -305,9 +301,7 @@ TARGET_BUILTIN(__builtin_ia32_pabsw128, TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "", "ssse3") TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "", "sse") -TARGET_HEADER_BUILTIN(_mm_setcsr, "vUi", "h","xmmintrin.h", ALL_LANGUAGES, "sse") TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "", "sse")
Re: [PATCH] D24153: Add bunch of _Interlocked builtins
This revision was automatically updated to reflect the committed changes. Closed by commit rL281378: Add bunch of _Interlocked builtins (authored by agutowski). Changed prior to commit: https://reviews.llvm.org/D24153?vs=70572=71223#toc Repository: rL LLVM https://reviews.llvm.org/D24153 Files: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/intrin.h cfe/trunk/test/CodeGen/ms-intrinsics.c cfe/trunk/test/CodeGen/pr27892.c Index: cfe/trunk/include/clang/Basic/Builtins.def === --- cfe/trunk/include/clang/Basic/Builtins.def +++ cfe/trunk/include/clang/Basic/Builtins.def @@ -720,13 +720,42 @@ LANGBUILTIN(__abnormal_termination, "i", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_abnormal_termination, "i", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__GetExceptionInfo, "v*.", "ntu", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedAnd8, "ccD*c","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedAnd16, "ssD*s","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedAnd,"LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedCompareExchange8, "ccD*cc", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedCompareExchange16, "ssD*ss", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedCompareExchange,"LiLiD*LiLi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedCompareExchange64, "LLiLLiD*LLiLLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchange,"LiLiD*Li", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedDecrement16,"ssD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedDecrement64,"LLiLLiD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchange8, "ccD*c","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchange16, "ssD*s","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeAdd8, "ccD*c", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeAdd16, "ssD*s", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeAdd,"LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangePointer,"v*v*D*v*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeSub8, "ccD*c","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeSub16, "ssD*s","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeSub,"LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedIncrement16,"ssD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedIncrement64,"LLiLLiD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedOr8, "ccD*c","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedOr16, "ssD*s","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedOr, "LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedXor, "LiLiD*Li","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES) Index: cfe/trunk/test/CodeGen/pr27892.c === --- cfe/trunk/test/CodeGen/pr27892.c +++ cfe/trunk/test/CodeGen/pr27892.c @@ -7,7 +7,7 @@ // CHECK: %[[p_addr:.*]] = alloca i64*, align 8 // CHECK: store i64* %p, i64** %[[p_addr]], align 8 // CHECK: %[[p_load:.*]] = load i64*, i64** %[[p_addr]], align 8 -// CHECK: %[[atomic_add:.*]] = atomicrmw volatile add i64* %[[p_load]], i64 1 seq_cst +// CHECK: %[[atomic_add:.*]] = atomicrmw add i64* %[[p_load]], i64 1 seq_cst // CHECK: %[[res:.*]] = add
Re: [PATCH] D24330: Add some MS aliases for existing intrinsics
This revision was automatically updated to reflect the committed changes. Closed by commit rL281375: Add some MS aliases for existing intrinsics (authored by agutowski). Changed prior to commit: https://reviews.llvm.org/D24330?vs=71213=71220#toc Repository: rL LLVM https://reviews.llvm.org/D24330 Files: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/include/clang/Basic/Builtins.h cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/emmintrin.h cfe/trunk/lib/Headers/ia32intrin.h cfe/trunk/lib/Headers/intrin.h cfe/trunk/lib/Headers/xmmintrin.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/CodeGen/builtins-x86.c cfe/trunk/test/Sema/implicit-intel-builtin-decl.c cfe/trunk/test/Sema/implicit-ms-builtin-decl.c Index: cfe/trunk/include/clang/Basic/BuiltinsX86.def === --- cfe/trunk/include/clang/Basic/BuiltinsX86.def +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def @@ -23,6 +23,10 @@ # define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif +#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) +# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + // FIXME: Are these nothrow/const? // Miscellaneous builtin for checking x86 cpu features. @@ -301,15 +305,18 @@ TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "", "ssse3") TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "", "sse") +TARGET_HEADER_BUILTIN(_mm_setcsr, "vUi", "h","xmmintrin.h", ALL_LANGUAGES, "sse") TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "", "sse") +TARGET_HEADER_BUILTIN(_mm_getcsr, "Ui", "h", "xmmintrin.h", ALL_LANGUAGES, "sse") TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_sfence, "v", "", "sse") +TARGET_HEADER_BUILTIN(_mm_sfence, "v", "h", "xmmintrin.h", ALL_LANGUAGES, "sse") TARGET_BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "", "sse") @@ -337,9 +344,13 @@ TARGET_BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "", "sse2") TARGET_BUILTIN(__builtin_ia32_clflush, "vvC*", "", "sse2") +TARGET_HEADER_BUILTIN(_mm_clflush, "vvC*", "h", "emmintrin.h", ALL_LANGUAGES, "sse2") TARGET_BUILTIN(__builtin_ia32_lfence, "v", "", "sse2") +TARGET_HEADER_BUILTIN(_mm_lfence, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2") TARGET_BUILTIN(__builtin_ia32_mfence, "v", "", "sse2") +TARGET_HEADER_BUILTIN(_mm_mfence, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2") TARGET_BUILTIN(__builtin_ia32_pause, "v", "", "sse2") +TARGET_HEADER_BUILTIN(_mm_pause, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2") TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "", "sse2") TARGET_BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "", "sse2") TARGET_BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "", "sse2") @@ -894,6 +905,7 @@ BUILTIN(__builtin_ia32_rdpmc, "ULLii", "") BUILTIN(__builtin_ia32_rdtsc, "ULLi", "") +BUILTIN(__rdtsc, "ULLi", "") BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "") // PKU TARGET_BUILTIN(__builtin_ia32_rdpkru, "Ui", "", "pku") @@ -2059,3 +2071,4 @@ #undef BUILTIN #undef TARGET_BUILTIN +#undef TARGET_HEADER_BUILTIN Index: cfe/trunk/include/clang/Basic/Builtins.h === --- cfe/trunk/include/clang/Basic/Builtins.h +++ cfe/trunk/include/clang/Basic/Builtins.h @@ -139,6 +139,13 @@ return strchr(getRecord(ID).Attributes, 'f') != nullptr; } + // \brief Returns true if this builtin requires appropriate header in other + // compilers. In Clang it will work even without including it, but we can emit + // a warning about missing header. + bool isHeaderDependentFunction(unsigned ID) const { +return strchr(getRecord(ID).Attributes, 'h') != nullptr; + } + /// \brief Determines whether this builtin is a predefined compiler-rt/libgcc /// function, such as "__clear_cache", where we know the signature a /// priori. Index: cfe/trunk/include/clang/Basic/Builtins.def === --- cfe/trunk/include/clang/Basic/Builtins.def +++ cfe/trunk/include/clang/Basic/Builtins.def @@ -74,6 +74,7 @@ // f -> this is a libc/libm function without the '__builtin_' prefix. It can // be followed by ':headername:' to state which header this function // comes
r281375 - Add some MS aliases for existing intrinsics
Author: agutowski Date: Tue Sep 13 14:26:42 2016 New Revision: 281375 URL: http://llvm.org/viewvc/llvm-project?rev=281375=rev Log: Add some MS aliases for existing intrinsics Reviewers: thakis, compnerd, majnemer, rsmith, rnk Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D24330 Added: cfe/trunk/test/Sema/implicit-intel-builtin-decl.c cfe/trunk/test/Sema/implicit-ms-builtin-decl.c Modified: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/include/clang/Basic/Builtins.h cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/emmintrin.h cfe/trunk/lib/Headers/ia32intrin.h cfe/trunk/lib/Headers/intrin.h cfe/trunk/lib/Headers/xmmintrin.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/CodeGen/builtins-x86.c Modified: cfe/trunk/include/clang/Basic/Builtins.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=281375=281374=281375=diff == --- cfe/trunk/include/clang/Basic/Builtins.def (original) +++ cfe/trunk/include/clang/Basic/Builtins.def Tue Sep 13 14:26:42 2016 @@ -74,6 +74,7 @@ // f -> this is a libc/libm function without the '__builtin_' prefix. It can // be followed by ':headername:' to state which header this function // comes from. +// h -> this function requires a specific header or an explicit declaration. // i -> this is a runtime library implemented function without the // '__builtin_' prefix. It will be implemented in compiler-rt or libgcc. // p:N: -> this is a printf-like function whose Nth argument is the format @@ -708,6 +709,9 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn" // Microsoft builtins. These are only active with -fms-extensions. LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES) +LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES) +LIBBUILTIN(_byteswap_ulong, "ULiULi", "fnc", "stdlib.h", ALL_MS_LANGUAGES) +LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", "stdlib.h", ALL_MS_LANGUAGES) LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__exception_code, "ULi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_exception_code, "ULi", "n", ALL_MS_LANGUAGES) @@ -724,6 +728,9 @@ LANGBUILTIN(_InterlockedExchange, LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) +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(_rotl8, "UcUcUc","n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl16, "UsUsUc","n", ALL_MS_LANGUAGES) Modified: cfe/trunk/include/clang/Basic/Builtins.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.h?rev=281375=281374=281375=diff == --- cfe/trunk/include/clang/Basic/Builtins.h (original) +++ cfe/trunk/include/clang/Basic/Builtins.h Tue Sep 13 14:26:42 2016 @@ -139,6 +139,13 @@ public: return strchr(getRecord(ID).Attributes, 'f') != nullptr; } + // \brief Returns true if this builtin requires appropriate header in other + // compilers. In Clang it will work even without including it, but we can emit + // a warning about missing header. + bool isHeaderDependentFunction(unsigned ID) const { +return strchr(getRecord(ID).Attributes, 'h') != nullptr; + } + /// \brief Determines whether this builtin is a predefined compiler-rt/libgcc /// function, such as "__clear_cache", where we know the signature a /// priori. Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=281375=281374=281375=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Tue Sep 13 14:26:42 2016 @@ -23,6 +23,10 @@ # define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif +#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) +# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + // FIXME: Are these nothrow/const? // Miscellaneous builtin for checking x86 cpu features. @@ -301,7 +305,9 @@ TARGET_BUILTIN(__builtin_ia32_pabsw128, TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "", "ssse3") TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "", "sse")
Re: [PATCH] D24330: Add some MS aliases for existing intrinsics
agutowski updated this revision to Diff 71213. agutowski added a comment. Merge C and C++ tests https://reviews.llvm.org/D24330 Files: include/clang/Basic/Builtins.def include/clang/Basic/Builtins.h include/clang/Basic/BuiltinsX86.def lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/Headers/emmintrin.h lib/Headers/ia32intrin.h lib/Headers/intrin.h lib/Headers/xmmintrin.h lib/Sema/SemaDecl.cpp test/CodeGen/builtins-x86.c test/Sema/implicit-intel-builtin-decl.c test/Sema/implicit-ms-builtin-decl.c Index: lib/Headers/ia32intrin.h === --- lib/Headers/ia32intrin.h +++ lib/Headers/ia32intrin.h @@ -60,12 +60,6 @@ return __builtin_ia32_rdpmc(__A); } -/* __rdtsc */ -static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) -__rdtsc(void) { - return __builtin_ia32_rdtsc(); -} - /* __rdtscp */ static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) __rdtscp(unsigned int *__A) { Index: lib/Headers/emmintrin.h === --- lib/Headers/emmintrin.h +++ lib/Headers/emmintrin.h @@ -2457,11 +2457,7 @@ /// \param __p ///A pointer to the memory location used to identify the cache line to be ///flushed. -static __inline__ void __DEFAULT_FN_ATTRS -_mm_clflush(void const *__p) -{ - __builtin_ia32_clflush(__p); -} +void _mm_clflush(void const *); /// \brief Forces strong memory ordering (serialization) between load ///instructions preceding this instruction and load instructions following @@ -2472,11 +2468,7 @@ /// /// This intrinsic corresponds to the \c LFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_lfence(void) -{ - __builtin_ia32_lfence(); -} +void _mm_lfence(void); /// \brief Forces strong memory ordering (serialization) between load and store ///instructions preceding this instruction and load and store instructions @@ -2487,11 +2479,7 @@ /// /// This intrinsic corresponds to the \c MFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_mfence(void) -{ - __builtin_ia32_mfence(); -} +void _mm_mfence(void); /// \brief Converts 16-bit signed integers from both 128-bit integer vector ///operands into 8-bit signed integers, and packs the results into the @@ -3213,11 +3201,7 @@ /// /// This intrinsic corresponds to the \c PAUSE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_pause(void) -{ - __builtin_ia32_pause(); -} +void _mm_pause(void); #undef __DEFAULT_FN_ATTRS Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -518,14 +518,6 @@ *_Index = 31 - __builtin_clzl(_Mask); return 1; } -static __inline__ unsigned short __DEFAULT_FN_ATTRS -__popcnt16(unsigned short _Value) { - return __builtin_popcount((int)_Value); -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -__popcnt(unsigned int _Value) { - return __builtin_popcount(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest(long const *_BitBase, long _BitPos) { return (*_BitBase >> _BitPos) & 1; @@ -568,11 +560,6 @@ *_Index = 63 - __builtin_clzll(_Mask); return 1; } -static __inline__ -unsigned __int64 __DEFAULT_FN_ATTRS -__popcnt64(unsigned __int64 _Value) { - return __builtin_popcountll(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest64(__int64 const *_BitBase, __int64 _BitPos) { return (*_BitBase >> _BitPos) & 1; Index: lib/Headers/xmmintrin.h === --- lib/Headers/xmmintrin.h +++ lib/Headers/xmmintrin.h @@ -2094,11 +2094,7 @@ /// /// This intrinsic corresponds to the \c SFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_sfence(void) -{ - __builtin_ia32_sfence(); -} +void _mm_sfence(void); /// \brief Extracts 16-bit element from a 64-bit vector of [4 x i16] and ///returns it, as specified by the immediate integer operand. @@ -2408,11 +2404,7 @@ /// /// \returns A 32-bit unsigned integer containing the contents of the MXCSR ///register. -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_mm_getcsr(void) -{ - return __builtin_ia32_stmxcsr(); -} +unsigned int _mm_getcsr(void); /// \brief Sets the MXCSR register with the 32-bit unsigned integer value. There ///are several groups of macros associated with this intrinsic, including: @@ -2450,11 +2442,7 @@ /// /// \param __i ///A 32-bit unsigned integer value to be written to the MXCSR register. -static __inline__ void __DEFAULT_FN_ATTRS -_mm_setcsr(unsigned int __i) -{ - __builtin_ia32_ldmxcsr(__i); -} +void _mm_setcsr(unsigned int); /// \brief Selects 4 float values from the 128-bit operands of [4 x float], as ///specified by the immediate value operand. Index: lib/CodeGen/CGBuiltin.cpp
Re: [PATCH] D24330: Add some MS aliases for existing intrinsics
agutowski updated this revision to Diff 71212. agutowski added a comment. Add test for implicitly declared intel intrinsic diagnostic in C++ https://reviews.llvm.org/D24330 Files: include/clang/Basic/Builtins.def include/clang/Basic/Builtins.h include/clang/Basic/BuiltinsX86.def lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/Headers/emmintrin.h lib/Headers/ia32intrin.h lib/Headers/intrin.h lib/Headers/xmmintrin.h lib/Sema/SemaDecl.cpp test/CodeGen/builtins-x86.c test/Sema/implicit-intel-builtin-decl.c test/Sema/implicit-intel-builtin-decl.cpp test/Sema/implicit-ms-builtin-decl.c Index: lib/Headers/ia32intrin.h === --- lib/Headers/ia32intrin.h +++ lib/Headers/ia32intrin.h @@ -60,12 +60,6 @@ return __builtin_ia32_rdpmc(__A); } -/* __rdtsc */ -static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) -__rdtsc(void) { - return __builtin_ia32_rdtsc(); -} - /* __rdtscp */ static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) __rdtscp(unsigned int *__A) { Index: lib/Headers/emmintrin.h === --- lib/Headers/emmintrin.h +++ lib/Headers/emmintrin.h @@ -2457,11 +2457,7 @@ /// \param __p ///A pointer to the memory location used to identify the cache line to be ///flushed. -static __inline__ void __DEFAULT_FN_ATTRS -_mm_clflush(void const *__p) -{ - __builtin_ia32_clflush(__p); -} +void _mm_clflush(void const *); /// \brief Forces strong memory ordering (serialization) between load ///instructions preceding this instruction and load instructions following @@ -2472,11 +2468,7 @@ /// /// This intrinsic corresponds to the \c LFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_lfence(void) -{ - __builtin_ia32_lfence(); -} +void _mm_lfence(void); /// \brief Forces strong memory ordering (serialization) between load and store ///instructions preceding this instruction and load and store instructions @@ -2487,11 +2479,7 @@ /// /// This intrinsic corresponds to the \c MFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_mfence(void) -{ - __builtin_ia32_mfence(); -} +void _mm_mfence(void); /// \brief Converts 16-bit signed integers from both 128-bit integer vector ///operands into 8-bit signed integers, and packs the results into the @@ -3213,11 +3201,7 @@ /// /// This intrinsic corresponds to the \c PAUSE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_pause(void) -{ - __builtin_ia32_pause(); -} +void _mm_pause(void); #undef __DEFAULT_FN_ATTRS Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -518,14 +518,6 @@ *_Index = 31 - __builtin_clzl(_Mask); return 1; } -static __inline__ unsigned short __DEFAULT_FN_ATTRS -__popcnt16(unsigned short _Value) { - return __builtin_popcount((int)_Value); -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -__popcnt(unsigned int _Value) { - return __builtin_popcount(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest(long const *_BitBase, long _BitPos) { return (*_BitBase >> _BitPos) & 1; @@ -568,11 +560,6 @@ *_Index = 63 - __builtin_clzll(_Mask); return 1; } -static __inline__ -unsigned __int64 __DEFAULT_FN_ATTRS -__popcnt64(unsigned __int64 _Value) { - return __builtin_popcountll(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest64(__int64 const *_BitBase, __int64 _BitPos) { return (*_BitBase >> _BitPos) & 1; Index: lib/Headers/xmmintrin.h === --- lib/Headers/xmmintrin.h +++ lib/Headers/xmmintrin.h @@ -2094,11 +2094,7 @@ /// /// This intrinsic corresponds to the \c SFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_sfence(void) -{ - __builtin_ia32_sfence(); -} +void _mm_sfence(void); /// \brief Extracts 16-bit element from a 64-bit vector of [4 x i16] and ///returns it, as specified by the immediate integer operand. @@ -2408,11 +2404,7 @@ /// /// \returns A 32-bit unsigned integer containing the contents of the MXCSR ///register. -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_mm_getcsr(void) -{ - return __builtin_ia32_stmxcsr(); -} +unsigned int _mm_getcsr(void); /// \brief Sets the MXCSR register with the 32-bit unsigned integer value. There ///are several groups of macros associated with this intrinsic, including: @@ -2450,11 +2442,7 @@ /// /// \param __i ///A 32-bit unsigned integer value to be written to the MXCSR register. -static __inline__ void __DEFAULT_FN_ATTRS -_mm_setcsr(unsigned int __i) -{ - __builtin_ia32_ldmxcsr(__i); -} +void _mm_setcsr(unsigned int); /// \brief Selects 4 float values from the 128-bit operands of [4 x float], as ///specified
Re: [PATCH] D24330: Add some MS aliases for existing intrinsics
agutowski added inline comments. Comment at: test/Sema/implicit-intel-builtin-decl.c:4 @@ +3,3 @@ +void f() { + (void)_mm_getcsr(); // expected-warning{{implicitly declaring library function '_mm_getcsr'}} \ + // expected-note{{include the header or explicitly provide a declaration for '_mm_getcsr'}} rnk wrote: > Can you add a C++ test? I think you'll get "undeclared identifier > '_mm_getcsr'" instead of this helpful diagnostic. This diagnostic works also in C++, although that's not the case with _byteswap functions - if they are LIBBUILTINs, the C++ diagnostic doesn't work, and LANGBUILTINs doesn't have header dependencies. I can create another thing like TARGET_HEADER_BUILTIN, but I don't know if that's a good idea. https://reviews.llvm.org/D24330 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D24330: Add some MS aliases for existing intrinsics
agutowski updated this revision to Diff 70926. agutowski added a comment. Separated Intel intrinsics tests https://reviews.llvm.org/D24330 Files: include/clang/Basic/Builtins.def include/clang/Basic/Builtins.h include/clang/Basic/BuiltinsX86.def lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/Headers/emmintrin.h lib/Headers/ia32intrin.h lib/Headers/intrin.h lib/Headers/xmmintrin.h lib/Sema/SemaDecl.cpp test/CodeGen/builtins-x86.c test/Sema/implicit-intel-builtin-decl.c test/Sema/implicit-ms-builtin-decl.c Index: lib/Headers/ia32intrin.h === --- lib/Headers/ia32intrin.h +++ lib/Headers/ia32intrin.h @@ -60,12 +60,6 @@ return __builtin_ia32_rdpmc(__A); } -/* __rdtsc */ -static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) -__rdtsc(void) { - return __builtin_ia32_rdtsc(); -} - /* __rdtscp */ static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) __rdtscp(unsigned int *__A) { Index: lib/Headers/emmintrin.h === --- lib/Headers/emmintrin.h +++ lib/Headers/emmintrin.h @@ -2457,11 +2457,7 @@ /// \param __p ///A pointer to the memory location used to identify the cache line to be ///flushed. -static __inline__ void __DEFAULT_FN_ATTRS -_mm_clflush(void const *__p) -{ - __builtin_ia32_clflush(__p); -} +void _mm_clflush(void const *); /// \brief Forces strong memory ordering (serialization) between load ///instructions preceding this instruction and load instructions following @@ -2472,11 +2468,7 @@ /// /// This intrinsic corresponds to the \c LFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_lfence(void) -{ - __builtin_ia32_lfence(); -} +void _mm_lfence(void); /// \brief Forces strong memory ordering (serialization) between load and store ///instructions preceding this instruction and load and store instructions @@ -2487,11 +2479,7 @@ /// /// This intrinsic corresponds to the \c MFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_mfence(void) -{ - __builtin_ia32_mfence(); -} +void _mm_mfence(void); /// \brief Converts 16-bit signed integers from both 128-bit integer vector ///operands into 8-bit signed integers, and packs the results into the @@ -3213,11 +3201,7 @@ /// /// This intrinsic corresponds to the \c PAUSE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_pause(void) -{ - __builtin_ia32_pause(); -} +void _mm_pause(void); #undef __DEFAULT_FN_ATTRS Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -518,14 +518,6 @@ *_Index = 31 - __builtin_clzl(_Mask); return 1; } -static __inline__ unsigned short __DEFAULT_FN_ATTRS -__popcnt16(unsigned short _Value) { - return __builtin_popcount((int)_Value); -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -__popcnt(unsigned int _Value) { - return __builtin_popcount(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest(long const *_BitBase, long _BitPos) { return (*_BitBase >> _BitPos) & 1; @@ -568,11 +560,6 @@ *_Index = 63 - __builtin_clzll(_Mask); return 1; } -static __inline__ -unsigned __int64 __DEFAULT_FN_ATTRS -__popcnt64(unsigned __int64 _Value) { - return __builtin_popcountll(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest64(__int64 const *_BitBase, __int64 _BitPos) { return (*_BitBase >> _BitPos) & 1; Index: lib/Headers/xmmintrin.h === --- lib/Headers/xmmintrin.h +++ lib/Headers/xmmintrin.h @@ -2094,11 +2094,7 @@ /// /// This intrinsic corresponds to the \c SFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_sfence(void) -{ - __builtin_ia32_sfence(); -} +void _mm_sfence(void); /// \brief Extracts 16-bit element from a 64-bit vector of [4 x i16] and ///returns it, as specified by the immediate integer operand. @@ -2408,11 +2404,7 @@ /// /// \returns A 32-bit unsigned integer containing the contents of the MXCSR ///register. -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_mm_getcsr(void) -{ - return __builtin_ia32_stmxcsr(); -} +unsigned int _mm_getcsr(void); /// \brief Sets the MXCSR register with the 32-bit unsigned integer value. There ///are several groups of macros associated with this intrinsic, including: @@ -2450,11 +2442,7 @@ /// /// \param __i ///A 32-bit unsigned integer value to be written to the MXCSR register. -static __inline__ void __DEFAULT_FN_ATTRS -_mm_setcsr(unsigned int __i) -{ - __builtin_ia32_ldmxcsr(__i); -} +void _mm_setcsr(unsigned int); /// \brief Selects 4 float values from the 128-bit operands of [4 x float], as ///specified by the immediate value operand. Index: lib/CodeGen/CGBuiltin.cpp
Re: [PATCH] D24330: Add some MS aliases for existing intrinsics
agutowski updated this revision to Diff 70923. agutowski added a comment. Changed way of handling Intel intrinsics Removed constant folding https://reviews.llvm.org/D24330 Files: include/clang/Basic/Builtins.def include/clang/Basic/Builtins.h include/clang/Basic/BuiltinsX86.def lib/Basic/Targets.cpp lib/CodeGen/CGBuiltin.cpp lib/Headers/emmintrin.h lib/Headers/ia32intrin.h lib/Headers/intrin.h lib/Headers/xmmintrin.h lib/Sema/SemaDecl.cpp test/CodeGen/builtins-x86.c test/Sema/implicit-ms-builtin-decl.c Index: lib/Headers/ia32intrin.h === --- lib/Headers/ia32intrin.h +++ lib/Headers/ia32intrin.h @@ -60,12 +60,6 @@ return __builtin_ia32_rdpmc(__A); } -/* __rdtsc */ -static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) -__rdtsc(void) { - return __builtin_ia32_rdtsc(); -} - /* __rdtscp */ static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) __rdtscp(unsigned int *__A) { Index: lib/Headers/emmintrin.h === --- lib/Headers/emmintrin.h +++ lib/Headers/emmintrin.h @@ -2457,11 +2457,7 @@ /// \param __p ///A pointer to the memory location used to identify the cache line to be ///flushed. -static __inline__ void __DEFAULT_FN_ATTRS -_mm_clflush(void const *__p) -{ - __builtin_ia32_clflush(__p); -} +void _mm_clflush(void const *); /// \brief Forces strong memory ordering (serialization) between load ///instructions preceding this instruction and load instructions following @@ -2472,11 +2468,7 @@ /// /// This intrinsic corresponds to the \c LFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_lfence(void) -{ - __builtin_ia32_lfence(); -} +void _mm_lfence(void); /// \brief Forces strong memory ordering (serialization) between load and store ///instructions preceding this instruction and load and store instructions @@ -2487,11 +2479,7 @@ /// /// This intrinsic corresponds to the \c MFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_mfence(void) -{ - __builtin_ia32_mfence(); -} +void _mm_mfence(void); /// \brief Converts 16-bit signed integers from both 128-bit integer vector ///operands into 8-bit signed integers, and packs the results into the @@ -3213,11 +3201,7 @@ /// /// This intrinsic corresponds to the \c PAUSE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_pause(void) -{ - __builtin_ia32_pause(); -} +void _mm_pause(void); #undef __DEFAULT_FN_ATTRS Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -518,14 +518,6 @@ *_Index = 31 - __builtin_clzl(_Mask); return 1; } -static __inline__ unsigned short __DEFAULT_FN_ATTRS -__popcnt16(unsigned short _Value) { - return __builtin_popcount((int)_Value); -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -__popcnt(unsigned int _Value) { - return __builtin_popcount(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest(long const *_BitBase, long _BitPos) { return (*_BitBase >> _BitPos) & 1; @@ -568,11 +560,6 @@ *_Index = 63 - __builtin_clzll(_Mask); return 1; } -static __inline__ -unsigned __int64 __DEFAULT_FN_ATTRS -__popcnt64(unsigned __int64 _Value) { - return __builtin_popcountll(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest64(__int64 const *_BitBase, __int64 _BitPos) { return (*_BitBase >> _BitPos) & 1; Index: lib/Headers/xmmintrin.h === --- lib/Headers/xmmintrin.h +++ lib/Headers/xmmintrin.h @@ -2094,11 +2094,7 @@ /// /// This intrinsic corresponds to the \c SFENCE instruction. /// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_sfence(void) -{ - __builtin_ia32_sfence(); -} +void _mm_sfence(void); /// \brief Extracts 16-bit element from a 64-bit vector of [4 x i16] and ///returns it, as specified by the immediate integer operand. @@ -2408,11 +2404,7 @@ /// /// \returns A 32-bit unsigned integer containing the contents of the MXCSR ///register. -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_mm_getcsr(void) -{ - return __builtin_ia32_stmxcsr(); -} +unsigned int _mm_getcsr(void); /// \brief Sets the MXCSR register with the 32-bit unsigned integer value. There ///are several groups of macros associated with this intrinsic, including: @@ -2450,11 +2442,7 @@ /// /// \param __i ///A 32-bit unsigned integer value to be written to the MXCSR register. -static __inline__ void __DEFAULT_FN_ATTRS -_mm_setcsr(unsigned int __i) -{ - __builtin_ia32_ldmxcsr(__i); -} +void _mm_setcsr(unsigned int); /// \brief Selects 4 float values from the 128-bit operands of [4 x float], as ///specified by the immediate value operand. Index: lib/CodeGen/CGBuiltin.cpp
Re: [PATCH] D24311: Implement MS _rot intrinsics
This revision was automatically updated to reflect the committed changes. Closed by commit rL280997: Implement MS _rot intrinsics (authored by agutowski). Changed prior to commit: https://reviews.llvm.org/D24311?vs=70747=70759#toc Repository: rL LLVM https://reviews.llvm.org/D24311 Files: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/intrin.h cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c Index: cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c === --- cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c +++ cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c @@ -0,0 +1,181 @@ +// 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-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ +// RUN: -triple thumbv7--windows -emit-llvm %s -o - \ +// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// 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-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ +// RUN: -triple i686--linux -emit-llvm %s -o - \ +// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ +// RUN: -triple x86_64--linux -emit-llvm %s -o - \ +// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG + +// rotate left + +unsigned char test_rotl8(unsigned char value, unsigned char shift) { + return _rotl8(value, shift); +} +// CHECK: i8 @test_rotl8 +// CHECK: [[SHIFT:%[0-9]+]] = and i8 %{{[0-9]+}}, 7 +// CHECK: [[NEGSHIFT:%[0-9]+]] = sub i8 8, [[SHIFT]] +// CHECK: [[HIGH:%[0-9]+]] = shl i8 [[VALUE:%[0-9]+]], [[SHIFT]] +// CHECK: [[LOW:%[0-9]+]] = lshr i8 [[VALUE]], [[NEGSHIFT]] +// CHECK: [[ROTATED:%[0-9]+]] = or i8 [[HIGH]], [[LOW]] +// CHECK: [[ISZERO:%[0-9]+]] = icmp eq i8 [[SHIFT]], 0 +// CHECK: [[RESULT:%[0-9]+]] = select i1 [[ISZERO]], i8 [[VALUE]], i8 [[ROTATED]] +// CHECK: ret i8 [[RESULT]] +// CHECK } + +unsigned short test_rotl16(unsigned short value, unsigned char shift) { + return _rotl16(value, shift); +} +// CHECK: i16 @test_rotl16 +// CHECK: [[SHIFT:%[0-9]+]] = and i16 %{{[0-9]+}}, 15 +// CHECK: [[NEGSHIFT:%[0-9]+]] = sub i16 16, [[SHIFT]] +// CHECK: [[HIGH:%[0-9]+]] = shl i16 [[VALUE:%[0-9]+]], [[SHIFT]] +// CHECK: [[LOW:%[0-9]+]] = lshr i16 [[VALUE]], [[NEGSHIFT]] +// CHECK: [[ROTATED:%[0-9]+]] = or i16 [[HIGH]], [[LOW]] +// CHECK: [[ISZERO:%[0-9]+]] = icmp eq i16 [[SHIFT]], 0 +// CHECK: [[RESULT:%[0-9]+]] = select i1 [[ISZERO]], i16 [[VALUE]], i16 [[ROTATED]] +// CHECK: ret i16 [[RESULT]] +// CHECK } + +unsigned int test_rotl(unsigned int value, int shift) { + return _rotl(value, shift); +} +// CHECK: i32 @test_rotl +// CHECK: [[SHIFT:%[0-9]+]] = and i32 %{{[0-9]+}}, 31 +// CHECK: [[NEGSHIFT:%[0-9]+]] = sub i32 32, [[SHIFT]] +// CHECK: [[HIGH:%[0-9]+]] = shl i32 [[VALUE:%[0-9]+]], [[SHIFT]] +// CHECK: [[LOW:%[0-9]+]] = lshr i32 [[VALUE]], [[NEGSHIFT]] +// CHECK: [[ROTATED:%[0-9]+]] = or i32 [[HIGH]], [[LOW]] +// CHECK: [[ISZERO:%[0-9]+]] = icmp eq i32 [[SHIFT]], 0 +// CHECK: [[RESULT:%[0-9]+]] = select i1 [[ISZERO]], i32 [[VALUE]], i32 [[ROTATED]] +// CHECK: ret i32 [[RESULT]] +// CHECK } + +unsigned long test_lrotl(unsigned long value, int shift) { + return _lrotl(value, shift); +} +// CHECK-32BIT-LONG: i32 @test_lrotl +// CHECK-32BIT-LONG: [[SHIFT:%[0-9]+]] = and i32 %{{[0-9]+}}, 31 +// CHECK-32BIT-LONG: [[NEGSHIFT:%[0-9]+]] = sub i32 32, [[SHIFT]] +// CHECK-32BIT-LONG: [[HIGH:%[0-9]+]] = shl i32 [[VALUE:%[0-9]+]], [[SHIFT]] +// CHECK-32BIT-LONG: [[LOW:%[0-9]+]] = lshr i32 [[VALUE]], [[NEGSHIFT]] +// CHECK-32BIT-LONG: [[ROTATED:%[0-9]+]] = or i32 [[HIGH]], [[LOW]] +// CHECK-32BIT-LONG: [[ISZERO:%[0-9]+]] = icmp eq i32 [[SHIFT]], 0 +// CHECK-32BIT-LONG: [[RESULT:%[0-9]+]] = select i1 [[ISZERO]], i32 [[VALUE]], i32 [[ROTATED]] +// CHECK-32BIT-LONG: ret i32 [[RESULT]] +// CHECK-32BIT-LONG } + +// CHECK-64BIT-LONG: i64 @test_lrotl +// CHECK-64BIT-LONG: [[SHIFT:%[0-9]+]] = and i64 %{{[0-9]+}}, 63 +// CHECK-64BIT-LONG: [[NEGSHIFT:%[0-9]+]] = sub i64 64, [[SHIFT]] +// CHECK-64BIT-LONG: [[HIGH:%[0-9]+]] = shl i64 [[VALUE:%[0-9]+]], [[SHIFT]] +// CHECK-64BIT-LONG: [[LOW:%[0-9]+]] = lshr i64 [[VALUE]], [[NEGSHIFT]] +// CHECK-64BIT-LONG: [[ROTATED:%[0-9]+]] = or i64 [[HIGH]], [[LOW]] +// CHECK-64BIT-LONG: [[ISZERO:%[0-9]+]] = icmp eq i64
r280997 - Implement MS _rot intrinsics
Author: agutowski Date: Thu Sep 8 17:32:19 2016 New Revision: 280997 URL: http://llvm.org/viewvc/llvm-project?rev=280997=rev Log: Implement MS _rot intrinsics Reviewers: thakis, Prazek, compnerd, rnk Subscribers: majnemer, cfe-commits Differential Revision: https://reviews.llvm.org/D24311 Added: cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c Modified: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/intrin.h Modified: cfe/trunk/include/clang/Basic/Builtins.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=280997=280996=280997=diff == --- cfe/trunk/include/clang/Basic/Builtins.def (original) +++ cfe/trunk/include/clang/Basic/Builtins.def Thu Sep 8 17:32:19 2016 @@ -725,6 +725,16 @@ LANGBUILTIN(_InterlockedExchangePointer, LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__readfsdword,"ULiULi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_rotl8, "UcUcUc","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_rotl16, "UsUsUc","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_lrotl, "ULiULii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_rotl64, "ULLiULLii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_rotr8, "UcUcUc","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_rotr16, "UsUsUc","n", ALL_MS_LANGUAGES) +LANGBUILTIN(_rotr, "UiUii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_lrotr, "ULiULii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_rotr64, "ULLiULLii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES) // Microsoft library builtins. Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=280997=280996=280997=diff == --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Thu Sep 8 17:32:19 2016 @@ -696,6 +696,58 @@ RValue CodeGenFunction::EmitBuiltinExpr( "cast"); return RValue::get(Result); } + case Builtin::BI_rotr8: + case Builtin::BI_rotr16: + case Builtin::BI_rotr: + case Builtin::BI_lrotr: + case Builtin::BI_rotr64: { +Value *Val = EmitScalarExpr(E->getArg(0)); +Value *Shift = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = Val->getType(); +Shift = Builder.CreateIntCast(Shift, ArgType, false); +unsigned ArgWidth = cast(ArgType)->getBitWidth(); +Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); +Value *ArgZero = llvm::Constant::getNullValue(ArgType); + +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift = Builder.CreateAnd(Shift, Mask); +Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift); + +Value *RightShifted = Builder.CreateLShr(Val, Shift); +Value *LeftShifted = Builder.CreateShl(Val, LeftShift); +Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); + +Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); +Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); +return RValue::get(Result); + } + case Builtin::BI_rotl8: + case Builtin::BI_rotl16: + case Builtin::BI_rotl: + case Builtin::BI_lrotl: + case Builtin::BI_rotl64: { +Value *Val = EmitScalarExpr(E->getArg(0)); +Value *Shift = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = Val->getType(); +Shift = Builder.CreateIntCast(Shift, ArgType, false); +unsigned ArgWidth = cast(ArgType)->getBitWidth(); +Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); +Value *ArgZero = llvm::Constant::getNullValue(ArgType); + +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift = Builder.CreateAnd(Shift, Mask); +Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift); + +Value *LeftShifted = Builder.CreateShl(Val, Shift); +Value *RightShifted = Builder.CreateLShr(Val, RightShift); +Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); + +Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); +Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); +return RValue::get(Result); + } case Builtin::BI__builtin_unpredictable: { // Always return the argument of __builtin_unpredictable. LLVM does not // handle this builtin. Metadata for this builtin should be added directly Modified: cfe/trunk/lib/Headers/intrin.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/intrin.h?rev=280997=280996=280997=diff == --- cfe/trunk/lib/Headers/intrin.h (original) +++ cfe/trunk/lib/Headers/intrin.h Thu Sep 8 17:32:19 2016 @@ -447,61 +447,6 @@
Re: [PATCH] D24311: Implement MS _rot intrinsics
agutowski marked 4 inline comments as done. agutowski added a comment. https://reviews.llvm.org/D24311 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D24311: Implement MS _rot intrinsics
agutowski updated this revision to Diff 70747. agutowski added a comment. Remove evaluating values for constant arguments https://reviews.llvm.org/D24311 Files: include/clang/Basic/Builtins.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics-rotations.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -447,61 +447,6 @@ return (unsigned __int64)__in1 * (unsigned __int64)__in2; } /**\ -|* Bit Twiddling -\**/ -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_rotl8(unsigned char _Value, unsigned char _Shift) { - _Shift &= 0x7; - return _Shift ? (_Value << _Shift) | (_Value >> (8 - _Shift)) : _Value; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_rotr8(unsigned char _Value, unsigned char _Shift) { - _Shift &= 0x7; - return _Shift ? (_Value >> _Shift) | (_Value << (8 - _Shift)) : _Value; -} -static __inline__ unsigned short __DEFAULT_FN_ATTRS -_rotl16(unsigned short _Value, unsigned char _Shift) { - _Shift &= 0xf; - return _Shift ? (_Value << _Shift) | (_Value >> (16 - _Shift)) : _Value; -} -static __inline__ unsigned short __DEFAULT_FN_ATTRS -_rotr16(unsigned short _Value, unsigned char _Shift) { - _Shift &= 0xf; - return _Shift ? (_Value >> _Shift) | (_Value << (16 - _Shift)) : _Value; -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_rotl(unsigned int _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value; -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_rotr(unsigned int _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value; -} -static __inline__ unsigned long __DEFAULT_FN_ATTRS -_lrotl(unsigned long _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value; -} -static __inline__ unsigned long __DEFAULT_FN_ATTRS -_lrotr(unsigned long _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value; -} -static -__inline__ unsigned __int64 __DEFAULT_FN_ATTRS -_rotl64(unsigned __int64 _Value, int _Shift) { - _Shift &= 0x3f; - return _Shift ? (_Value << _Shift) | (_Value >> (64 - _Shift)) : _Value; -} -static -__inline__ unsigned __int64 __DEFAULT_FN_ATTRS -_rotr64(unsigned __int64 _Value, int _Shift) { - _Shift &= 0x3f; - return _Shift ? (_Value >> _Shift) | (_Value << (64 - _Shift)) : _Value; -} -/**\ |* Bit Counting and Testing \**/ static __inline__ unsigned char __DEFAULT_FN_ATTRS Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -696,6 +696,58 @@ "cast"); return RValue::get(Result); } + case Builtin::BI_rotr8: + case Builtin::BI_rotr16: + case Builtin::BI_rotr: + case Builtin::BI_lrotr: + case Builtin::BI_rotr64: { +Value *Val = EmitScalarExpr(E->getArg(0)); +Value *Shift = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = Val->getType(); +Shift = Builder.CreateIntCast(Shift, ArgType, false); +unsigned ArgWidth = cast(ArgType)->getBitWidth(); +Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); +Value *ArgZero = llvm::Constant::getNullValue(ArgType); + +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift = Builder.CreateAnd(Shift, Mask); +Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift); + +Value *RightShifted = Builder.CreateLShr(Val, Shift); +Value *LeftShifted = Builder.CreateShl(Val, LeftShift); +Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); + +Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); +Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); +return RValue::get(Result); + } + case Builtin::BI_rotl8: + case Builtin::BI_rotl16: + case Builtin::BI_rotl: + case Builtin::BI_lrotl: + case Builtin::BI_rotl64: { +Value *Val = EmitScalarExpr(E->getArg(0)); +Value *Shift = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = Val->getType(); +Shift = Builder.CreateIntCast(Shift, ArgType, false); +unsigned ArgWidth = cast(ArgType)->getBitWidth(); +Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); +Value *ArgZero = llvm::Constant::getNullValue(ArgType); + +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift = Builder.CreateAnd(Shift, Mask); +Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift); + +Value
Re: [PATCH] D24311: Implement MS _rot intrinsics
agutowski added inline comments. Comment at: lib/AST/ExprConstant.cpp:7024-7050 @@ -7023,1 +7023,29 @@ + case Builtin::BI_rotl8: + case Builtin::BI_rotl16: + case Builtin::BI_rotl: + case Builtin::BI_lrotl: + case Builtin::BI_rotl64: { +APSInt Val, Shift; +if (!EvaluateInteger(E->getArg(0), Val, Info) || +!EvaluateInteger(E->getArg(1), Shift, Info)) + return false; + +APSInt BitWidth(llvm::APInt(32, Val.getBitWidth())); +return Success(Val.rotl(Shift % BitWidth), E); + } + + case Builtin::BI_rotr8: + case Builtin::BI_rotr16: + case Builtin::BI_rotr: + case Builtin::BI_lrotr: + case Builtin::BI_rotr64: { +APSInt Val, Shift; +if (!EvaluateInteger(E->getArg(0), Val, Info) || +!EvaluateInteger(E->getArg(1), Shift, Info)) + return false; + +APSInt BitWidth(llvm::APInt(32, Val.getBitWidth())); +return Success(Val.rotr(Shift % BitWidth), E); + } + majnemer wrote: > Any reason why we need this? > > Given: > #include > > constexpr int x = _rotl8(1, 2); > > MSVC 2015 reports: > error C2131: expression did not evaluate to a constant Hm, I don't know. Is there any reason why we shouldn't do this? I mean, I just had the feeling that if we can evaluate something during compilation time, we should to it. https://reviews.llvm.org/D24311 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D24311: Implement MS _rot intrinsics
agutowski updated this revision to Diff 70646. agutowski marked an inline comment as done. agutowski added a comment. Add evaluating values for constant arguments https://reviews.llvm.org/D24311 Files: include/clang/Basic/Builtins.def lib/AST/ExprConstant.cpp lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics-rotations.c test/Sema/constant-builtins-2.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -447,61 +447,6 @@ return (unsigned __int64)__in1 * (unsigned __int64)__in2; } /**\ -|* Bit Twiddling -\**/ -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_rotl8(unsigned char _Value, unsigned char _Shift) { - _Shift &= 0x7; - return _Shift ? (_Value << _Shift) | (_Value >> (8 - _Shift)) : _Value; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_rotr8(unsigned char _Value, unsigned char _Shift) { - _Shift &= 0x7; - return _Shift ? (_Value >> _Shift) | (_Value << (8 - _Shift)) : _Value; -} -static __inline__ unsigned short __DEFAULT_FN_ATTRS -_rotl16(unsigned short _Value, unsigned char _Shift) { - _Shift &= 0xf; - return _Shift ? (_Value << _Shift) | (_Value >> (16 - _Shift)) : _Value; -} -static __inline__ unsigned short __DEFAULT_FN_ATTRS -_rotr16(unsigned short _Value, unsigned char _Shift) { - _Shift &= 0xf; - return _Shift ? (_Value >> _Shift) | (_Value << (16 - _Shift)) : _Value; -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_rotl(unsigned int _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value; -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_rotr(unsigned int _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value; -} -static __inline__ unsigned long __DEFAULT_FN_ATTRS -_lrotl(unsigned long _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value; -} -static __inline__ unsigned long __DEFAULT_FN_ATTRS -_lrotr(unsigned long _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value; -} -static -__inline__ unsigned __int64 __DEFAULT_FN_ATTRS -_rotl64(unsigned __int64 _Value, int _Shift) { - _Shift &= 0x3f; - return _Shift ? (_Value << _Shift) | (_Value >> (64 - _Shift)) : _Value; -} -static -__inline__ unsigned __int64 __DEFAULT_FN_ATTRS -_rotr64(unsigned __int64 _Value, int _Shift) { - _Shift &= 0x3f; - return _Shift ? (_Value >> _Shift) | (_Value << (64 - _Shift)) : _Value; -} -/**\ |* Bit Counting and Testing \**/ static __inline__ unsigned char __DEFAULT_FN_ATTRS Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -696,6 +696,58 @@ "cast"); return RValue::get(Result); } + case Builtin::BI_rotr8: + case Builtin::BI_rotr16: + case Builtin::BI_rotr: + case Builtin::BI_lrotr: + case Builtin::BI_rotr64: { +Value *Val = EmitScalarExpr(E->getArg(0)); +Value *Shift = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = Val->getType(); +Shift = Builder.CreateIntCast(Shift, ArgType, false); +unsigned ArgWidth = cast(ArgType)->getBitWidth(); +Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); +Value *ArgZero = llvm::Constant::getNullValue(ArgType); + +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift = Builder.CreateAnd(Shift, Mask); +Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift); + +Value *RightShifted = Builder.CreateLShr(Val, Shift); +Value *LeftShifted = Builder.CreateShl(Val, LeftShift); +Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); + +Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); +Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); +return RValue::get(Result); + } + case Builtin::BI_rotl8: + case Builtin::BI_rotl16: + case Builtin::BI_rotl: + case Builtin::BI_lrotl: + case Builtin::BI_rotl64: { +Value *Val = EmitScalarExpr(E->getArg(0)); +Value *Shift = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = Val->getType(); +Shift = Builder.CreateIntCast(Shift, ArgType, false); +unsigned ArgWidth = cast(ArgType)->getBitWidth(); +Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); +Value *ArgZero = llvm::Constant::getNullValue(ArgType); + +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift =
[PATCH] D24330: Add some MS aliases for existing intrinsics
agutowski created this revision. agutowski added reviewers: rnk, thakis, compnerd, majnemer. agutowski added a subscriber: cfe-commits. https://reviews.llvm.org/D24330 Files: include/clang/Basic/Builtins.def include/clang/Basic/BuiltinsX86.def lib/AST/ExprConstant.cpp lib/CodeGen/CGBuiltin.cpp lib/Headers/emmintrin.h lib/Headers/ia32intrin.h lib/Headers/intrin.h lib/Headers/xmmintrin.h test/CodeGen/builtins-x86.c test/Sema/constant-builtins-2.c test/Sema/constant-builtins.c Index: lib/Headers/ia32intrin.h === --- lib/Headers/ia32intrin.h +++ lib/Headers/ia32intrin.h @@ -60,12 +60,6 @@ return __builtin_ia32_rdpmc(__A); } -/* __rdtsc */ -static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) -__rdtsc(void) { - return __builtin_ia32_rdtsc(); -} - /* __rdtscp */ static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) __rdtscp(unsigned int *__A) { Index: lib/Headers/emmintrin.h === --- lib/Headers/emmintrin.h +++ lib/Headers/emmintrin.h @@ -2447,52 +2447,6 @@ } #endif -/// \brief The cache line containing __p is flushed and invalidated from all -///caches in the coherency domain. -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c CLFLUSH instruction. -/// -/// \param __p -///A pointer to the memory location used to identify the cache line to be -///flushed. -static __inline__ void __DEFAULT_FN_ATTRS -_mm_clflush(void const *__p) -{ - __builtin_ia32_clflush(__p); -} - -/// \brief Forces strong memory ordering (serialization) between load -///instructions preceding this instruction and load instructions following -///this instruction, ensuring the system completes all previous loads before -///executing subsequent loads. -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c LFENCE instruction. -/// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_lfence(void) -{ - __builtin_ia32_lfence(); -} - -/// \brief Forces strong memory ordering (serialization) between load and store -///instructions preceding this instruction and load and store instructions -///following this instruction, ensuring that the system completes all -///previous memory accesses before executing subsequent memory accesses. -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c MFENCE instruction. -/// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_mfence(void) -{ - __builtin_ia32_mfence(); -} - /// \brief Converts 16-bit signed integers from both 128-bit integer vector ///operands into 8-bit signed integers, and packs the results into the ///destination. Positive values greater than 0x7F are saturated to 0x7F. @@ -3206,19 +3160,6 @@ return (__m128d)__a; } -/// \brief Indicates that a spin loop is being executed for the purposes of -///optimizing power consumption during the loop. -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c PAUSE instruction. -/// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_pause(void) -{ - __builtin_ia32_pause(); -} - #undef __DEFAULT_FN_ATTRS #define _MM_SHUFFLE2(x, y) (((x) << 1) | (y)) Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -518,14 +518,6 @@ *_Index = 31 - __builtin_clzl(_Mask); return 1; } -static __inline__ unsigned short __DEFAULT_FN_ATTRS -__popcnt16(unsigned short _Value) { - return __builtin_popcount((int)_Value); -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -__popcnt(unsigned int _Value) { - return __builtin_popcount(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest(long const *_BitBase, long _BitPos) { return (*_BitBase >> _BitPos) & 1; @@ -568,11 +560,6 @@ *_Index = 63 - __builtin_clzll(_Mask); return 1; } -static __inline__ -unsigned __int64 __DEFAULT_FN_ATTRS -__popcnt64(unsigned __int64 _Value) { - return __builtin_popcountll(_Value); -} static __inline__ unsigned char __DEFAULT_FN_ATTRS _bittest64(__int64 const *_BitBase, __int64 _BitPos) { return (*_BitBase >> _BitPos) & 1; Index: lib/Headers/xmmintrin.h === --- lib/Headers/xmmintrin.h +++ lib/Headers/xmmintrin.h @@ -2085,21 +2085,6 @@ __builtin_nontemporal_store((__v4sf)__a, (__v4sf*)__p); } -/// \brief Forces strong memory ordering (serialization) between store -///instructions preceding this instruction and store instructions following -///this instruction, ensuring the system completes all previous stores -///before executing subsequent stores. -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c SFENCE instruction. -/// -static __inline__ void __DEFAULT_FN_ATTRS -_mm_sfence(void) -{ - __builtin_ia32_sfence(); -} - /// \brief
Re: [PATCH] D24311: Implement MS _rot intrinsics
agutowski marked 2 inline comments as done. agutowski added a comment. In https://reviews.llvm.org/D24311#536333, @rnk wrote: > You should locally verify that this generates the correct assembly when > optimizations are enabled, and if it doesn't, try to make the input look more > like llvm/test/CodeGen/X86/rotate.ll Yeah, I checked that it's optimized to ROL/ROR instruction - now, after looking closer, I can see that it's optimized for all functions except for the ones operating on 16-bit integers. Could that be a calculated decision, or should I try to make it generate ROL/ROR whenever it can? Comment at: lib/CodeGen/CGBuiltin.cpp:740 @@ +739,3 @@ +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift = Builder.CreateAnd(Shift, Mask); +Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift); Ah, I am sure I saw that bug, but apparently I forgot about it, as on my machine it returned correct values. Thanks! https://reviews.llvm.org/D24311 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D24311: Implement MS _rot intrinsics
agutowski updated this revision to Diff 70614. agutowski added a comment. Fix undefined value problem when rotating by zero bits Change tests to work without -Oz flag Fix types of arguments in tests https://reviews.llvm.org/D24311 Files: include/clang/Basic/Builtins.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics-rotations.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -447,61 +447,6 @@ return (unsigned __int64)__in1 * (unsigned __int64)__in2; } /**\ -|* Bit Twiddling -\**/ -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_rotl8(unsigned char _Value, unsigned char _Shift) { - _Shift &= 0x7; - return _Shift ? (_Value << _Shift) | (_Value >> (8 - _Shift)) : _Value; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_rotr8(unsigned char _Value, unsigned char _Shift) { - _Shift &= 0x7; - return _Shift ? (_Value >> _Shift) | (_Value << (8 - _Shift)) : _Value; -} -static __inline__ unsigned short __DEFAULT_FN_ATTRS -_rotl16(unsigned short _Value, unsigned char _Shift) { - _Shift &= 0xf; - return _Shift ? (_Value << _Shift) | (_Value >> (16 - _Shift)) : _Value; -} -static __inline__ unsigned short __DEFAULT_FN_ATTRS -_rotr16(unsigned short _Value, unsigned char _Shift) { - _Shift &= 0xf; - return _Shift ? (_Value >> _Shift) | (_Value << (16 - _Shift)) : _Value; -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_rotl(unsigned int _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value; -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_rotr(unsigned int _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value; -} -static __inline__ unsigned long __DEFAULT_FN_ATTRS -_lrotl(unsigned long _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value; -} -static __inline__ unsigned long __DEFAULT_FN_ATTRS -_lrotr(unsigned long _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value; -} -static -__inline__ unsigned __int64 __DEFAULT_FN_ATTRS -_rotl64(unsigned __int64 _Value, int _Shift) { - _Shift &= 0x3f; - return _Shift ? (_Value << _Shift) | (_Value >> (64 - _Shift)) : _Value; -} -static -__inline__ unsigned __int64 __DEFAULT_FN_ATTRS -_rotr64(unsigned __int64 _Value, int _Shift) { - _Shift &= 0x3f; - return _Shift ? (_Value >> _Shift) | (_Value << (64 - _Shift)) : _Value; -} -/**\ |* Bit Counting and Testing \**/ static __inline__ unsigned char __DEFAULT_FN_ATTRS Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -696,6 +696,58 @@ "cast"); return RValue::get(Result); } + case Builtin::BI_rotr8: + case Builtin::BI_rotr16: + case Builtin::BI_rotr: + case Builtin::BI_lrotr: + case Builtin::BI_rotr64: { +Value *Val = EmitScalarExpr(E->getArg(0)); +Value *Shift = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = Val->getType(); +Shift = Builder.CreateIntCast(Shift, ArgType, false); +unsigned ArgWidth = cast(ArgType)->getBitWidth(); +Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); +Value *ArgZero = llvm::Constant::getNullValue(ArgType); + +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift = Builder.CreateAnd(Shift, Mask); +Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift); + +Value *RightShifted = Builder.CreateLShr(Val, Shift); +Value *LeftShifted = Builder.CreateShl(Val, LeftShift); +Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); + +Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); +Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); +return RValue::get(Result); + } + case Builtin::BI_rotl8: + case Builtin::BI_rotl16: + case Builtin::BI_rotl: + case Builtin::BI_lrotl: + case Builtin::BI_rotl64: { +Value *Val = EmitScalarExpr(E->getArg(0)); +Value *Shift = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = Val->getType(); +Shift = Builder.CreateIntCast(Shift, ArgType, false); +unsigned ArgWidth = cast(ArgType)->getBitWidth(); +Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); +Value *ArgZero = llvm::Constant::getNullValue(ArgType); + +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift = Builder.CreateAnd(Shift, Mask); +Value
[PATCH] D24311: Implement MS _rot intrinsics
agutowski created this revision. agutowski added reviewers: rnk, thakis, Prazek, compnerd. agutowski added a subscriber: cfe-commits. https://reviews.llvm.org/D24311 Files: include/clang/Basic/Builtins.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics-rotations.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -447,61 +447,6 @@ return (unsigned __int64)__in1 * (unsigned __int64)__in2; } /**\ -|* Bit Twiddling -\**/ -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_rotl8(unsigned char _Value, unsigned char _Shift) { - _Shift &= 0x7; - return _Shift ? (_Value << _Shift) | (_Value >> (8 - _Shift)) : _Value; -} -static __inline__ unsigned char __DEFAULT_FN_ATTRS -_rotr8(unsigned char _Value, unsigned char _Shift) { - _Shift &= 0x7; - return _Shift ? (_Value >> _Shift) | (_Value << (8 - _Shift)) : _Value; -} -static __inline__ unsigned short __DEFAULT_FN_ATTRS -_rotl16(unsigned short _Value, unsigned char _Shift) { - _Shift &= 0xf; - return _Shift ? (_Value << _Shift) | (_Value >> (16 - _Shift)) : _Value; -} -static __inline__ unsigned short __DEFAULT_FN_ATTRS -_rotr16(unsigned short _Value, unsigned char _Shift) { - _Shift &= 0xf; - return _Shift ? (_Value >> _Shift) | (_Value << (16 - _Shift)) : _Value; -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_rotl(unsigned int _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value; -} -static __inline__ unsigned int __DEFAULT_FN_ATTRS -_rotr(unsigned int _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value; -} -static __inline__ unsigned long __DEFAULT_FN_ATTRS -_lrotl(unsigned long _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value; -} -static __inline__ unsigned long __DEFAULT_FN_ATTRS -_lrotr(unsigned long _Value, int _Shift) { - _Shift &= 0x1f; - return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value; -} -static -__inline__ unsigned __int64 __DEFAULT_FN_ATTRS -_rotl64(unsigned __int64 _Value, int _Shift) { - _Shift &= 0x3f; - return _Shift ? (_Value << _Shift) | (_Value >> (64 - _Shift)) : _Value; -} -static -__inline__ unsigned __int64 __DEFAULT_FN_ATTRS -_rotr64(unsigned __int64 _Value, int _Shift) { - _Shift &= 0x3f; - return _Shift ? (_Value >> _Shift) | (_Value << (64 - _Shift)) : _Value; -} -/**\ |* Bit Counting and Testing \**/ static __inline__ unsigned char __DEFAULT_FN_ATTRS Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -696,6 +696,52 @@ "cast"); return RValue::get(Result); } + case Builtin::BI_rotr8: + case Builtin::BI_rotr16: + case Builtin::BI_rotr: + case Builtin::BI_lrotr: + case Builtin::BI_rotr64: { +Value *Val = EmitScalarExpr(E->getArg(0)); +Value *Shift = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = Val->getType(); +Shift = Builder.CreateIntCast(Shift, ArgType, false); +unsigned ArgWidth = cast(ArgType)->getBitWidth(); +Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); + +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift = Builder.CreateAnd(Shift, Mask); +Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift); + +Value *RightShifted = Builder.CreateLShr(Val, Shift); +Value *LeftShifted = Builder.CreateShl(Val, LeftShift); +Value *Shifted = Builder.CreateOr(LeftShifted, RightShifted); + +return RValue::get(Shifted); + } + case Builtin::BI_rotl8: + case Builtin::BI_rotl16: + case Builtin::BI_rotl: + case Builtin::BI_lrotl: + case Builtin::BI_rotl64: { +Value *Val = EmitScalarExpr(E->getArg(0)); +Value *Shift = EmitScalarExpr(E->getArg(1)); + +llvm::Type *ArgType = Val->getType(); +Shift = Builder.CreateIntCast(Shift, ArgType, false); +unsigned ArgWidth = cast(ArgType)->getBitWidth(); +Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); + +Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); +Shift = Builder.CreateAnd(Shift, Mask); +Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift); + +Value *LeftShifted = Builder.CreateShl(Val, Shift); +Value *RightShifted = Builder.CreateLShr(Val, RightShift); +Value *Shifted = Builder.CreateOr(LeftShifted, RightShifted); + +return RValue::get(Shifted); + } case
Re: [PATCH] D24153: Add bunch of _Interlocked builtins
agutowski marked an inline comment as done. agutowski added a comment. https://reviews.llvm.org/D24153 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D24153: Add bunch of _Interlocked builtins
agutowski updated this revision to Diff 70572. agutowski added a comment. Mark _InterlockedIncrement and _InterlockedDecrement as non-volatile https://reviews.llvm.org/D24153 Files: include/clang/Basic/Builtins.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c test/CodeGen/pr27892.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -602,177 +602,6 @@ } #endif /**\ -|* Interlocked Exchange Add -\**/ -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd8(char volatile *_Addend, char _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd16(short volatile *_Addend, short _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); -} -#endif -/**\ -|* Interlocked Exchange Sub -\**/ -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedExchangeSub8(char volatile *_Subend, char _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedExchangeSub16(short volatile *_Subend, short _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -} -static __inline__ long __DEFAULT_FN_ATTRS -_InterlockedExchangeSub(long volatile *_Subend, long _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -} -#endif -/**\ -|* Interlocked Increment -\**/ -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedIncrement16(short volatile *_Value) { - return __atomic_add_fetch(_Value, 1, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedIncrement64(__int64 volatile *_Value) { - return __atomic_add_fetch(_Value, 1, __ATOMIC_SEQ_CST); -} -#endif -/**\ -|* Interlocked Decrement -\**/ -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedDecrement16(short volatile *_Value) { - return __atomic_sub_fetch(_Value, 1, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedDecrement64(__int64 volatile *_Value) { - return __atomic_sub_fetch(_Value, 1, __ATOMIC_SEQ_CST); -} -#endif -/**\ -|* Interlocked And -\**/ -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedAnd8(char volatile *_Value, char _Mask) { - return __atomic_fetch_and(_Value, _Mask, __ATOMIC_SEQ_CST); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedAnd16(short volatile *_Value, short _Mask) { - return __atomic_fetch_and(_Value, _Mask, __ATOMIC_SEQ_CST); -} -static __inline__ long __DEFAULT_FN_ATTRS -_InterlockedAnd(long volatile *_Value, long _Mask) { - return __atomic_fetch_and(_Value, _Mask, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask) { - return __atomic_fetch_and(_Value, _Mask, __ATOMIC_SEQ_CST); -} -#endif -/**\ -|* Interlocked Or -\**/ -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedOr8(char volatile *_Value, char _Mask) { - return __atomic_fetch_or(_Value, _Mask, __ATOMIC_SEQ_CST); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedOr16(short volatile *_Value, short _Mask) { - return __atomic_fetch_or(_Value, _Mask, __ATOMIC_SEQ_CST); -} -static __inline__ long __DEFAULT_FN_ATTRS -_InterlockedOr(long volatile *_Value, long _Mask) { - return __atomic_fetch_or(_Value, _Mask, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedOr64(__int64 volatile *_Value, __int64 _Mask) { - return __atomic_fetch_or(_Value, _Mask,
[PATCH] D24153: Add bunch of _Interlocked builtins
agutowski created this revision. agutowski added reviewers: rnk, compnerd, thakis. agutowski added a subscriber: cfe-commits. https://reviews.llvm.org/D24153 Files: include/clang/Basic/Builtins.def lib/CodeGen/CGBuiltin.cpp lib/Headers/intrin.h test/CodeGen/ms-intrinsics.c Index: lib/Headers/intrin.h === --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -602,177 +602,6 @@ } #endif /**\ -|* Interlocked Exchange Add -\**/ -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd8(char volatile *_Addend, char _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd16(short volatile *_Addend, short _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); -} -#endif -/**\ -|* Interlocked Exchange Sub -\**/ -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedExchangeSub8(char volatile *_Subend, char _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedExchangeSub16(short volatile *_Subend, short _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -} -static __inline__ long __DEFAULT_FN_ATTRS -_InterlockedExchangeSub(long volatile *_Subend, long _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value) { - return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); -} -#endif -/**\ -|* Interlocked Increment -\**/ -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedIncrement16(short volatile *_Value) { - return __atomic_add_fetch(_Value, 1, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedIncrement64(__int64 volatile *_Value) { - return __atomic_add_fetch(_Value, 1, __ATOMIC_SEQ_CST); -} -#endif -/**\ -|* Interlocked Decrement -\**/ -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedDecrement16(short volatile *_Value) { - return __atomic_sub_fetch(_Value, 1, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedDecrement64(__int64 volatile *_Value) { - return __atomic_sub_fetch(_Value, 1, __ATOMIC_SEQ_CST); -} -#endif -/**\ -|* Interlocked And -\**/ -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedAnd8(char volatile *_Value, char _Mask) { - return __atomic_fetch_and(_Value, _Mask, __ATOMIC_SEQ_CST); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedAnd16(short volatile *_Value, short _Mask) { - return __atomic_fetch_and(_Value, _Mask, __ATOMIC_SEQ_CST); -} -static __inline__ long __DEFAULT_FN_ATTRS -_InterlockedAnd(long volatile *_Value, long _Mask) { - return __atomic_fetch_and(_Value, _Mask, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask) { - return __atomic_fetch_and(_Value, _Mask, __ATOMIC_SEQ_CST); -} -#endif -/**\ -|* Interlocked Or -\**/ -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedOr8(char volatile *_Value, char _Mask) { - return __atomic_fetch_or(_Value, _Mask, __ATOMIC_SEQ_CST); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedOr16(short volatile *_Value, short _Mask) { - return __atomic_fetch_or(_Value, _Mask, __ATOMIC_SEQ_CST); -} -static __inline__ long __DEFAULT_FN_ATTRS -_InterlockedOr(long volatile *_Value, long _Mask) { - return __atomic_fetch_or(_Value, _Mask, __ATOMIC_SEQ_CST); -} -#ifdef __x86_64__ -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedOr64(__int64 volatile *_Value, __int64 _Mask) { - return __atomic_fetch_or(_Value, _Mask, __ATOMIC_SEQ_CST); -} -#endif
Re: [PATCH] D23944: Parsing MS pragma intrinsic
agutowski marked an inline comment as done. agutowski added a comment. https://reviews.llvm.org/D23944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23944: Parsing MS pragma intrinsic
agutowski updated this revision to Diff 69768. agutowski added a comment. Fixed typo https://reviews.llvm.org/D23944 Files: include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/IdentifierTable.h include/clang/Parse/Parser.h lib/Parse/ParsePragma.cpp test/Preprocessor/pragma_microsoft.c Index: lib/Parse/ParsePragma.cpp === --- lib/Parse/ParsePragma.cpp +++ lib/Parse/ParsePragma.cpp @@ -161,6 +161,12 @@ PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {} }; +struct PragmaMSIntrinsicHandler : public PragmaHandler { + PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {} + void HandlePragma(Preprocessor , PragmaIntroducerKind Introducer, +Token ) override; +}; + } // end namespace void Parser::initializePragmaHandlers() { @@ -229,6 +235,8 @@ PP.AddPragmaHandler(MSSection.get()); MSRuntimeChecks.reset(new PragmaMSRuntimeChecksHandler()); PP.AddPragmaHandler(MSRuntimeChecks.get()); +MSIntrinsic.reset(new PragmaMSIntrinsicHandler()); +PP.AddPragmaHandler(MSIntrinsic.get()); } OptimizeHandler.reset(new PragmaOptimizeHandler(Actions)); @@ -297,6 +305,8 @@ MSSection.reset(); PP.RemovePragmaHandler(MSRuntimeChecks.get()); MSRuntimeChecks.reset(); +PP.RemovePragmaHandler(MSIntrinsic.get()); +MSIntrinsic.reset(); } PP.RemovePragmaHandler("STDC", FPContractHandler.get()); @@ -2127,3 +2137,53 @@ PP.EnterTokenStream(std::move(TokenArray), 1, /*DisableMacroExpansion=*/false); } + +/// \brief Handle the Microsoft \#pragma intrinsic extension. +/// +/// The syntax is: +/// \code +/// #pragma intrinsic(memset) +/// #pragma intrinsic(strlen, memcpy) +/// \endcode +/// +/// Pragma intrisic tells the compiler to use a builtin version of the +/// function. Clang does it anyway, so the pragma doesn't really do anything. +/// Anyway, we emit a warning if the function specified in \#pragma intrinsic +/// isn't an intrinsic in clang and suggest to include intrin.h. +void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor , +PragmaIntroducerKind Introducer, +Token ) { + PP.Lex(Tok); + + if (Tok.isNot(tok::l_paren)) { +PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) +<< "intrinsic"; +return; + } + PP.Lex(Tok); + + bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H"); + + while (Tok.is(tok::identifier)) { +IdentifierInfo *II = Tok.getIdentifierInfo(); +if (!II->getBuiltinID()) + PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin) + << II << SuggestIntrinH; + +PP.Lex(Tok); +if (Tok.isNot(tok::comma)) + break; +PP.Lex(Tok); + } + + if (Tok.isNot(tok::r_paren)) { +PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) +<< "intrinsic"; +return; + } + PP.Lex(Tok); + + if (Tok.isNot(tok::eod)) +PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) +<< "intrinsic"; +} Index: include/clang/Parse/Parser.h === --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -172,6 +172,7 @@ std::unique_ptr MSCodeSeg; std::unique_ptr MSSection; std::unique_ptr MSRuntimeChecks; + std::unique_ptr MSIntrinsic; std::unique_ptr OptimizeHandler; std::unique_ptr LoopHintHandler; std::unique_ptr UnrollHintHandler; Index: include/clang/Basic/IdentifierTable.h === --- include/clang/Basic/IdentifierTable.h +++ include/clang/Basic/IdentifierTable.h @@ -205,8 +205,7 @@ /// \brief Return a value indicating whether this is a builtin function. /// - /// 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. - /// 2+ are specific builtin functions. + /// 0 is not-built-in. 1+ are specific builtin functions. unsigned getBuiltinID() const { if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS) return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS; Index: include/clang/Basic/DiagnosticParseKinds.td === --- include/clang/Basic/DiagnosticParseKinds.td +++ include/clang/Basic/DiagnosticParseKinds.td @@ -911,6 +911,10 @@ def warn_pragma_pack_malformed : Warning< "expected integer or identifier in '#pragma pack' - ignored">, InGroup; +// - #pragma intrinsic +def warn_pragma_intrinsic_builtin : Warning< + "%0 is not a recognized builtin%select{|; consider including to access non-builtin intrinsics}1">, + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, Index: test/Preprocessor/pragma_microsoft.c === ---
Re: [PATCH] D23944: Parsing MS pragma intrinsic
agutowski updated this revision to Diff 69767. agutowski added a comment. Fixed checking if the function is an intrinsic. Updated getBuiltinID description. https://reviews.llvm.org/D23944 Files: include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/IdentifierTable.h include/clang/Parse/Parser.h lib/Parse/ParsePragma.cpp test/Preprocessor/pragma_microsoft.c Index: lib/Parse/ParsePragma.cpp === --- lib/Parse/ParsePragma.cpp +++ lib/Parse/ParsePragma.cpp @@ -161,6 +161,12 @@ PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {} }; +struct PragmaMSIntrinsicHandler : public PragmaHandler { + PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {} + void HandlePragma(Preprocessor , PragmaIntroducerKind Introducer, +Token ) override; +}; + } // end namespace void Parser::initializePragmaHandlers() { @@ -229,6 +235,8 @@ PP.AddPragmaHandler(MSSection.get()); MSRuntimeChecks.reset(new PragmaMSRuntimeChecksHandler()); PP.AddPragmaHandler(MSRuntimeChecks.get()); +MSIntrinsic.reset(new PragmaMSIntrinsicHandler()); +PP.AddPragmaHandler(MSIntrinsic.get()); } OptimizeHandler.reset(new PragmaOptimizeHandler(Actions)); @@ -297,6 +305,8 @@ MSSection.reset(); PP.RemovePragmaHandler(MSRuntimeChecks.get()); MSRuntimeChecks.reset(); +PP.RemovePragmaHandler(MSIntrinsic.get()); +MSIntrinsic.reset(); } PP.RemovePragmaHandler("STDC", FPContractHandler.get()); @@ -2127,3 +2137,53 @@ PP.EnterTokenStream(std::move(TokenArray), 1, /*DisableMacroExpansion=*/false); } + +/// \brief Handle the Microsoft \#pragma intrinsic extension. +/// +/// The syntax is: +/// \code +/// #pragma intrinsic(memset) +/// #pragma intrinsic(strlen, memcpy) +/// \endcode +/// +/// Pragma intrisic tells the compiler to use a builtin version of the +/// function. Clang does it anyway, so the pragma doesn't really do anything. +/// Anyway, we emit a warning if the function specified in \#pragma intrinsic +/// isn't an intrinsic in clang and suggest to include intrin.h. +void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor , +PragmaIntroducerKind Introducer, +Token ) { + PP.Lex(Tok); + + if (Tok.isNot(tok::l_paren)) { +PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) +<< "intrinsic"; +return; + } + PP.Lex(Tok); + + bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H"); + + while (Tok.is(tok::identifier)) { +IdentifierInfo *II = Tok.getIdentifierInfo(); +if (II->getBuiltinID()) + PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin) + << II << SuggestIntrinH; + +PP.Lex(Tok); +if (Tok.isNot(tok::comma)) + break; +PP.Lex(Tok); + } + + if (Tok.isNot(tok::r_paren)) { +PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) +<< "intrinsic"; +return; + } + PP.Lex(Tok); + + if (Tok.isNot(tok::eod)) +PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) +<< "intrinsic"; +} Index: include/clang/Parse/Parser.h === --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -172,6 +172,7 @@ std::unique_ptr MSCodeSeg; std::unique_ptr MSSection; std::unique_ptr MSRuntimeChecks; + std::unique_ptr MSIntrinsic; std::unique_ptr OptimizeHandler; std::unique_ptr LoopHintHandler; std::unique_ptr UnrollHintHandler; Index: include/clang/Basic/IdentifierTable.h === --- include/clang/Basic/IdentifierTable.h +++ include/clang/Basic/IdentifierTable.h @@ -205,8 +205,7 @@ /// \brief Return a value indicating whether this is a builtin function. /// - /// 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. - /// 2+ are specific builtin functions. + /// 0 is not-built-in. 1+ are specific builtin functions. unsigned getBuiltinID() const { if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS) return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS; Index: include/clang/Basic/DiagnosticParseKinds.td === --- include/clang/Basic/DiagnosticParseKinds.td +++ include/clang/Basic/DiagnosticParseKinds.td @@ -911,6 +911,10 @@ def warn_pragma_pack_malformed : Warning< "expected integer or identifier in '#pragma pack' - ignored">, InGroup; +// - #pragma intrinsic +def warn_pragma_intrinsic_builtin : Warning< + "%0 is not a recognized builtin%select{|; consider including to access non-builtin intrinsics}1">, + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, Index: test/Preprocessor/pragma_microsoft.c
Re: [PATCH] D23944: Parsing MS pragma intrinsic
agutowski marked 4 inline comments as done. agutowski added a comment. https://reviews.llvm.org/D23944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23944: Parsing MS pragma intrinsic
agutowski updated this revision to Diff 69632. agutowski added a comment. Changed warning template to use select, fixed some mistakes in the comments. https://reviews.llvm.org/D23944 Files: include/clang/Basic/DiagnosticParseKinds.td include/clang/Parse/Parser.h lib/Parse/ParsePragma.cpp test/Preprocessor/pragma_microsoft.c Index: lib/Parse/ParsePragma.cpp === --- lib/Parse/ParsePragma.cpp +++ lib/Parse/ParsePragma.cpp @@ -161,6 +161,12 @@ PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {} }; +struct PragmaMSIntrinsicHandler : public PragmaHandler { + PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {} + void HandlePragma(Preprocessor , PragmaIntroducerKind Introducer, +Token ) override; +}; + } // end namespace void Parser::initializePragmaHandlers() { @@ -229,6 +235,8 @@ PP.AddPragmaHandler(MSSection.get()); MSRuntimeChecks.reset(new PragmaMSRuntimeChecksHandler()); PP.AddPragmaHandler(MSRuntimeChecks.get()); +MSIntrinsic.reset(new PragmaMSIntrinsicHandler()); +PP.AddPragmaHandler(MSIntrinsic.get()); } OptimizeHandler.reset(new PragmaOptimizeHandler(Actions)); @@ -297,6 +305,8 @@ MSSection.reset(); PP.RemovePragmaHandler(MSRuntimeChecks.get()); MSRuntimeChecks.reset(); +PP.RemovePragmaHandler(MSIntrinsic.get()); +MSIntrinsic.reset(); } PP.RemovePragmaHandler("STDC", FPContractHandler.get()); @@ -2127,3 +2137,53 @@ PP.EnterTokenStream(std::move(TokenArray), 1, /*DisableMacroExpansion=*/false); } + +/// \brief Handle the Microsoft \#pragma intrinsic extension. +/// +/// The syntax is: +/// \code +/// #pragma intrinsic(memset) +/// #pragma intrinsic(strlen, memcpy) +/// \endcode +/// +/// Pragma intrisic tells the compiler to use a builtin version of the +/// function. Clang does it anyway, so the pragma doesn't really do anything. +/// Anyway, we emit a warning if the function specified in \#pragma intrinsic +/// isn't an intrinsic in clang and suggest to include intrin.h. +void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor , +PragmaIntroducerKind Introducer, +Token ) { + PP.Lex(Tok); + + if (Tok.isNot(tok::l_paren)) { +PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) +<< "intrinsic"; +return; + } + PP.Lex(Tok); + + bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H"); + + while (Tok.is(tok::identifier)) { +IdentifierInfo *II = Tok.getIdentifierInfo(); +if (II->getBuiltinID() < 2) + PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin) + << II << SuggestIntrinH; + +PP.Lex(Tok); +if (Tok.isNot(tok::comma)) + break; +PP.Lex(Tok); + } + + if (Tok.isNot(tok::r_paren)) { +PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) +<< "intrinsic"; +return; + } + PP.Lex(Tok); + + if (Tok.isNot(tok::eod)) +PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) +<< "intrinsic"; +} Index: include/clang/Parse/Parser.h === --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -172,6 +172,7 @@ std::unique_ptr MSCodeSeg; std::unique_ptr MSSection; std::unique_ptr MSRuntimeChecks; + std::unique_ptr MSIntrinsic; std::unique_ptr OptimizeHandler; std::unique_ptr LoopHintHandler; std::unique_ptr UnrollHintHandler; Index: include/clang/Basic/DiagnosticParseKinds.td === --- include/clang/Basic/DiagnosticParseKinds.td +++ include/clang/Basic/DiagnosticParseKinds.td @@ -911,6 +911,10 @@ def warn_pragma_pack_malformed : Warning< "expected integer or identifier in '#pragma pack' - ignored">, InGroup; +// - #pragma intrinsic +def warn_pragma_intrinsic_builtin : Warning< + "%0 is not a recognized builtin%select{|; consider including to access non-builtin intrinsics}1">, + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, Index: test/Preprocessor/pragma_microsoft.c === --- test/Preprocessor/pragma_microsoft.c +++ test/Preprocessor/pragma_microsoft.c @@ -162,3 +162,19 @@ // Test that runtime_checks is parsed but ignored. #pragma runtime_checks("sc", restore) // no-warning + +// Test pragma intrinsic +#pragma intrinsic(memset) // no-warning +#pragma intrinsic(memcpy, strlen, strlen) // no-warning +#pragma intrinsic() // no-warning +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} +#pragma intrinsic(main) // expected-warning {{'main' is not a recognized builtin; consider including }} +#pragma intrinsic( //
Re: [PATCH] D23944: Parsing MS pragma intrinsic
agutowski added inline comments. Comment at: lib/Parse/ParsePragma.cpp:2164 @@ +2163,3 @@ + + bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H"); + aaron.ballman wrote: > Is this safe to rely on? I'm not familiar with how we do our intrinsics, but > it's spelled `__INTRIN_H_` in MSVC 2015, but perhaps we only care about > intrin.h from Clang? I guess we only care about intrin.h from Clang - as far as I can see, MSVC's intrin.h contains only declarations, so including it won't change anything most of the time if the intrinsic isn't implemented in Clang. https://reviews.llvm.org/D23944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23944: Parsing MS pragma intrinsic
agutowski marked 2 inline comments as done. agutowski added a comment. https://reviews.llvm.org/D23944 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23944: Parsing MS pragma intrinsic
agutowski updated this revision to Diff 69605. agutowski added a comment. Changed warning messages https://reviews.llvm.org/D23944 Files: include/clang/Basic/DiagnosticParseKinds.td include/clang/Parse/Parser.h lib/Parse/ParsePragma.cpp test/Preprocessor/pragma_microsoft.c Index: lib/Parse/ParsePragma.cpp === --- lib/Parse/ParsePragma.cpp +++ lib/Parse/ParsePragma.cpp @@ -161,6 +161,12 @@ PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {} }; +struct PragmaMSIntrinsicHandler : public PragmaHandler { + PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {} + void HandlePragma(Preprocessor , PragmaIntroducerKind Introducer, +Token ) override; +}; + } // end namespace void Parser::initializePragmaHandlers() { @@ -229,6 +235,8 @@ PP.AddPragmaHandler(MSSection.get()); MSRuntimeChecks.reset(new PragmaMSRuntimeChecksHandler()); PP.AddPragmaHandler(MSRuntimeChecks.get()); +MSIntrinsic.reset(new PragmaMSIntrinsicHandler()); +PP.AddPragmaHandler(MSIntrinsic.get()); } OptimizeHandler.reset(new PragmaOptimizeHandler(Actions)); @@ -297,6 +305,8 @@ MSSection.reset(); PP.RemovePragmaHandler(MSRuntimeChecks.get()); MSRuntimeChecks.reset(); +PP.RemovePragmaHandler(MSIntrinsic.get()); +MSIntrinsic.reset(); } PP.RemovePragmaHandler("STDC", FPContractHandler.get()); @@ -2127,3 +2137,57 @@ PP.EnterTokenStream(std::move(TokenArray), 1, /*DisableMacroExpansion=*/false); } + +/// \brief Handle the Microsoft \#pragma intrinsic extension. +/// The syntax is: +/// \code +/// #pragma intrinsic(memset) +/// #pragma intrinsic(strlen, memcpy) +/// \endcode +/// +/// Pragma intrisic tells compiler to use a builtin version of function. +/// Clang does it anyway, so the pragma doesn't really do anything. +/// Anyway, we emit a warning if the function specified in pragma intrinsic +/// isn't an intrinsic in clang and suggest to include intrin.h. +void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor , +PragmaIntroducerKind Introducer, +Token ) { + PP.Lex(Tok); + + if (Tok.isNot(tok::l_paren)) { +PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) +<< "intrinsic"; +return; + } + PP.Lex(Tok); + + bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H"); + + while (Tok.is(tok::identifier)) { +IdentifierInfo *II = Tok.getIdentifierInfo(); +if (II->getBuiltinID() < 2) { + if (SuggestIntrinH) { +PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin_suggest) +<< II; + } else { +PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin) << II; + } +} + +PP.Lex(Tok); +if (Tok.isNot(tok::comma)) + break; +PP.Lex(Tok); + } + + if (Tok.isNot(tok::r_paren)) { +PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) +<< "intrinsic"; +return; + } + PP.Lex(Tok); + + if (Tok.isNot(tok::eod)) +PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) +<< "intrinsic"; +} Index: include/clang/Parse/Parser.h === --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -172,6 +172,7 @@ std::unique_ptr MSCodeSeg; std::unique_ptr MSSection; std::unique_ptr MSRuntimeChecks; + std::unique_ptr MSIntrinsic; std::unique_ptr OptimizeHandler; std::unique_ptr LoopHintHandler; std::unique_ptr UnrollHintHandler; Index: include/clang/Basic/DiagnosticParseKinds.td === --- include/clang/Basic/DiagnosticParseKinds.td +++ include/clang/Basic/DiagnosticParseKinds.td @@ -911,6 +911,13 @@ def warn_pragma_pack_malformed : Warning< "expected integer or identifier in '#pragma pack' - ignored">, InGroup; +// - #pragma intrinsic +def warn_pragma_intrinsic_builtin : Warning< + "%0 is not a recognized builtin">, + InGroup; +def warn_pragma_intrinsic_builtin_suggest : Warning< + "%0 is not a recognized builtin; consider including to access non-builtin intrinsics">, + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, Index: test/Preprocessor/pragma_microsoft.c === --- test/Preprocessor/pragma_microsoft.c +++ test/Preprocessor/pragma_microsoft.c @@ -162,3 +162,19 @@ // Test that runtime_checks is parsed but ignored. #pragma runtime_checks("sc", restore) // no-warning + +// Test pragma intrinsic +#pragma intrinsic(memset) // no-warning +#pragma intrinsic(memcpy, strlen, strlen) // no-warning +#pragma intrinsic() // no-warning +#pragma intrinsic(asdf) // expected-warning {{'asdf' is not a