From 7edb8ee9adf17233206edf26826dba9477352bba Mon Sep 17 00:00:00 2001 From: Luther Monson Date: Thu, 9 Jul 2026 17:00:24 -0700 Subject: [PATCH] fix(build): re-enable x86 hardware intrinsics (SHA-NI, PCLMUL, AVX2) The spc fork env.ini places -fvisibility-inlines-hidden (C++-only) in PHP_MAKE_EXTRA_CFLAGS. GCC warns on every C compile, php-src's AX_GCC_FUNC_ATTRIBUTE macro treats any stderr as "unsupported", and HAVE_FUNC_ATTRIBUTE_TARGET/IFUNC come back undefined -- so every Linux SDK ever shipped had ALL x86 intrinsic resolvers compiled out: - SHA-NI sha256: measured 2.7x slower than FrankenPHP/docker builds (540ns vs 200ns per 64-byte digest) - PCLMUL crc32c: 2.2x slower - every ZEND_INTRIN_* resolver (SSSE3/SSE4.2/AVX2/AVX512 incl. base64) Verified via nm on shipped tarballs (no SHA256_Transform_shani symbol), an autoconf repro on the almalinux8/gcc-13 builder (236 bytes of stderr with the flag, 0 without), and an algo matrix where exactly the two algorithms with attribute-gated hardware paths run 2-3x slow while all others sit at ratio ~1.0. Upstream static-php-cli fixed the flag placement on main in May 2026; until the fork rebases onto that, override PHP_MAKE_EXTRA_CFLAGS via env (real env vars win over env.ini) with the identical value minus the one poison token, ${SPC_DEFAULT_CFLAGS} pre-expanded. Adds a hard guard after staging: x86_64 builds fail unless HAVE_FUNC_ATTRIBUTE_TARGET is defined in php_config.h AND SHA256_Transform_shani is present in libphp.a -- a soft-sha256 SDK can never ship silently again. --- .github/workflows/build.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 60693fd..75d3db0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -155,6 +155,22 @@ jobs: export SPC_TARGET="$(uname -m)-linux-gnu" fi + # Hardware-intrinsics fix: the spc fork env.ini puts + # -fvisibility-inlines-hidden (a C++-only flag) into + # PHP_MAKE_EXTRA_CFLAGS. GCC warns on every C compile, and + # php-src AX_GCC_FUNC_ATTRIBUTE treats ANY stderr as + # "attribute unsupported", so HAVE_FUNC_ATTRIBUTE_TARGET/IFUNC + # end up undefined and PHP silently skips ALL x86 intrinsic + # resolvers: SHA-NI sha256 (measured 2.7x slower than it + # should be), PCLMUL crc32c (2.2x), and every ZEND_INTRIN_* + # path (SSSE3/AVX2 base64 etc.). Upstream spc fixed the flag + # placement in May 2026; until the fork rebases onto that, + # override here -- env vars win over env.ini. Value = the fork + # env.ini line with the one C++-only token removed and + # ${SPC_DEFAULT_CFLAGS} pre-expanded (env-provided values skip + # the ini ${} interpolation, so it must be spelled out). + export SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fno-ident -fPIE -fvisibility=hidden -fPIC -O3 -pipe -fno-plt -fno-semantic-interposition -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections -Wno-unused-command-line-argument" + # Extract spc into a fresh temp dir and PATH it: on the ubuntu # image the runner storage/userns combo denied writes into # /usr/local/bin during extraction (run 28759904638) even though @@ -239,6 +255,18 @@ jobs: fi cp -RLf "$PHP_INC_DIR" /output/include/php + # Guard: prove the CFLAGS override above actually re-enabled + # the hardware intrinsics. Every Linux SDK before 2026-07 + # shipped with HAVE_FUNC_ATTRIBUTE_TARGET silently undefined + # (no SHA-NI sha256, no PCLMUL crc32, no AVX2 base64) and no + # check caught it. x86_64 only: PHP ext/hash has no aarch64 + # equivalent intrinsics. + if [ "$(uname -m)" = "x86_64" ]; then + grep -q "define HAVE_FUNC_ATTRIBUTE_TARGET 1" /output/include/php/main/php_config.h + nm /output/lib/libphp.a | grep -q "SHA256_Transform_shani" + echo "==> intrinsics guard passed: SHA-NI transform present in libphp.a" + fi + # Bundle the container libstdc++.a (musl-flavored on Alpine, # glibc-flavored on Ubuntu) so downstream consumers link # against the same C++ runtime spc used to compile libicu*,