From ef530ce7c61dc16387fb68d48aebfbbbfe02adbb Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Mon, 16 Sep 2024 12:23:05 +0800 Subject: [PATCH] gh-123748: Add conditional compilation rules for HACL SIMD256 and SIMD128 on macOS (#123989) Add conditional compilation rules to allow HACL SIMD256 and SIMD128 to be ignored on the ARM64 pass of universal2 macOS builds. --- Makefile.pre.in | 6 +++ Misc/sbom.spdx.json | 38 +++++++++++++++++++ .../Hacl_Hash_Blake2b_Simd256_universal2.c | 15 ++++++++ .../Hacl_Hash_Blake2s_Simd128_universal2.c | 14 +++++++ Modules/blake2module.c | 10 +++++ configure | 35 ++++++++++++++++- configure.ac | 29 +++++++++++++- 7 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.c create mode 100644 Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.c diff --git a/Makefile.pre.in b/Makefile.pre.in index 579b3fddabc..de4aed6cb10 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1387,9 +1387,15 @@ Modules/_hacl/Hacl_Hash_Blake2b.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b.c $ Modules/_hacl/Hacl_Hash_Blake2s_Simd128.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s_Simd128.c $(LIBHACL_BLAKE2_HEADERS) $(CC) -c $(LIBHACL_CFLAGS) $(LIBHACL_SIMD128_FLAGS) -DHACL_CAN_COMPILE_VEC128 -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s_Simd128.c +Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.c $(LIBHACL_BLAKE2_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) $(LIBHACL_SIMD128_FLAGS) -DHACL_CAN_COMPILE_VEC128 -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.c + Modules/_hacl/Hacl_Hash_Blake2b_Simd256.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b_Simd256.c $(LIBHACL_BLAKE2_HEADERS) $(CC) -c $(LIBHACL_CFLAGS) $(LIBHACL_SIMD256_FLAGS) -DHACL_CAN_COMPILE_VEC256 -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b_Simd256.c +Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.c $(LIBHACL_BLAKE2_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) $(LIBHACL_SIMD256_FLAGS) -DHACL_CAN_COMPILE_VEC256 -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.c + Modules/_hacl/Lib_Memzero0.o: $(srcdir)/Modules/_hacl/Lib_Memzero0.c $(LIBHACL_BLAKE2_HEADERS) $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Lib_Memzero0.c diff --git a/Misc/sbom.spdx.json b/Misc/sbom.spdx.json index 05647c1fe41..f07ad9423d9 100644 --- a/Misc/sbom.spdx.json +++ b/Misc/sbom.spdx.json @@ -351,6 +351,20 @@ ], "fileName": "Modules/_hacl/Hacl_Hash_Blake2b_Simd256.h" }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-Blake2b-Simd256-universal2.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "5afc433179d71abd6649596797a7e8953e89172d" + }, + { + "algorithm": "SHA256", + "checksumValue": "db42da82d18641d68d3670e6201e0cbb43415daaa84f29770b8f0ebf33562975" + } + ], + "fileName": "Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.c" + }, { "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-Blake2s.c", "checksums": [ @@ -407,6 +421,20 @@ ], "fileName": "Modules/_hacl/Hacl_Hash_Blake2s_Simd128.h" }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-Blake2s-Simd128-universal2.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d70c6dbcb91d56bbd80f7bf860e508a748042d0d" + }, + { + "algorithm": "SHA256", + "checksumValue": "5b132ab850a5e0fe6f27e08a955f8989ea3aae8e5b3115f0195039034ece8c04" + } + ], + "fileName": "Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.c" + }, { "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-MD5.c", "checksums": [ @@ -1800,6 +1828,11 @@ "relationshipType": "CONTAINS", "spdxElementId": "SPDXRef-PACKAGE-hacl-star" }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-Blake2b-Simd256-universal2.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, { "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-Blake2s.c", "relationshipType": "CONTAINS", @@ -1820,6 +1853,11 @@ "relationshipType": "CONTAINS", "spdxElementId": "SPDXRef-PACKAGE-hacl-star" }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-Blake2s-Simd128-universal2.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, { "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-MD5.c", "relationshipType": "CONTAINS", diff --git a/Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.c b/Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.c new file mode 100644 index 00000000000..116499fedb3 --- /dev/null +++ b/Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.c @@ -0,0 +1,15 @@ +// This file isn't part of a standard HACL source tree. +// +// It is required for compatibility with universal2 macOS builds. The code in +// Hacl_Hash_Blake2b_Simd256.c *will* compile on macOS x86_64, but *won't* +// compile on ARM64. However, because universal2 builds are compiled in a +// single pass, autoconf detects that the required compiler features *are* +// available, and tries to compile this file, which then fails because of the +// lack of support on ARM64. +// +// To compensate for this, autoconf will include *this* file instead of +// Hacl_Hash_Blake2b_Simd256.c when compiling for universal. This allows the +// underlying source code of HACL to remain unmodified. +#if !(defined(__APPLE__) && defined(__arm64__)) +#include "Hacl_Hash_Blake2b_Simd256.c" +#endif diff --git a/Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.c b/Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.c new file mode 100644 index 00000000000..951306db494 --- /dev/null +++ b/Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.c @@ -0,0 +1,14 @@ +// This file isn't part of a standard HACL source tree. +// +// It is required for compatibility with universal2 macOS builds. The code in +// Hacl_Hash_Blake2s_Simd128.c will compile on macOS ARM64, but performance +// isn't great, so it's disabled. However, because universal2 builds are +// compiled in a single pass, autoconf detects that the required compiler +// features *are* available, and tries to include this file. +// +// To compensate for this, autoconf will include *this* file instead of +// Hacl_Hash_Blake2s_Simd128.c when compiling for universal. This allows the +// underlying source code of HACL to remain unmodified. +#if !(defined(__APPLE__) && defined(__arm64__)) +#include "Hacl_Hash_Blake2s_Simd128.c" +#endif diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 56d1cedef44..1ec676c34c6 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -41,6 +41,16 @@ #include +// SIMD256 can't be compiled on macOS ARM64, and performance of SIMD128 isn't +// great; but when compiling a universal2 binary, autoconf will set +// HACL_CAN_COMPILE_SIMD128 and HACL_CAN_COMPILE_SIMD256 because they *can* be +// compiled on x86_64. If we're on macOS ARM64, disable these preprocessor +// symbols. +#if defined(__APPLE__) && defined(__arm64__) +# undef HACL_CAN_COMPILE_SIMD128 +# undef HACL_CAN_COMPILE_SIMD256 +#endif + // ECX #define ECX_SSE3 (1 << 0) #define ECX_SSSE3 (1 << 9) diff --git a/configure b/configure index 746c3b074d1..69301dec854 100755 --- a/configure +++ b/configure @@ -30521,11 +30521,27 @@ if test "x$ax_cv_check_cflags__Werror__msse__msse2__msse3__msse4_1__msse4_2" = x then : LIBHACL_SIMD128_FLAGS="-msse -msse2 -msse3 -msse4.1 -msse4.2" - LIBHACL_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128.o" + printf "%s\n" "#define HACL_CAN_COMPILE_SIMD128 1" >>confdefs.h + # macOS universal2 builds *support* the -msse etc flags because they're + # available on x86_64. However, performance of the HACL SIMD128 implementation + # isn't great, so it's disabled on ARM64. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for HACL* SIMD128 implementation" >&5 +printf %s "checking for HACL* SIMD128 implementation... " >&6; } + if test "$UNIVERSAL_ARCHS" == "universal2"; then + LIBHACL_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.o" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: universal2" >&5 +printf "%s\n" "universal2" >&6; } + else + LIBHACL_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128.o" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: standard" >&5 +printf "%s\n" "standard" >&6; } + fi + + else $as_nop : fi @@ -30569,11 +30585,26 @@ if test "x$ax_cv_check_cflags__Werror__mavx2" = xyes then : LIBHACL_SIMD256_FLAGS="-mavx2" - LIBHACL_SIMD256_OBJS="Modules/_hacl/Hacl_Hash_Blake2b_Simd256.o" printf "%s\n" "#define HACL_CAN_COMPILE_SIMD256 1" >>confdefs.h + # macOS universal2 builds *support* the -mavx2 compiler flag because it's + # available on x86_64; but the HACL SIMD256 build then fails because the + # implementation requires symbols that aren't available on ARM64. Use a + # wrapped implementation if we're building for universal2. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for HACL* SIMD256 implementation" >&5 +printf %s "checking for HACL* SIMD256 implementation... " >&6; } + if test "$UNIVERSAL_ARCHS" == "universal2"; then + LIBHACL_SIMD256_OBJS="Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.o" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: universal2" >&5 +printf "%s\n" "universal2" >&6; } + else + LIBHACL_SIMD256_OBJS="Modules/_hacl/Hacl_Hash_Blake2b_Simd256.o" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: standard" >&5 +printf "%s\n" "standard" >&6; } + fi + else $as_nop : fi diff --git a/configure.ac b/configure.ac index 9284350695c..ab39f46deeb 100644 --- a/configure.ac +++ b/configure.ac @@ -7805,8 +7805,21 @@ AC_SUBST([LIBHACL_CFLAGS]) dnl This can be extended here to detect e.g. Power8, which HACL* should also support. AX_CHECK_COMPILE_FLAG([-msse -msse2 -msse3 -msse4.1 -msse4.2],[ [LIBHACL_SIMD128_FLAGS="-msse -msse2 -msse3 -msse4.1 -msse4.2"] - [LIBHACL_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128.o"] + AC_DEFINE([HACL_CAN_COMPILE_SIMD128], [1], [HACL* library can compile SIMD128 implementations]) + + # macOS universal2 builds *support* the -msse etc flags because they're + # available on x86_64. However, performance of the HACL SIMD128 implementation + # isn't great, so it's disabled on ARM64. + AC_MSG_CHECKING([for HACL* SIMD128 implementation]) + if test "$UNIVERSAL_ARCHS" == "universal2"; then + [LIBHACL_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128_universal2.o"] + AC_MSG_RESULT([universal2]) + else + [LIBHACL_SIMD128_OBJS="Modules/_hacl/Hacl_Hash_Blake2s_Simd128.o"] + AC_MSG_RESULT([standard]) + fi + ], [], [-Werror]) AC_SUBST([LIBHACL_SIMD128_FLAGS]) @@ -7814,8 +7827,20 @@ AC_SUBST([LIBHACL_SIMD128_OBJS]) AX_CHECK_COMPILE_FLAG([-mavx2],[ [LIBHACL_SIMD256_FLAGS="-mavx2"] - [LIBHACL_SIMD256_OBJS="Modules/_hacl/Hacl_Hash_Blake2b_Simd256.o"] AC_DEFINE([HACL_CAN_COMPILE_SIMD256], [1], [HACL* library can compile SIMD256 implementations]) + + # macOS universal2 builds *support* the -mavx2 compiler flag because it's + # available on x86_64; but the HACL SIMD256 build then fails because the + # implementation requires symbols that aren't available on ARM64. Use a + # wrapped implementation if we're building for universal2. + AC_MSG_CHECKING([for HACL* SIMD256 implementation]) + if test "$UNIVERSAL_ARCHS" == "universal2"; then + [LIBHACL_SIMD256_OBJS="Modules/_hacl/Hacl_Hash_Blake2b_Simd256_universal2.o"] + AC_MSG_RESULT([universal2]) + else + [LIBHACL_SIMD256_OBJS="Modules/_hacl/Hacl_Hash_Blake2b_Simd256.o"] + AC_MSG_RESULT([standard]) + fi ], [], [-Werror]) AC_SUBST([LIBHACL_SIMD256_FLAGS])