diff options
| author | Craig Topper <craig.topper@intel.com> | 2018-06-21 18:56:30 +0000 |
|---|---|---|
| committer | Craig Topper <craig.topper@intel.com> | 2018-06-21 18:56:30 +0000 |
| commit | 1763dbb2780d808033bbbefb299d6a88d106557f (patch) | |
| tree | b4ce77c807691c557657062d5419fc78c6e4e42f /clang | |
| parent | 3505045b428410c736f79d612950c864e2d9d5a8 (diff) | |
| download | bcm5719-llvm-1763dbb2780d808033bbbefb299d6a88d106557f.tar.gz bcm5719-llvm-1763dbb2780d808033bbbefb299d6a88d106557f.zip | |
[X86] Correct the inline assembly implementations of __movsb/w/d/q and __stosw/d/q to mark registers/memory as modified
The inline assembly for these didn't mark that edi, esi, ecx are modified by movs/stos instruction. It also didn't mark that memory is modified.
This issue was reported to llvm-dev last year http://lists.llvm.org/pipermail/cfe-dev/2017-November/055863.html but no bug was ever filed.
Differential Revision: https://reviews.llvm.org/D48448
llvm-svn: 335270
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Headers/intrin.h | 21 | ||||
| -rw-r--r-- | clang/test/CodeGen/ms-intrinsics.c | 83 |
2 files changed, 97 insertions, 7 deletions
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index cf6e25a49ad..7dd70acc373 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -797,33 +797,40 @@ _InterlockedCompareExchange64_rel(__int64 volatile *_Destination, #if defined(__i386__) || defined(__x86_64__) static __inline__ void __DEFAULT_FN_ATTRS __movsb(unsigned char *__dst, unsigned char const *__src, size_t __n) { - __asm__("rep movsb" : : "D"(__dst), "S"(__src), "c"(__n)); + __asm__ __volatile__("rep movsb" : "+D"(__dst), "+S"(__src), "+c"(__n) + : : "memory"); } static __inline__ void __DEFAULT_FN_ATTRS __movsd(unsigned long *__dst, unsigned long const *__src, size_t __n) { - __asm__("rep movsl" : : "D"(__dst), "S"(__src), "c"(__n)); + __asm__ __volatile__("rep movsl" : "+D"(__dst), "+S"(__src), "+c"(__n) + : : "memory"); } static __inline__ void __DEFAULT_FN_ATTRS __movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) { - __asm__("rep movsw" : : "D"(__dst), "S"(__src), "c"(__n)); + __asm__ __volatile__("rep movsw" : "+D"(__dst), "+S"(__src), "+c"(__n) + : : "memory"); } 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)); + __asm__ __volatile__("rep stosl" : "+D"(__dst), "+c"(__n) : "a"(__x) + : "memory"); } static __inline__ void __DEFAULT_FN_ATTRS __stosw(unsigned short *__dst, unsigned short __x, size_t __n) { - __asm__("rep stosw" : : "D"(__dst), "a"(__x), "c"(__n)); + __asm__ __volatile__("rep stosw" : "+D"(__dst), "+c"(__n) : "a"(__x) + : "memory"); } #endif #ifdef __x86_64__ static __inline__ void __DEFAULT_FN_ATTRS __movsq(unsigned long long *__dst, unsigned long long const *__src, size_t __n) { - __asm__("rep movsq" : : "D"(__dst), "S"(__src), "c"(__n)); + __asm__ __volatile__("rep movsq" : "+D"(__dst), "+S"(__src), "+c"(__n) + : : "memory"); } static __inline__ void __DEFAULT_FN_ATTRS __stosq(unsigned __int64 *__dst, unsigned __int64 __x, size_t __n) { - __asm__("rep stosq" : : "D"(__dst), "a"(__x), "c"(__n)); + __asm__ __volatile__("rep stosq" : "+D"(__dst), "+c"(__n) : "a"(__x) + : "memory"); } #endif diff --git a/clang/test/CodeGen/ms-intrinsics.c b/clang/test/CodeGen/ms-intrinsics.c index a9902b2f219..2e85be89266 100644 --- a/clang/test/CodeGen/ms-intrinsics.c +++ b/clang/test/CodeGen/ms-intrinsics.c @@ -29,6 +29,89 @@ void test__stosb(unsigned char *Dest, unsigned char Data, size_t Count) { // CHECK-X64: ret void // CHECK-X64: } +void test__movsb(unsigned char *Dest, unsigned char *Src, size_t Count) { + return __movsb(Dest, Src, Count); +} +// CHECK-I386-LABEL: define{{.*}} void @test__movsb +// CHECK-I386: call { i8*, i8*, i32 } asm sideeffect "rep movsb", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %Dest, i8* %Src, i32 %Count) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64-LABEL: define{{.*}} void @test__movsb +// CHECK-X64: call { i8*, i8*, i64 } asm sideeffect "rep movsb", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %Dest, i8* %Src, i64 %Count) +// CHECK-X64: ret void +// CHECK-X64: } + +void test__stosw(unsigned short *Dest, unsigned short Data, size_t Count) { + return __stosw(Dest, Data, Count); +} +// CHECK-I386-LABEL: define{{.*}} void @test__stosw +// CHECK-I386: call { i16*, i32 } asm sideeffect "rep stosw", "={di},={cx},{ax},0,1,~{memory},~{dirflag},~{fpsr},~{flags}"(i16 %Data, i16* %Dest, i32 %Count) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64-LABEL: define{{.*}} void @test__stosw +// CHECK-X64: call { i16*, i64 } asm sideeffect "rep stosw", "={di},={cx},{ax},0,1,~{memory},~{dirflag},~{fpsr},~{flags}"(i16 %Data, i16* %Dest, i64 %Count) +// CHECK-X64: ret void +// CHECK-X64: } + +void test__movsw(unsigned short *Dest, unsigned short *Src, size_t Count) { + return __movsw(Dest, Src, Count); +} +// CHECK-I386-LABEL: define{{.*}} void @test__movsw +// CHECK-I386: call { i16*, i16*, i32 } asm sideeffect "rep movsw", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i16* %Dest, i16* %Src, i32 %Count) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64-LABEL: define{{.*}} void @test__movsw +// CHECK-X64: call { i16*, i16*, i64 } asm sideeffect "rep movsw", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i16* %Dest, i16* %Src, i64 %Count) +// CHECK-X64: ret void +// CHECK-X64: } + +void test__stosd(unsigned long *Dest, unsigned long Data, size_t Count) { + return __stosd(Dest, Data, Count); +} +// CHECK-I386-LABEL: define{{.*}} void @test__stosd +// CHECK-I386: call { i32*, i32 } asm sideeffect "rep stosl", "={di},={cx},{ax},0,1,~{memory},~{dirflag},~{fpsr},~{flags}"(i32 %Data, i32* %Dest, i32 %Count) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64-LABEL: define{{.*}} void @test__stosd +// CHECK-X64: call { i32*, i64 } asm sideeffect "rep stosl", "={di},={cx},{ax},0,1,~{memory},~{dirflag},~{fpsr},~{flags}"(i32 %Data, i32* %Dest, i64 %Count) +// CHECK-X64: ret void +// CHECK-X64: } + +void test__movsd(unsigned long *Dest, unsigned long *Src, size_t Count) { + return __movsd(Dest, Src, Count); +} +// CHECK-I386-LABEL: define{{.*}} void @test__movsd +// CHECK-I386: call { i32*, i32*, i32 } asm sideeffect "rep movsl", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Dest, i32* %Src, i32 %Count) +// CHECK-I386: ret void +// CHECK-I386: } + +// CHECK-X64-LABEL: define{{.*}} void @test__movsd +// CHECK-X64: call { i32*, i32*, i64 } asm sideeffect "rep movsl", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Dest, i32* %Src, i64 %Count) +// CHECK-X64: ret void +// CHECK-X64: } + +#ifdef __x86_64__ +void test__stosq(unsigned __int64 *Dest, unsigned __int64 Data, size_t Count) { + return __stosq(Dest, Data, Count); +} +// CHECK-X64-LABEL: define{{.*}} void @test__stosq +// CHECK-X64: call { i64*, i64 } asm sideeffect "rep stosq", "={di},={cx},{ax},0,1,~{memory},~{dirflag},~{fpsr},~{flags}"(i64 %Data, i64* %Dest, i64 %Count) +// CHECK-X64: ret void +// CHECK-X64: } + +void test__movsq(unsigned __int64 *Dest, unsigned __int64 *Src, size_t Count) { + return __movsq(Dest, Src, Count); +} +// CHECK-X64-LABEL: define{{.*}} void @test__movsq +// CHECK-X64: call { i64*, i64*, i64 } asm sideeffect "rep movsq", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %Dest, i64* %Src, i64 %Count) +// CHECK-X64: ret void +// CHECK-X64: } +#endif + void test__ud2(void) { __ud2(); } |

