diff --git a/Misc/NEWS.d/next/Build/2026-03-18-00-00-00.gh-issue-138114.PwrVec.rst b/Misc/NEWS.d/next/Build/2026-03-18-00-00-00.gh-issue-138114.PwrVec.rst new file mode 100644 index 00000000000000..9d5929b6a3b4af --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-03-18-00-00-00.gh-issue-138114.PwrVec.rst @@ -0,0 +1,3 @@ +Enable HACL* BLAKE2s SIMD128 vectorization on PowerPC64 (POWER8+) using +AltiVec/VSX instructions. The HACL* library already contained a complete +PowerPC64 vec128 implementation but CPython's configure never enabled it. diff --git a/Modules/_hacl/ppc_altivec_fix.h b/Modules/_hacl/ppc_altivec_fix.h new file mode 100644 index 00000000000000..1283e96b6edf94 --- /dev/null +++ b/Modules/_hacl/ppc_altivec_fix.h @@ -0,0 +1,32 @@ +/* + * PowerPC AltiVec bool keyword fix for HACL* BLAKE2 SIMD128. + * + * When GCC compiles with -maltivec, it makes "bool" a keyword meaning + * "__vector __bool int" (a 128-bit vector type). This conflicts with + * C99/C11 stdbool.h where bool means _Bool (a scalar type). + * + * The -Dbool=_Bool workaround does NOT work because altivec.h re-enables + * the keyword after the macro is defined. Instead, this header includes + * altivec.h first, then undefines the bool/true/false keywords and + * restores the C99 scalar definitions. Vector boolean types remain + * accessible via the explicit __vector __bool syntax. + * + * This header is force-included (-include) before HACL SIMD128 sources + * via LIBHACL_SIMD128_FLAGS in configure.ac. + */ +#ifndef PPC_ALTIVEC_BOOL_FIX_H +#define PPC_ALTIVEC_BOOL_FIX_H + +#if defined(__ALTIVEC__) || defined(__VSX__) +#include + +#undef bool +#undef true +#undef false + +#define bool _Bool +#define true 1 +#define false 0 +#endif /* __ALTIVEC__ || __VSX__ */ + +#endif /* PPC_ALTIVEC_BOOL_FIX_H */ diff --git a/configure b/configure index 23f24d51c79e1a..2cba3b1f91c1dd 100755 --- a/configure +++ b/configure @@ -32918,9 +32918,63 @@ printf "%s\n" "standard" >&6; } fi +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -maltivec -mvsx" >&5 +printf %s "checking whether C compiler accepts -maltivec -mvsx... " >&6; } +if test ${ax_cv_check_cflags__Werror__maltivec__mvsx+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror -maltivec -mvsx" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags__Werror__maltivec__mvsx=yes +else case e in #( + e) ax_cv_check_cflags__Werror__maltivec__mvsx=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__maltivec__mvsx" >&5 +printf "%s\n" "$ax_cv_check_cflags__Werror__maltivec__mvsx" >&6; } +if test "x$ax_cv_check_cflags__Werror__maltivec__mvsx" = xyes +then : + + LIBHACL_SIMD128_FLAGS="-maltivec -mvsx -flax-vector-conversions -Wno-return-type -include \$(srcdir)/Modules/_hacl/ppc_altivec_fix.h" + + +printf "%s\n" "#define _Py_HACL_CAN_COMPILE_VEC128 1" >>confdefs.h + + + LIBHACL_BLAKE2_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128.o" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for HACL* SIMD128 implementation" >&5 +printf %s "checking for HACL* SIMD128 implementation... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: PowerPC AltiVec/VSX" >&5 +printf "%s\n" "PowerPC AltiVec/VSX" >&6; } + else case e in #( e) : ;; esac +fi + + ;; +esac fi fi diff --git a/configure.ac b/configure.ac index 635fce3f2e6fad..9d7f649133c1a3 100644 --- a/configure.ac +++ b/configure.ac @@ -8110,7 +8110,7 @@ fi if test "$ac_sys_system" != "Linux-android" -a "$ac_sys_system" != "WASI" || \ { test -n "$ANDROID_API_LEVEL" && test "$ANDROID_API_LEVEL" -ge 28; } then - dnl This can be extended here to detect e.g. Power8, which HACL* should also support. + dnl Check for x86 SSE support (SIMD128) AX_CHECK_COMPILE_FLAG([-msse -msse2 -msse3 -msse4.1 -msse4.2],[ [LIBHACL_SIMD128_FLAGS="-msse -msse2 -msse3 -msse4.1 -msse4.2"] @@ -8129,7 +8129,20 @@ then AC_MSG_RESULT([standard]) fi - ], [], [-Werror]) + ], [ + dnl x86 SSE not available; check for PowerPC AltiVec/VSX (Power8+). + dnl HACL* libintvector.h has a complete vec128 implementation for __powerpc64__. + AX_CHECK_COMPILE_FLAG([-maltivec -mvsx],[ + [LIBHACL_SIMD128_FLAGS="-maltivec -mvsx -flax-vector-conversions -Wno-return-type -include \$(srcdir)/Modules/_hacl/ppc_altivec_fix.h"] + + AC_DEFINE([_Py_HACL_CAN_COMPILE_VEC128], [1], [ + HACL* library can compile SIMD128 implementations]) + + [LIBHACL_BLAKE2_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128.o"] + AC_MSG_CHECKING([for HACL* SIMD128 implementation]) + AC_MSG_RESULT([PowerPC AltiVec/VSX]) + ], [], [-Werror]) + ], [-Werror]) fi AC_SUBST([LIBHACL_SIMD128_FLAGS]) AC_SUBST([LIBHACL_BLAKE2_SIMD128_OBJS])