diff mbox

Patch RFA: Move x86 _mm_pause out of pragma target("sse") scope

Message ID mcr1tvc7b0s.fsf@iant-glaptop.roam.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor May 29, 2014, 5:25 p.m. UTC
The _mm_pause intrinsic is defined in xmmintrin.h.  Right now using it
with -m32 with the default -march option gives an error:

/home/iant/foo.c: In function ‘f’:
/home/iant/gcc/go-install/lib/gcc/x86_64-unknown-linux-gnu/4.10.0/include/xmmintrin.h:1238:1: error: inlining failed in call to always_inline ‘_mm_pause’: target specific option mismatch
 _mm_pause (void)
 ^
/home/iant/foo5.c:3:13: error: called from here
 void f () { _mm_pause (); }
             ^

This error is because _mm_pause is defined in the scope of #pragma GCC
target("sse").  But _mm_pause, which simply generates the pause
instruction, does not require SSE support.  The pause instruction has
nothing really to do with SSE, and it works on all x86 processors (on
processors that do not explicitly recognize it, it is a nop).

I propose the following patch, which moves _mm_pause out of the pragma
target scope.

I know that x86intrin.h provides a similar intrinsic, __pause, but I
think it's worth making _mm_pause work reasonably as well.

I'm running a full testsuite run.  OK for mainline if it passes?

Ian


gcc/ChangeLog:

2014-05-29  Ian Lance Taylor  <iant@google.com>

	* config/i386/xmmintrin.h (_mm_pause): Move out of scope of pragma
	target("sse").

gcc/testsuite/ChangeLog:

2014-05-29  Ian Lance Taylor  <iant@google.com>

	* gcc.target/i386/pause-2.c: New test.
diff mbox

Patch

Index: config/i386/xmmintrin.h
===================================================================
--- config/i386/xmmintrin.h	(revision 211057)
+++ config/i386/xmmintrin.h	(working copy)
@@ -1231,15 +1231,6 @@  _mm_sfence (void)
   __builtin_ia32_sfence ();
 }
 
-/* The execution of the next instruction is delayed by an implementation
-   specific amount of time.  The instruction does not modify the
-   architectural state.  */
-extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm_pause (void)
-{
-  __builtin_ia32_pause ();
-}
-
 /* Transpose the 4x4 matrix composed of row[0-3].  */
 #define _MM_TRANSPOSE4_PS(row0, row1, row2, row3)			\
 do {									\
@@ -1262,4 +1253,15 @@  do {									\
 #pragma GCC pop_options
 #endif /* __DISABLE_SSE__ */
 
+/* The execution of the next instruction is delayed by an implementation
+   specific amount of time.  The instruction does not modify the
+   architectural state.  This is after the pop_options pragma because
+   it does not require SSE support in the processor--the encoding is a
+   nop on processors that do not support it.  */
+extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_pause (void)
+{
+  __builtin_ia32_pause ();
+}
+
 #endif /* _XMMINTRIN_H_INCLUDED */
Index: testsuite/gcc.target/i386/pause-2.c
===================================================================
--- testsuite/gcc.target/i386/pause-2.c	(revision 0)
+++ testsuite/gcc.target/i386/pause-2.c	(revision 0)
@@ -0,0 +1,12 @@ 
+/* Test that pause instruction works even when SSE is not enabled.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -dp" } */
+/* { dg-final { scan-assembler-times "\\*pause" 1 } } */
+
+#include <xmmintrin.h>
+
+void
+foo (void)
+{
+  _mm_pause ();
+}