From c3e787d9850d9eca6252e089510ccd656580cc95 Mon Sep 17 00:00:00 2001 From: Mark Rose Date: Fri, 23 Oct 2026 09:08:54 -0600 Subject: [PATCH 1/3] CI: build the Windows ASan job in native SIMD mode, and drop -s m from the macOS ASan job In the NOSIMD builds the medium self-test took about half of each job: 70 of 150 minutes on Windows and 45 of 95 on macOS. Windows now builds the runner's SIMD mode under the sanitizers, as the Linux ASan job does since #263, and keeps -s m. On macOS the SIMD asm does not assemble under -Og, so that job stays NOSIMD and its ladder stops at 's', as in the TSan jobs. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 981d5ac6d..a76408bf4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -473,8 +473,8 @@ jobs: run: | set -x -o pipefail # Build the runner's native SIMD mode under the sanitizers: AVX2 or AVX-512 on x86, - # depending on the runner, and ASIMD on ARM. This is the only job that builds the - # hand-tuned SIMD asm under a sanitizer. Issue #12, a SEGV in radix48_dit_pass1 during + # depending on the runner, and ASIMD on ARM. This and the Windows ASan job are the only ones + # that build the hand-tuned SIMD asm under a sanitizer. Issue #12, a SEGV in radix48_dit_pass1 during # 'Mlucas -s m', was reported by ASan on an ARM runner. (The macOS ASan job stays on # NOSIMD, see PR #71: there the SIMD asm fails to assemble under -Og, "invalid CFI # advance_loc expression".) @@ -783,7 +783,9 @@ jobs: (cd obj_mfac${word:+_$word}_nosimd; make clean) done cd obj_nosimd - for s in tt t s m; do time ./Mlucas -s $s -cpu "0:$(( $(sysctl -n hw.ncpu) - 1 ))" 2>&1 | tee -a test.log; done + # Ladder stops at 's', as in the TSan jobs: in this NOSIMD build '-s m' took about 45 of the job's + # 95 minutes, and the Linux and Windows ASan jobs run it in their SIMD builds. + for s in tt t s; do time ./Mlucas -s $s -cpu "0:$(( $(sysctl -n hw.ncpu) - 1 ))" 2>&1 | tee -a test.log; done for s in tt t s; do time ./Mlucas -prp -s $s -cpu "0:$(( $(sysctl -n hw.ncpu) - 1 ))" 2>&1 | tee -a test.log; done bash -e -o pipefail -- ../config-fermat.sh -cpu "0:$(( $(sysctl -n hw.ncpu) - 1 ))" for word in '' {{1..4},n}word; do @@ -1047,14 +1049,16 @@ jobs: shell: bash run: | set -x - bash -e -o pipefail -- makemake.sh use_hwloc nosimd - (cd obj_nosimd; make clean) + # Build the runner's native SIMD mode (AVX2 or AVX-512) under the sanitizers, as the Linux ASan + # job does: in the NOSIMD build '-s m' took about 70 of the job's 150 minutes. + bash -e -o pipefail -- makemake.sh use_hwloc + (cd obj; make clean) for word in '' {{1..4},n}word; do echo -e "\nMfactor $word\n" bash -e -o pipefail -- makemake.sh mfac $word nosimd (cd obj_mfac${word:+_$word}_nosimd; make clean) done - cd obj_nosimd + cd obj for s in tt t s m; do time ./Mlucas -s $s -cpu "0:$(( NUMBER_OF_PROCESSORS - 1 ))" |& tee -a test.log; done for s in tt t s; do time ./Mlucas -prp -s $s -cpu "0:$(( NUMBER_OF_PROCESSORS - 1 ))" |& tee -a test.log; done bash -e -o pipefail -- ../config-fermat.sh -cpu "0:$(( NUMBER_OF_PROCESSORS - 1 ))" From e2df33863f6a6765414481e62127f332d13106c3 Mon Sep 17 00:00:00 2001 From: Mark Rose Date: Mon, 26 Oct 2026 16:34:50 -0600 Subject: [PATCH 2/3] CI: build Mfactor in the native SIMD mode in the Linux and Windows ASan jobs The Linux x86 and Windows ASan jobs now build Mlucas in the runner's native SIMD mode, but still built every Mfactor word width NOSIMD. Build those in the native mode too. On ARM the Linux ASan job keeps Mfactor on NOSIMD, as the main Linux job does, because the ASIMD build's trial-factoring routines are stubs. The macOS ASan job is unchanged: its runner is ARM, so NOSIMD is still the only build whose Mfactor self-tests anything. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a76408bf4..4668ccaf7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -486,10 +486,12 @@ jobs: bash -e -o pipefail -- makemake.sh use_hwloc nosimd (cd obj_nosimd; make clean) fi + # Mfactor builds the native SIMD mode too, except on ARM, where it builds NOSIMD for the same reason. + if [[ $HOSTTYPE == aarch64 ]]; then mode=nosimd; else mode=; fi for word in '' {{1..4},n}word; do echo -e "\nMfactor $word\n" - bash -e -o pipefail -- makemake.sh mfac $word nosimd - (cd obj_mfac${word:+_$word}_nosimd; make clean) + bash -e -o pipefail -- makemake.sh mfac $word $mode + (cd obj_mfac${word:+_$word}${mode:+_$mode}; make clean) done cd obj for s in tt t s m; do time ./Mlucas -s $s -cpu "0:$(( $(nproc --all) - 1 ))" |& tee -a test.log; done @@ -499,7 +501,7 @@ jobs: fi bash -e -o pipefail -- ../config-fermat.sh -cpu "0:$(( $(nproc --all) - 1 ))" for word in '' {{1..4},n}word; do - (cd "../obj_mfac${word:+_$word}_nosimd" && time "./Mfactor${word:+_$word}" -m 521 -bmax 20) + (cd "../obj_mfac${word:+_$word}${mode:+_$mode}" && time "./Mfactor${word:+_$word}" -m 521 -bmax 20) done - uses: actions/upload-artifact@v7 if: always() @@ -1049,21 +1051,21 @@ jobs: shell: bash run: | set -x - # Build the runner's native SIMD mode (AVX2 or AVX-512) under the sanitizers, as the Linux ASan - # job does: in the NOSIMD build '-s m' took about 70 of the job's 150 minutes. + # Build the runner's native SIMD mode (AVX2 or AVX-512) under the sanitizers, for both Mlucas and + # Mfactor, as the Linux ASan job does: in the NOSIMD build '-s m' took about 70 of the job's 150 minutes. bash -e -o pipefail -- makemake.sh use_hwloc (cd obj; make clean) for word in '' {{1..4},n}word; do echo -e "\nMfactor $word\n" - bash -e -o pipefail -- makemake.sh mfac $word nosimd - (cd obj_mfac${word:+_$word}_nosimd; make clean) + bash -e -o pipefail -- makemake.sh mfac $word + (cd obj_mfac${word:+_$word}; make clean) done cd obj for s in tt t s m; do time ./Mlucas -s $s -cpu "0:$(( NUMBER_OF_PROCESSORS - 1 ))" |& tee -a test.log; done for s in tt t s; do time ./Mlucas -prp -s $s -cpu "0:$(( NUMBER_OF_PROCESSORS - 1 ))" |& tee -a test.log; done bash -e -o pipefail -- ../config-fermat.sh -cpu "0:$(( NUMBER_OF_PROCESSORS - 1 ))" for word in '' {{1..4},n}word; do - (cd "../obj_mfac${word:+_$word}_nosimd" && time "./Mfactor${word:+_$word}" -m 521 -bmax 20) + (cd "../obj_mfac${word:+_$word}" && time "./Mfactor${word:+_$word}" -m 521 -bmax 20) done - uses: actions/upload-artifact@v7 if: always() From 990a0dfe83b8631b1cc924c7a7c832f69267560a Mon Sep 17 00:00:00 2001 From: Mark Rose Date: Mon, 26 Oct 2026 17:32:42 -0600 Subject: [PATCH 3/3] Mfactor: free psmall, the AVX-512 sieve's per-thread prime table Mfactor's AVX-512 build allocates psmall for the vectorised bit-clearing and never frees it, so LeakSanitizer fails every word width with a 400000-byte leak from factor.c:1534 (NUM_SIEVING_PRIME x 4 bytes per thread). The ASan jobs only ever ran NOSIMD Mfactor builds, where psmall doesn't exist, so it went unseen; now that the Linux ASan job builds Mfactor in the runner's native mode, it would fail on every AVX-512 runner. Co-Authored-By: Claude Opus 5.5 --- src/factor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/factor.c b/src/factor.c index b90fcc27f..6c572ad02 100755 --- a/src/factor.c +++ b/src/factor.c @@ -2548,6 +2548,9 @@ candidate factors that survive sieving. */ free((void *)q); free((void *)q2); free((void *)u64_arr); + #if defined(USE_AVX512) && !defined(USE_IMCI512) + free((void *)psmall); + #endif #ifdef MULTITHREAD free((void *)tdat); tdat = 0x0; #endif