Uh oh!
There was an error while loading. Please reload this page.
deps: enable AVX-512 OpenSSL asm with clang - #65136
Conversation
nodejs-github-bot
commented
Aug 8, 2026
Review requested:
|
c8f1ee4 to
4faf749CompareThere was a problem hiding this comment.
Pull request overview
This PR updates OpenSSL build selection logic so clang builds can use the AVX-512-capable pre-generated OpenSSL assembly set, aligning performance-sensitive crypto paths with gcc builds and avoiding silent fallback to the AVX2-only asm set.
Changes:
- Extend the
deps/openssl/openssl.gypcondition that selectsopenssl_asm*.gypito also accept sufficiently newllvm_version(LLVM/clang integrated assembler). - Apply the same selection logic to both the main OpenSSL target and the FIPS module target.
Suppressed comments (1)
deps/openssl/openssl.gyp:119
- Same issue as above for the FIPS target:
llvm_versioncan bypass thenasm_versioncheck on Windows, but Windows still usesnasm.exeto assemble these files. This may incorrectly select the AVX-512 asm set when NASM is unavailable/too old.
}, 'gas_version and v(gas_version) >= v("2.26") or '
'nasm_version and v(nasm_version) >= v("2.11.8") or '
'llvm_version and v(llvm_version) >= v("8.0")', {
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| }, 'gas_version and v(gas_version) >= v("2.26") or ' | ||
| 'nasm_version and v(nasm_version) >= v("2.11.8")', { | ||
| 'nasm_version and v(nasm_version) >= v("2.11.8") or ' | ||
| 'llvm_version and v(llvm_version) >= v("8.0")', { |
There was a problem hiding this comment.
I expect that if llvm_version indicates a recent version, then nasm should be adequate to build the resulting objects. You'd have a misconfigured system otherwise.
nodejs-github-bot
commented
Aug 8, 2026
Node.js ships two pre-generated sets of OpenSSL assembly: `asm`, which contains the AVX-512 routines, and `asm_avx2`, which does not. The set is picked in deps/openssl/openssl.gyp based on `gas_version` or `nasm_version`, but configure.py only reports `gas_version` when the compiler is not clang, because clang uses its own integrated assembler and has no GNU assembler version to report. Consequently every clang build silently falls back to the AVX-512-less `asm_avx2` set, with no warning. The result is that `ossl_vaes_vpclmulqdq_capable()` is assembled as a stub that always returns 0, so OpenSSL never selects `ossl_aes_gcm_encrypt_avx512()` and uses the older AES-NI path instead. On an Intel Xeon Gold 6548N this costs roughly 1.6x on AES-256-GCM and 1.8x on both ChaCha20-Poly1305 and RSA-2048 signing. This is not limited to custom builds: BUILDING.md documents that the official linux-x64 binaries are produced with clang, and the shipped v25.x and v26.x binaries contain the stub. Accept `llvm_version` in the condition, the way deps/openssl/openssl.gypi already does for the AVX2 set. clang's integrated assembler has handled AVX512IFMA since 3.9 and VAES / VPCLMULQDQ since 6.0; 8.0 is used as a conservative floor, well below the clang 19.1 that Node.js already requires.
4faf749 to
322485dComparenodejs-github-bot
commented
Aug 11, 2026
nodejs-github-bot
commented
Aug 11, 2026
Uh oh!
There was an error while loading. Please reload this page.
nodejs-github-bot
commented
Aug 11, 2026
Landed in 175cd52 |
Node.js ships two pre-generated sets of OpenSSL assembly: `asm`, which contains the AVX-512 routines, and `asm_avx2`, which does not. The set is picked in deps/openssl/openssl.gyp based on `gas_version` or `nasm_version`, but configure.py only reports `gas_version` when the compiler is not clang, because clang uses its own integrated assembler and has no GNU assembler version to report. Consequently every clang build silently falls back to the AVX-512-less `asm_avx2` set, with no warning. The result is that `ossl_vaes_vpclmulqdq_capable()` is assembled as a stub that always returns 0, so OpenSSL never selects `ossl_aes_gcm_encrypt_avx512()` and uses the older AES-NI path instead. On an Intel Xeon Gold 6548N this costs roughly 1.6x on AES-256-GCM and 1.8x on both ChaCha20-Poly1305 and RSA-2048 signing. This is not limited to custom builds: BUILDING.md documents that the official linux-x64 binaries are produced with clang, and the shipped v25.x and v26.x binaries contain the stub. Accept `llvm_version` in the condition, the way deps/openssl/openssl.gypi already does for the AVX2 set. clang's integrated assembler has handled AVX512IFMA since 3.9 and VAES / VPCLMULQDQ since 6.0; 8.0 is used as a conservative floor, well below the clang 19.1 that Node.js already requires. PR-URL: #65136 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Node.js ships two pre-generated sets of OpenSSL assembly: `asm`, which contains the AVX-512 routines, and `asm_avx2`, which does not. The set is picked in deps/openssl/openssl.gyp based on `gas_version` or `nasm_version`, but configure.py only reports `gas_version` when the compiler is not clang, because clang uses its own integrated assembler and has no GNU assembler version to report. Consequently every clang build silently falls back to the AVX-512-less `asm_avx2` set, with no warning. The result is that `ossl_vaes_vpclmulqdq_capable()` is assembled as a stub that always returns 0, so OpenSSL never selects `ossl_aes_gcm_encrypt_avx512()` and uses the older AES-NI path instead. On an Intel Xeon Gold 6548N this costs roughly 1.6x on AES-256-GCM and 1.8x on both ChaCha20-Poly1305 and RSA-2048 signing. This is not limited to custom builds: BUILDING.md documents that the official linux-x64 binaries are produced with clang, and the shipped v25.x and v26.x binaries contain the stub. Accept `llvm_version` in the condition, the way deps/openssl/openssl.gypi already does for the AVX2 set. clang's integrated assembler has handled AVX512IFMA since 3.9 and VAES / VPCLMULQDQ since 6.0; 8.0 is used as a conservative floor, well below the clang 19.1 that Node.js already requires. PR-URL: #65136 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Node.js ships two pre-generated sets of OpenSSL assembly: `asm`, which contains the AVX-512 routines, and `asm_avx2`, which does not. The set is picked in deps/openssl/openssl.gyp based on `gas_version` or `nasm_version`, but configure.py only reports `gas_version` when the compiler is not clang, because clang uses its own integrated assembler and has no GNU assembler version to report. Consequently every clang build silently falls back to the AVX-512-less `asm_avx2` set, with no warning. The result is that `ossl_vaes_vpclmulqdq_capable()` is assembled as a stub that always returns 0, so OpenSSL never selects `ossl_aes_gcm_encrypt_avx512()` and uses the older AES-NI path instead. On an Intel Xeon Gold 6548N this costs roughly 1.6x on AES-256-GCM and 1.8x on both ChaCha20-Poly1305 and RSA-2048 signing. This is not limited to custom builds: BUILDING.md documents that the official linux-x64 binaries are produced with clang, and the shipped v25.x and v26.x binaries contain the stub. Accept `llvm_version` in the condition, the way deps/openssl/openssl.gypi already does for the AVX2 set. clang's integrated assembler has handled AVX512IFMA since 3.9 and VAES / VPCLMULQDQ since 6.0; 8.0 is used as a conservative floor, well below the clang 19.1 that Node.js already requires. PR-URL: #65136 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
I was trying to find out which compile was better for compiling Node.js : GCC or LLVM/clang. One of my benchmark showed that GCC was massively better. After investigating, I found that it was a configuration issue that disabled part of OpenSSL under AVX-512. Note that I am using Linux.
We don't need to worry about Apple Clang because AVX-512 on Apple systems is a narrow niche.
Node.js ships two pre-generated sets of OpenSSL assembly:
asm, which contains the AVX-512 routines, andasm_avx2, which does not. The set is picked in deps/openssl/openssl.gyp based ongas_versionornasm_version, but configure.py only reportsgas_versionwhen the compiler is not clang, because clang uses its own integrated assembler and has no GNU assembler version to report. Consequently every clang build silently falls back to the AVX-512-lessasm_avx2set, with no warning.The result is that
ossl_vaes_vpclmulqdq_capable()is assembled as a stub that always returns 0, so OpenSSL never selectsossl_aes_gcm_encrypt_avx512()and uses the older AES-NI path instead. On a Zen 5 machine this costs roughly 1.6x on AES-256-GCM, 1.7x on ChaCha20-Poly1305 and 1.8x on RSA-2048 signing.Accept
llvm_versionin the condition, the way deps/openssl/openssl.gypi already does for the AVX2 set. clang's integrated assembler has handled AVX512IFMA since 7.0 at least and VAES / VPCLMULQDQ since 7.0 at least; 8.0 is used as a conservative floor, well below the clang that Node.js is built with today.