]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Add volatiles for x86-64 bits/mathinline.h
authorAndreas Jaeger <jaegerandi@gmail.com>
Wed, 9 May 2012 18:17:21 +0000 (20:17 +0200)
committerAndreas Jaeger <jaegerandi@gmail.com>
Wed, 9 May 2012 18:17:21 +0000 (20:17 +0200)
[BZ #14053]
GCC 4.7 might remove consecutive calls to e.g. lrintf since
the assembler instructions are the same and GCC does not know
that the result is different depending on the rounding mode.  For
SSE instructions, the control register is not available so there
is no way to inform GCC about this. Therefore the asms are marked
as volatile.

ChangeLog
NEWS
sysdeps/x86_64/fpu/bits/mathinline.h

index 6d7243b27b5c47ad05ca78cb83fe17f4298bd6bd..a89b1919889df068bea192753c9aa0a60244d938 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2012-05-09  Andreas Jaeger  <aj@suse.de>
+
+        [BZ #14053]
+        * sysdeps/x86_64/fpu/bits/mathinline.h (lrintf): Add __volatile
+       to asm.
+        (lrint): Likewise.
+        (llrintf): Likewise.
+        (llrint): Likewise.
+        (rint): Likewise.
+        (rintf): Likewise.
+        (nearbyint): Likewise.
+        (nearbyintf): Likewise.
+
 2012-05-09  Andreas Jaeger  <aj@suse.de>
            Pedro Alves  <palves@redhat.com>
 
diff --git a/NEWS b/NEWS
index a10e8868a7afd33b63d234348bd14af6b9feedd9..2cf47c39219693dd97825716e3ab5bd0bafd2b21 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -24,7 +24,7 @@ Version 2.16
   13895, 13908, 13910, 13911, 13912, 13913, 13914, 13915, 13916, 13917,
   13918, 13919, 13920, 13921, 13922, 13923, 13924, 13926, 13927, 13928,
   13938, 13941, 13942, 13963, 13967, 13970, 13973, 13979, 13983, 14027,
-  14033, 14034, 14040, 14049, 14055, 14064, 14080, 14083
+  14033, 14034, 14040, 14049, 14053, 14055, 14064, 14080, 14083
 
 * ISO C11 support:
 
index c072f16a21e5465246e8628fdf3243e66cf5f727..49a199b60bf2b5a29d0ba4a17768e67f7bc74482 100644 (file)
@@ -79,7 +79,11 @@ __MATH_INLINE long int
 __NTH (lrintf (float __x))
 {
   long int __res;
-  __asm ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
+  /* Mark as volatile since the result is dependend on the state of
+     the SSE control register (the rounding mode). Otherwise GCC might
+     remove these assembler instructions since it does not know about
+     the rounding mode change and cannot currently be told.  */
+  __asm __volatile__ ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
   return __res;
 }
 #  endif
@@ -88,7 +92,11 @@ __MATH_INLINE long int
 __NTH (lrint (double __x))
 {
   long int __res;
-  __asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
+  /* Mark as volatile since the result is dependend on the state of
+     the SSE control register (the rounding mode). Otherwise GCC might
+     remove these assembler instructions since it does not know about
+     the rounding mode change and cannot currently be told.  */
+  __asm __volatile__ ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
   return __res;
 }
 #  endif
@@ -97,14 +105,22 @@ __MATH_INLINE long long int
 __NTH (llrintf (float __x))
 {
   long long int __res;
-  __asm ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
+  /* Mark as volatile since the result is dependend on the state of
+     the SSE control register (the rounding mode). Otherwise GCC might
+     remove these assembler instructions since it does not know about
+     the rounding mode change and cannot currently be told.  */
+  __asm __volatile__ ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
   return __res;
 }
 __MATH_INLINE long long int
 __NTH (llrint (double __x))
 {
   long long int __res;
-  __asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
+  /* Mark as volatile since the result is dependend on the state of
+     the SSE control register (the rounding mode). Otherwise GCC might
+     remove these assembler instructions since it does not know about
+     the rounding mode change and cannot currently be told.  */
+  __asm __volatile__ ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
   return __res;
 }
 #  endif
@@ -176,14 +192,22 @@ __MATH_INLINE double
 __NTH (rint (double __x))
 {
   double __res;
-  __asm ("roundsd $4, %1, %0" : "=x" (__res) : "xm" (__x));
+  /* Mark as volatile since the result is dependend on the state of
+     the SSE control register (the rounding mode). Otherwise GCC might
+     remove these assembler instructions since it does not know about
+     the rounding mode change and cannot currently be told.  */
+  __asm __volatile__ ("roundsd $4, %1, %0" : "=x" (__res) : "xm" (__x));
   return __res;
 }
 __MATH_INLINE float
 __NTH (rintf (float __x))
 {
   float __res;
-  __asm ("roundss $4, %1, %0" : "=x" (__res) : "xm" (__x));
+  /* Mark as volatile since the result is dependend on the state of
+     the SSE control register (the rounding mode). Otherwise GCC might
+     remove these assembler instructions since it does not know about
+     the rounding mode change and cannot currently be told.  */
+  __asm __volatile__ ("roundss $4, %1, %0" : "=x" (__res) : "xm" (__x));
   return __res;
 }
 
@@ -193,14 +217,22 @@ __MATH_INLINE double
 __NTH (nearbyint (double __x))
 {
   double __res;
-  __asm ("roundsd $0xc, %1, %0" : "=x" (__res) : "xm" (__x));
+  /* Mark as volatile since the result is dependend on the state of
+     the SSE control register (the rounding mode). Otherwise GCC might
+     remove these assembler instructions since it does not know about
+     the rounding mode change and cannot currently be told.  */
+  __asm __volatile__ ("roundsd $0xc, %1, %0" : "=x" (__res) : "xm" (__x));
   return __res;
 }
 __MATH_INLINE float
 __NTH (nearbyintf (float __x))
 {
   float __res;
-  __asm ("roundss $0xc, %1, %0" : "=x" (__res) : "xm" (__x));
+  /* Mark as volatile since the result is dependend on the state of
+     the SSE control register (the rounding mode). Otherwise GCC might
+     remove these assembler instructions since it does not know about
+     the rounding mode change and cannot currently be told.  */
+  __asm __volatile__ ("roundss $0xc, %1, %0" : "=x" (__res) : "xm" (__x));
   return __res;
 }
 #   endif