forked from OSchip/llvm-project
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 llvm-svn: 284253
This commit is contained in:
parent
c39f8b0a3a
commit
1deab38717
|
@ -2041,6 +2041,8 @@ TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "
|
|||
|
||||
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
|
||||
|
|
|
@ -7770,6 +7770,11 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1024,11 +1024,6 @@ __movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) {
|
|||
: "%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");
|
||||
|
|
|
@ -14,6 +14,22 @@ typedef __SIZE_TYPE__ size_t;
|
|||
|
||||
#include <intrin.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue