_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