Commit da2fa6d621 for openssl.org
commit da2fa6d621a6edbcd1a88d823813a5f11102a4df
Author: Milan Broz <gmazyland@gmail.com>
Date: Tue Apr 28 22:21:14 2026 +0200
Do not compile AVX2 code if AVX2 intrinsics is not supported
Old and exotic compilers do not support AVX2 instrinsic.
Add guard for Clang, GCC >= 8 and MSVC >= 2019.
Fixes: #30958
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Thu Apr 30 11:44:32 2026
(Merged from https://github.com/openssl/openssl/pull/31020)
diff --git a/crypto/evp/enc_b64_avx2.c b/crypto/evp/enc_b64_avx2.c
index 5a3d6d921d..dafa834a48 100644
--- a/crypto/evp/enc_b64_avx2.c
+++ b/crypto/evp/enc_b64_avx2.c
@@ -7,6 +7,7 @@
#if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
#if !defined(_M_ARM64EC)
+#if defined(HAVE_AVX2_INTRINSICS)
#define STRINGIFY_IMPLEMENTATION_(a) #a
#define STRINGIFY(a) STRINGIFY_IMPLEMENTATION_(a)
@@ -668,5 +669,6 @@ size_t encode_base64_avx2(EVP_ENCODE_CTX *ctx, unsigned char *dst,
return (size_t)(out - (uint8_t *)dst) + evp_encodeblock_int(ctx, out, src + i, srclen - i, final_wrap_cnt);
}
OPENSSL_UNTARGET_AVX2
+#endif /* defined(HAVE_AVX2_INTRINSICS) */
#endif /* !defined(_M_ARM64EC) */
#endif
diff --git a/crypto/evp/enc_b64_avx2.h b/crypto/evp/enc_b64_avx2.h
index 89dba6285d..71b0a004e7 100644
--- a/crypto/evp/enc_b64_avx2.h
+++ b/crypto/evp/enc_b64_avx2.h
@@ -4,11 +4,21 @@
#include <openssl/evp.h>
#include <stddef.h>
+#if defined(__clang__)
+#define HAVE_AVX2_INTRINSICS 1
+#elif defined(__GNUC__) && (__GNUC__ >= 8)
+#define HAVE_AVX2_INTRINSICS 1
+#elif defined(_MSC_VER) && (_MSC_VER >= 1920) /* MSVC 2019 */
+#define HAVE_AVX2_INTRINSICS 1
+#endif
+
#if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
#if !defined(_M_ARM64EC)
+#if defined(HAVE_AVX2_INTRINSICS)
size_t encode_base64_avx2(EVP_ENCODE_CTX *ctx,
unsigned char *out, const unsigned char *src, int srclen,
int newlines, int *wrap_cnt);
+#endif /* defined(HAVE_AVX2_INTRINSICS) */
#endif /* !defined(_M_ARM64EC) */
#endif
diff --git a/crypto/evp/encode.c b/crypto/evp/encode.c
index 4f2c412c3c..4686e0d910 100644
--- a/crypto/evp/encode.c
+++ b/crypto/evp/encode.c
@@ -405,14 +405,14 @@ int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
j = evp_encodeblock_int(ctx, out, in, inl - (inl % EVP_ENCODE_B64_LENGTH),
&wrap_cnt);
} else {
-#if defined(__AVX2__)
+#if defined(__AVX2__) && defined(HAVE_AVX2_INTRINSICS)
const int newlines = !(ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) ? EVP_ENCODE_B64_LENGTH : 0;
j = encode_base64_avx2(ctx,
(unsigned char *)out,
(const unsigned char *)in,
inl - (inl % EVP_ENCODE_B64_LENGTH), newlines, &wrap_cnt);
-#elif defined(HAS_IA32CAP_IS_64)
+#elif defined(HAS_IA32CAP_IS_64) && defined(HAVE_AVX2_INTRINSICS)
if ((OPENSSL_ia32cap_P[2] & (1u << 5)) != 0) {
const int newlines = !(ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) ? EVP_ENCODE_B64_LENGTH : 0;
@@ -473,9 +473,9 @@ int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
{
int wrap_cnt = 0;
-#if defined(__AVX2__)
+#if defined(__AVX2__) && defined(HAVE_AVX2_INTRINSICS)
return (int)encode_base64_avx2(NULL, t, f, dlen, 0, &wrap_cnt);
-#elif defined(HAS_IA32CAP_IS_64)
+#elif defined(HAS_IA32CAP_IS_64) && defined(HAVE_AVX2_INTRINSICS)
if ((OPENSSL_ia32cap_P[2] & (1u << 5)) != 0)
return (int)encode_base64_avx2(NULL, t, f, dlen, 0, &wrap_cnt);
else