From af60b0ec79e9c5d7116122b185e44927aca5aa07 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 1 Jan 2021 05:30:34 -0800 Subject: [PATCH] x86: Cast to unsigned short first for _mm_extract_pi16 _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 48384052544..f013f5c08fe 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 + +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 + +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 + +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 + +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 + +unsigned int foo16(__m64 x) { return _mm_extract_pi16(x, 3); } -- 2.30.2