Hi All,

The following patch has been bootstrapped and regtested on powerpc64le-linux
and powerpc64-linux.

The Power10 implementation of the SSE movemask intrinsics uses
vec_extractm(). On big-endian PowerPC, the vector element order
causes vec_extractm() to produce the mask bits in a different
order than required by the SSE movemask intrinsics.

Reverse the vector element order with vec_reve() on big-endian Power10
before calling vec_extractm(). This ensures that _mm_movemask_pd(),
_mm_movemask_ps(), and _mm_movemask_epi8() produce the same results on
both big and little endian targets.

2026-09-28  Jeevitha Palanisamy  <[email protected]>

gcc/
        PR target/127274
        * config/rs6000/emmintrin.h (_mm_movemask_pd): Reverse vector
        element order on big-endian Power10 before calling vec_extractm().
        (_mm_movemask_epi8): Likewise.
        * config/rs6000/xmmintrin.h (_mm_movemask_ps): Likewise.

diff --git a/gcc/config/rs6000/emmintrin.h b/gcc/config/rs6000/emmintrin.h
index 4d442d2e965..551be83617d 100644
--- a/gcc/config/rs6000/emmintrin.h
+++ b/gcc/config/rs6000/emmintrin.h
@@ -1234,6 +1234,9 @@ extern __inline int __attribute__((__gnu_inline__, 
__always_inline__, __artifici
 _mm_movemask_pd (__m128d  __A)
 {
 #ifdef _ARCH_PWR10
+#ifdef __BIG_ENDIAN__
+  __A = vec_reve (__A);
+#endif
   return vec_extractm ((__v2du) __A);
 #else
   __vector unsigned long long __result;
@@ -2031,6 +2034,9 @@ extern __inline int __attribute__((__gnu_inline__, 
__always_inline__, __artifici
 _mm_movemask_epi8 (__m128i __A)
 {
 #ifdef _ARCH_PWR10
+#ifdef __BIG_ENDIAN__
+  __A = (__m128i) vec_reve ((__v16qu) __A);
+#endif
   return vec_extractm ((__v16qu) __A);
 #else
   __vector unsigned long long __result;
diff --git a/gcc/config/rs6000/xmmintrin.h b/gcc/config/rs6000/xmmintrin.h
index bd5be193b44..d98d4b3570c 100644
--- a/gcc/config/rs6000/xmmintrin.h
+++ b/gcc/config/rs6000/xmmintrin.h
@@ -1353,6 +1353,9 @@ extern __inline int __attribute__((__gnu_inline__, 
__always_inline__, __artifici
 _mm_movemask_ps (__m128  __A)
 {
 #ifdef _ARCH_PWR10
+#ifdef __BIG_ENDIAN__
+  __A = vec_reve (__A);
+#endif
   return vec_extractm ((__vector unsigned int) __A);
 #else
   __vector unsigned long long __result;

Reply via email to