r335270 - [X86] Correct the inline assembly implementations of __movsb/w/d/q and __stosw/d/q to mark registers/memory as modified

Craig Topper via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 21 11:56:30 PDT 2018


Author: ctopper
Date: Thu Jun 21 11:56:30 2018
New Revision: 335270

URL: http://llvm.org/viewvc/llvm-project?rev=335270&view=rev
Log:
[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

Modified:
    cfe/trunk/lib/Headers/intrin.h
    cfe/trunk/test/CodeGen/ms-intrinsics.c

Modified: cfe/trunk/lib/Headers/intrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/intrin.h?rev=335270&r1=335269&r2=335270&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/intrin.h (original)
+++ cfe/trunk/lib/Headers/intrin.h Thu Jun 21 11:56:30 2018
@@ -797,33 +797,40 @@ _InterlockedCompareExchange64_rel(__int6
 #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
 

Modified: cfe/trunk/test/CodeGen/ms-intrinsics.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-intrinsics.c?rev=335270&r1=335269&r2=335270&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ms-intrinsics.c (original)
+++ cfe/trunk/test/CodeGen/ms-intrinsics.c Thu Jun 21 11:56:30 2018
@@ -29,6 +29,89 @@ void test__stosb(unsigned char *Dest, un
 // 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();
 }




More information about the cfe-commits mailing list