_mm_extract_pi16 is intrinsic for pextrw, which should be zero-extended,
not sign-extended.

gcc/

        PR target/98495
        * config/i386/xmmintrin.h (_mm_extract_pi16): Cast to unsigned
        short first.

gcc/testsuite/

        PR target/98495
        * gcc.target/i386/pr98495-1.c: New test.
        * gcc.target/i386/pr98495-2.c: New test.
        * gcc.target/i386/pr98495-3.c: New test.
        * gcc.target/i386/pr98495-4.c: New test.
        * gcc.target/i386/pr98495-5.c: New test.
---
 gcc/config/i386/xmmintrin.h               |  4 ++--
 gcc/testsuite/gcc.target/i386/pr98495-1.c | 10 ++++++++++
 gcc/testsuite/gcc.target/i386/pr98495-2.c | 11 +++++++++++
 gcc/testsuite/gcc.target/i386/pr98495-3.c |  8 ++++++++
 gcc/testsuite/gcc.target/i386/pr98495-4.c |  8 ++++++++
 gcc/testsuite/gcc.target/i386/pr98495-5.c |  9 +++++++++
 6 files changed, 48 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr98495-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr98495-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr98495-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr98495-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr98495-5.c

diff --git a/gcc/config/i386/xmmintrin.h b/gcc/config/i386/xmmintrin.h
index c6f1c012630..9e27717d0c7 100644
--- a/gcc/config/i386/xmmintrin.h
+++ b/gcc/config/i386/xmmintrin.h
@@ -1022,7 +1022,7 @@ _mm_move_ss (__m128 __A, __m128 __B)
 extern __inline int __attribute__((__gnu_inline__, __always_inline__, 
__artificial__))
 _mm_extract_pi16 (__m64 const __A, int const __N)
 {
-  return __builtin_ia32_vec_ext_v4hi ((__v4hi)__A, __N);
+  return (unsigned short) __builtin_ia32_vec_ext_v4hi ((__v4hi)__A, __N);
 }
 
 extern __inline int __attribute__((__gnu_inline__, __always_inline__, 
__artificial__))
@@ -1032,7 +1032,7 @@ _m_pextrw (__m64 const __A, int const __N)
 }
 #else
 #define _mm_extract_pi16(A, N) \
-  ((int) __builtin_ia32_vec_ext_v4hi ((__v4hi)(__m64)(A), (int)(N)))
+  ((int) (unsigned short) __builtin_ia32_vec_ext_v4hi ((__v4hi)(__m64)(A), 
(int)(N)))
 
 #define _m_pextrw(A, N) _mm_extract_pi16(A, N)
 #endif
diff --git a/gcc/testsuite/gcc.target/i386/pr98495-1.c 
b/gcc/testsuite/gcc.target/i386/pr98495-1.c
new file mode 100644
index 00000000000..df24e63d182
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98495-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mmmx -msse2 -mtune=generic" } */
+/* { dg-final { scan-assembler-not "movswl" } } */
+/* { dg-final { scan-assembler-not "movzwl" } } */
+/* { dg-final { scan-assembler-not "cwtl" } } */
+/* { dg-final { scan-assembler "pextrw" } } */
+
+#include <xmmintrin.h>
+
+unsigned int foo16(__m64 x) { return _mm_extract_pi16(x, 3); }
diff --git a/gcc/testsuite/gcc.target/i386/pr98495-2.c 
b/gcc/testsuite/gcc.target/i386/pr98495-2.c
new file mode 100644
index 00000000000..5fd001eefed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98495-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mmmx -msse2 -mtune=generic" } */
+/* { dg-final { scan-assembler-not "movswl" } } */
+/* { dg-final { scan-assembler-not "movzwl" } } */
+/* { dg-final { scan-assembler-not "cwtl" } } */
+/* { dg-final { scan-assembler-not "cltq" } } */
+/* { dg-final { scan-assembler "pextrw" } } */
+
+#include <xmmintrin.h>
+
+unsigned long long int foo16(__m64 x) { return _mm_extract_pi16(x, 3); }
diff --git a/gcc/testsuite/gcc.target/i386/pr98495-3.c 
b/gcc/testsuite/gcc.target/i386/pr98495-3.c
new file mode 100644
index 00000000000..458b470cbd1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98495-3.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mmmx -msse2 -mtune=generic" } */
+/* { dg-final { scan-assembler "(movswl|cwtl)" } } */
+/* { dg-final { scan-assembler "pextrw" } } */
+
+#include <xmmintrin.h>
+
+int foo16(__m64 x) { return (short) _mm_extract_pi16(x, 3); }
diff --git a/gcc/testsuite/gcc.target/i386/pr98495-4.c 
b/gcc/testsuite/gcc.target/i386/pr98495-4.c
new file mode 100644
index 00000000000..16d3cbadb03
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98495-4.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mmmx -msse2 -mtune=generic" } */
+/* { dg-final { scan-assembler "movswq" } } */
+/* { dg-final { scan-assembler "pextrw" } } */
+
+#include <xmmintrin.h>
+
+long long int foo16(__m64 x) { return (short) _mm_extract_pi16(x, 3); }
diff --git a/gcc/testsuite/gcc.target/i386/pr98495-5.c 
b/gcc/testsuite/gcc.target/i386/pr98495-5.c
new file mode 100644
index 00000000000..a62b42d8eb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98495-5.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -mmmx -msse2 -mtune=generic" } */
+/* { dg-final { scan-assembler-not "movswl" } } */
+/* { dg-final { scan-assembler-not "cwtl" } } */
+/* { dg-final { scan-assembler "pextrw" } } */
+
+#include <xmmintrin.h>
+
+unsigned int foo16(__m64 x) { return _mm_extract_pi16(x, 3); }
-- 
2.29.2

Reply via email to