[clang] 91bc85b - [MS] Preserve base register %esi around movs[bwl]

via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 23 01:28:55 PDT 2021


Author: namazso
Date: 2021-07-23T16:28:32+08:00
New Revision: 91bc85b1ebaaa4e61058c24b556d6f0569a9b091

URL: https://github.com/llvm/llvm-project/commit/91bc85b1ebaaa4e61058c24b556d6f0569a9b091
DIFF: https://github.com/llvm/llvm-project/commit/91bc85b1ebaaa4e61058c24b556d6f0569a9b091.diff

LOG: [MS] Preserve base register %esi around movs[bwl]

fix for behavior reported in https://bugs.llvm.org/show_bug.cgi?id=51100 workaround for root cause https://bugs.llvm.org/show_bug.cgi?id=16830

similar to https://reviews.llvm.org/D101338

Reviewed By: craig.topper

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index 2b4e1b75e404b..ff8eb8fca2687 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -451,24 +451,47 @@ unsigned char _InterlockedCompareExchange128_rel(__int64 volatile *_Destination,
 static __inline__ void __DEFAULT_FN_ATTRS __movsb(unsigned char *__dst,
                                                   unsigned char const *__src,
                                                   size_t __n) {
-  __asm__ __volatile__("rep movsb" : "+D"(__dst), "+S"(__src), "+c"(__n)
-                       : : "memory");
+#if defined(__x86_64__)
+  __asm__ __volatile__("rep movsb"
+                       : "+D"(__dst), "+S"(__src), "+c"(__n)
+                       :
+                       : "memory");
+#else
+  __asm__ __volatile__("xchg %%esi, %1\nrep movsb\nxchg %%esi, %1"
+                       : "+D"(__dst), "+r"(__src), "+c"(__n)
+                       :
+                       : "memory");
+#endif
 }
 static __inline__ void __DEFAULT_FN_ATTRS __movsd(unsigned long *__dst,
                                                   unsigned long const *__src,
                                                   size_t __n) {
+#if defined(__x86_64__)
   __asm__ __volatile__("rep movsl"
                        : "+D"(__dst), "+S"(__src), "+c"(__n)
                        :
                        : "memory");
+#else
+  __asm__ __volatile__("xchg %%esi, %1\nrep movsl\nxchg %%esi, %1"
+                       : "+D"(__dst), "+r"(__src), "+c"(__n)
+                       :
+                       : "memory");
+#endif
 }
 static __inline__ void __DEFAULT_FN_ATTRS __movsw(unsigned short *__dst,
                                                   unsigned short const *__src,
                                                   size_t __n) {
+#if defined(__x86_64__)
   __asm__ __volatile__("rep movsw"
                        : "+D"(__dst), "+S"(__src), "+c"(__n)
                        :
                        : "memory");
+#else
+  __asm__ __volatile__("xchg %%esi, %1\nrep movsw\nxchg %%esi, %1"
+                       : "+D"(__dst), "+r"(__src), "+c"(__n)
+                       :
+                       : "memory");
+#endif
 }
 static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst,
                                                   unsigned long __x,

diff  --git a/clang/test/CodeGen/ms-intrinsics.c b/clang/test/CodeGen/ms-intrinsics.c
index 9f608158b1673..92bcc2cea2f63 100644
--- a/clang/test/CodeGen/ms-intrinsics.c
+++ b/clang/test/CodeGen/ms-intrinsics.c
@@ -36,7 +36,7 @@ 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:   tail call { i8*, i8*, i32 } asm sideeffect "xchg %esi, $1\0Arep movsb\0Axchg %esi, $1", "={di},=r,={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %Dest, i8* %Src, i32 %Count)
 // CHECK-I386:   ret void
 // CHECK-I386: }
 
@@ -62,7 +62,7 @@ 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:   tail call { i16*, i16*, i32 } asm sideeffect "xchg %esi, $1\0Arep movsw\0Axchg %esi, $1", "={di},=r,={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i16* %Dest, i16* %Src, i32 %Count)
 // CHECK-I386:   ret void
 // CHECK-I386: }
 
@@ -88,7 +88,7 @@ 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:   tail call { i32*, i32*, i32 } asm sideeffect "xchg %esi, $1\0Arep movsl\0Axchg %esi, $1", "={di},=r,={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Dest, i32* %Src, i32 %Count)
 // CHECK-I386:   ret void
 // CHECK-I386: }
 


        


More information about the cfe-commits mailing list