E M 445b596238
fix: harden linux release builds against GCC's -march=native bug on Zen4
The linux-amd64 release build was intermittently failing with:

    'asm' operand has impossible constraints

in secp256k1's hand-written x86_64 assembly (scalar_4x64_impl.h,
USE_ASM_X86_64 path). Root cause, confirmed against upstream
(bitcoin-core/secp256k1#1623): on GCC 11 (Ubuntu 22.04's default),
-march=native's CPU autodetection misidentifies early AMD Zen4 chips
as znver3 while still enabling -mavx512f via CPUID feature probing.
-march=znver3 -mavx512f is an invalid combination matching no real
CPU -- GCC 11 predates Zen4 entirely -- and its register allocator
cannot satisfy the asm's constraints under it. Upstream confirmed
this is fixed by a GCC version that knows about znver4 (13+), and
closed the report as a GCC autodetection bug, not a secp256k1 defect.
This explains the apparent intermittency: it only reproduces on
whichever physical Zen4 host GitHub's runner fleet happens to assign
to a given job.

Two independent changes address this:

- Bump the linux-amd64 and linux-arm64 release builders from
  ubuntu-22.04(-arm) to ubuntu-24.04(-arm), kept on the same Ubuntu
  version across both architectures. Ubuntu 24.04 ships GCC 13 by
  default (GCC isn't installed separately in this workflow -- the
  runner image's preinstalled toolchain comes from its Ubuntu base),
  which correctly recognizes znver4 and produces a valid -march=native
  expansion.

- Also pass -d:disableMarchNative on the linux-amd64 build (matrix-
  scoped; arm64/macOS don't compile the affected x86_64 asm path).
  This is kept even after the GCC bump because -march=native is
  independently unsound for a publicly distributed binary: it bakes
  in whatever instruction set extensions the build runner's CPU
  happens to have (e.g. AVX-512) into the shipped binary, which would
  crash with an illegal instruction on end-user machines lacking that
  extension -- a separate, permanent concern from the GCC 11 bug.
2026-06-22 15:56:34 +02:00
..