Segfault with gcc 15 and -O2
Describe the bug
The testsuite for fmpz_mpoly_factor fails when building on gcc 15 when compiling with optimization level -O2 or greater.
Steps to reproduce
$ make distclean && CFLAGS='-O2 -g' ./configure && make -j10 && make -j10 check MOD=fmpz_mpoly_factor
[...]
CC fmpz_mpoly_factor/test/main.c
fmpz_mpoly_factor_squarefree...
fmpz_mpoly_factor...
fmpz_mpoly_factor_gcd_brown...
fmpz_mpoly_factor_gcd_zippel...
fmpz_mpoly_factor_zassenhaus...
fmpz_poly_pfrac...
fmpz_mpoly_factor_gcd_subresultant...
fmpz_mpoly_factor_squarefree 0.02 (PASS)
fmpz_mpoly_factor_wang...
fmpz_mpoly_factor 0.04 (PASS)
fmpz_mpoly_factor_content...
fmpz_mpoly_factor_gcd_subresultant 0.05 (PASS)
fmpz_mpoly_factor_gcd_zippel2...
FAIL:
factor is reducible
fmpz_mpoly_factor_content 0.03 (PASS)
fmpz_mpoly_factor_gcd_zippel 0.16 (PASS)
fmpz_mpoly_factor_lcc_kaltofen...
fmpz_mpoly_factor_lcc_kaltofen 0.01 (PASS)
fmpz_mpoly_factor_zassenhaus 0.23 (PASS)
fmpz_mpoly_factor_zippel...
fmpz_poly_pfrac 0.23 (PASS)
FAIL:
factor is reducible
make: *** [Makefile:790: build/fmpz_mpoly_factor/test/main_TEST_RUN_2] Aborted (core dumped)
make: *** Waiting for unfinished jobs....
fmpz_mpoly_factor_gcd_zippel2 0.25 (PASS)
fmpz_mpoly_factor_gcd_brown 0.61 (PASS)
fmpz_mpoly_factor_gcd_brown_threaded...
Expected behavior
Tests currently succeed with -O1, expected would be the same with -O2:
$ make distclean && CFLAGS='-O1 -g' ./configure && make -j10 && make -j10 check MOD=fmpz_mpoly_factor
[...]
CC fmpz_mpoly_factor/test/main.c
fmpz_mpoly_factor_zassenhaus...
fmpz_mpoly_factor...
fmpz_mpoly_factor_squarefree...
fmpz_mpoly_factor_gcd_brown...
fmpz_mpoly_factor_gcd_subresultant...
fmpz_poly_pfrac...
fmpz_mpoly_factor_gcd_zippel...
fmpz_mpoly_factor_squarefree 0.02 (PASS)
fmpz_mpoly_factor_wang...
fmpz_mpoly_factor 0.04 (PASS)
fmpz_mpoly_factor_content...
fmpz_mpoly_factor_gcd_subresultant 0.06 (PASS)
fmpz_mpoly_factor_gcd_zippel2...
fmpz_mpoly_factor_content 0.03 (PASS)
fmpz_mpoly_factor_gcd_zippel 0.17 (PASS)
fmpz_mpoly_factor_lcc_kaltofen...
fmpz_mpoly_factor_lcc_kaltofen 0.01 (PASS)
fmpz_mpoly_factor_wang 0.19 (PASS)
fmpz_poly_pfrac 0.24 (PASS)
fmpz_mpoly_factor_zassenhaus 0.24 (PASS)
fmpz_mpoly_factor_zippel...
fmpz_mpoly_factor_gcd_zippel2 0.25 (PASS)
fmpz_mpoly_factor_zippel 0.13 (PASS)
fmpz_mpoly_factor_gcd_brown 0.63 (PASS)
fmpz_mpoly_factor_gcd_brown_threaded...
fmpz_mpoly_factor_gcd_brown_threaded 0.11 (PASS)
All tests passed for fmpz_mpoly_factor.
System (please complete the following information):
- System CPU: AMD Ryzen 9 7900X (Fedora 42)
- Version of FLINT (if using Git, please specify commit): 3.2.2, 3.3.0, and 94b262d899476a5559aec65b4e65673dd77399c6
- How FLINT was configured (i.e. options pushed):
CFLAGS='-O2 -g' ./configure Output of
configurechecking build system type... zen4-pc-linux-gnu checking host system type... zen4-pc-linux-gnu checking how to print strings... printf checking for gcc... gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... no checking for suffix of object files... o checking whether the compiler supports GNU C... yes checking whether gcc accepts -g... yes checking for gcc option to enable C11 features... none needed checking for a sed that does not truncate output... /usr/bin/sed checking for grep that handles long lines and -e... /usr/bin/grep checking for egrep... /usr/bin/grep -E checking for fgrep... /usr/bin/grep -F checking for ld used by gcc... ld checking if the linker (ld) is GNU ld... yes checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B checking the name lister (/usr/bin/nm -B) interface... BSD nm checking whether ln -s works... yes checking the maximum length of command line arguments... 1572864 checking how to convert zen4-pc-linux-gnu file names to zen4-pc-linux-gnu format... func_convert_file_noop checking how to convert zen4-pc-linux-gnu file names to toolchain format... func_convert_file_noop checking for ld option to reload object files... -r checking for file... file checking for objdump... objdump checking how to recognize dependent libraries... pass_all checking for dlltool... no checking how to associate runtime and link libraries... printf %s\n checking for ranlib... ranlib checking for archiver @FILE support... @ checking for strip... strip checking for gawk... gawk checking command to parse /usr/bin/nm -B output from gcc object... ok checking for sysroot... no checking for a working dd... /usr/bin/dd checking how to truncate binary pipes... /usr/bin/dd bs=4096 count=1 checking for mt... no checking if : is a manifest tool... no checking for stdio.h... yes checking for stdlib.h... yes checking for string.h... yes checking for inttypes.h... yes checking for stdint.h... yes checking for strings.h... yes checking for sys/stat.h... yes checking for sys/types.h... yes checking for unistd.h... yes checking for dlfcn.h... yes checking for objdir... .libs checking if gcc supports -fno-rtti -fno-exceptions... no checking for gcc option to produce PIC... -fPIC -DPIC checking if gcc PIC flag -fPIC -DPIC works... yes checking if gcc static flag -static works... no checking if gcc supports -c -o file.o... yes checking if gcc supports -c -o file.o... (cached) yes checking whether the gcc linker (ld) supports shared libraries... yes checking whether -lc should be explicitly linked in... no checking dynamic linker characteristics... GNU/Linux ld.so checking how to hardcode library paths into programs... immediate checking whether stripping libraries is possible... yes checking if libtool supports shared libraries... yes checking whether to build shared libraries... yes checking whether to build static libraries... no checking for a race-free mkdir -p... /usr/bin/mkdir -p checking how to run the C preprocessor... gcc -E checking if compiler is GCC... yes checking if compiler is Clang... no checking for inline... inline checking whether byte ordering is bigendian... no checking if memory is strongly-ordered... yes checking for gmp.h... yes checking if version of GMP is greater than 6.2.1... yes checking if GMP defines mp_limb_t as unsigned long long int... no checking for mpfr.h... yes checking if version of MPFR is greater than 4.1.0... yes checking for desired ABI... 64 checking for stdarg.h... yes checking for math.h... yes checking for float.h... yes checking for errno.h... yes checking for fenv.h... yes checking for alloca.h... yes checking for malloc.h... yes checking for sys/param.h... yes checking for windows.h... no checking for pthread_np.h... no checking for pthread.h... yes checking for library containing atan2... -lm checking for library containing __gmpz_init... -lgmp checking for library containing __gmpn_mul_basecase... none required checking for library containing __gmpn_gcd_11... none required checking for library containing __gmpn_div_q... none required checking for library containing __gmpn_invert_limb... none required checking for library containing __gmpn_modexact_1_odd... no checking for library containing __gmpn_addmul_2... none required checking for library containing __gmpn_add_n_sub_n... none required checking for library containing __gmpn_add_nc... no checking for library containing __gmpn_sub_nc... no checking for library containing __gmpn_addlsh1_n... none required checking for library containing __gmpn_addlsh1_n_ip1... no checking for library containing __gmpn_rsh1sub_n... none required checking for library containing __gmpn_rsh1add_n... none required checking for library containing mpfr_init... -lmpfr checking for library containing mpfr_round_p... none required checking for library containing mpfr_mulhigh_n... none required checking for library containing mpfr_sqrhigh_n... none required checking whether gcc accepts -pthread... yes checking if cpu_set_t is supported... yes checking if alloca works... yes checking for aligned_alloc... yes checking for _aligned_malloc... no checking whether gcc accepts -g -O2 -g... yes checking for immintrin.h... yes checking if system have required x86_64 instruction set for fft_small... no checking if system can use FLINT's fft_small module... no checking for suitable m4... m4 checking whether assembler supports --noexecstack option... yes checking how to switch to text section... .text checking how to switch to data section... .data checking for assembler label suffix... : checking for assembler global directive... .globl checking for assembler global directive attribute... checking if globals are prefixed by underscore... no checking how to switch to read-only data section... .section .rodata checking for assembler .type directive... .type $1,@$2 checking for assembler .size directive... .size $1,$2 checking for assembler local label prefix... .L checking for assembler byte directive... .byte checking if .align assembly directive is logarithmic... no checking if the .align directive accepts an 0x90 fill in .text... yes checking for assembler COFF type directives... no creating config.m4 configure: creating ./config.status config.status: creating Makefile config.status: creating flint.pc config.status: creating src/flint.h config.status: creating src/config.h config.status: creating src/flint-config.h config.status: linking src/gmpcompat.h.in to src/gmpcompat.h config.status: linking src/mpn_extras/x86_64/zen4/flint-mparam.h to src/flint-mparam.h config.status: linking src/fmpz/link/fmpz_single.c to src/fmpz/fmpz.c config.status: executing libtool commands
Additional context
Related issues:
- https://github.com/Singular/Singular/issues/1281
- https://github.com/sagemath/sage/issues/40253
$ gdb build/fmpz_mpoly_factor/test/main
[..]
fmpz_mpoly_factor...
fmpz_mpoly_factor 0.04 (PASS)
fmpz_mpoly_factor_content...
fmpz_mpoly_factor_content 0.02 (PASS)
fmpz_mpoly_factor_squarefree...
fmpz_mpoly_factor_squarefree 0.01 (PASS)
fmpz_mpoly_factor_wang...
FAIL:
factor is reducible
Program received signal SIGABRT, Aborted.
0x00007ffff70ec11c in __pthread_kill_implementation () from /lib64/libc.so.6
Missing rpms, try: dnf --enablerepo='*debug*' install gmp-debuginfo-6.3.0-4.fc42.x86_64 glibc-debuginfo-2.41-5.fc42.x86_64
(gdb) bt
#0 0x00007ffff70ec11c in __pthread_kill_implementation () from /lib64/libc.so.6
#1 0x00007ffff7092afe in raise () from /lib64/libc.so.6
#2 0x00007ffff707a6d0 in abort () from /lib64/libc.so.6
#3 0x00007ffff742570b in flint_abort () at /home/vbraun/Sage/flint/src/generic_files/exception.c:130
#4 0x0000000000402c7b in check_omega (lower=lower@entry=5, upper=upper@entry=9223372036854775807, p=p@entry=0x7fffffffc800,
ctx=ctx@entry=0x7fffffffc910, factor_fun=<optimized out>) at /home/vbraun/Sage/flint/src/fmpz_mpoly_factor/test/t-factor.c:73
#5 0x00000000004034f3 in test_fmpz_mpoly_factor_wang () at /home/vbraun/Sage/flint/src/fmpz_mpoly_factor/test/t-factor_wang.c:162
#6 0x0000000000400cc2 in main (argc=<optimized out>, argv=<optimized out>) at /home/vbraun/Sage/flint/src/fmpz_mpoly_factor/test/main.c:49
(gdb) l
44 TEST_FUNCTION(fmpz_poly_pfrac)
45 };
46
47 /* main function *************************************************************/
48
49 TEST_MAIN(tests)
Does it work with GCC 14?
Yes, I should have said that: Works fine on gcc 14 / Fedora 41
I believe I have the infrastructure to test this myself on a similar system. But it may take a month or two before I have the opportunity to sit down and check this.
@antonio-rojas reports that it is also fixed by adding -fno-strict-aliasing, this is also what Fedora does:
https://src.fedoraproject.org/rpms/flint/blob/rawhide/f/flint.spec#_97-98
%build
# FLINT builds and passes all tests without this using GCC <= 14
# Tests fail with incorrect answers using GCC >= 15.0
CFLAGS='%{build_cflags} -fno-strict-aliasing'
CXXFLAGS='%{build_cxxflags} -fno-strict-aliasing'
%configure \
Interesting. Would be good to catch the place where it happens.
Compiling with CFLAGS='-fstrict-aliasing -Wstrict-aliasing=1 -O2' produces possibly relevant warnings.
Here's a selection:
/home/rburing/src/flint-gcc15/src/nmod_poly/hgcd.c: In function '_nmod_poly_hgcd':
/home/rburing/src/flint-gcc15/src/nmod_poly/hgcd.c:30:5: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
30 | GR_MUST_SUCCEED(_gr_poly_hgcd(NULL, &sgnM, (gr_ptr *) M, lenM, A, lenA, B, lenB, a, lena, b, lenb, NMOD_POLY_HGCD_CUTOFF, ctx));
| ^~~~~~~~~~~~~~~
/home/rburing/src/flint-gcc15/src/fmpz/fmpz.c: In function '_fmpz_new_mpz':
/home/rburing/src/flint-gcc15/src/fmpz/fmpz.c:120:13: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
120 | ((fmpz_block_header_s *) page_ptr)->address = ptr;
| ^
/home/rburing/src/flint-gcc15/src/fmpz_poly/mullow_SS.c: In function '_fmpz_poly_mullow_SS':
/home/rburing/src/flint-gcc15/src/fmpz_poly/mullow_SS.c:65:5: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
65 | for (i = 0, ptr = (ulong *) ii + 4*n; i < 4*n; i++, ptr += size)
| ^~~
/home/rburing/src/flint-gcc15/src/fmpz_poly/mullow_SS.c:88:9: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
88 | for (i = 0, ptr = (ulong *) jj + 4*n; i < 4*n; i++, ptr += size)
| ^~~
/home/rburing/src/flint-gcc15/src/fmpz_poly/mullow_SS_precache.c: In function 'fmpz_poly_mul_SS_precache_init':
/home/rburing/src/flint-gcc15/src/fmpz_poly/mullow_SS_precache.c:56:36: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
56 | for (i = 0, ptr = (ulong *) pre->jj + 4*pre->n; i < 4*pre->n; i++, ptr += size)
| ~~~^~~~
/home/rburing/src/flint-gcc15/src/fmpz_poly/mullow_SS_precache.c:58:5: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
58 | t1 = (ulong **) ptr;
| ^~
/home/rburing/src/flint-gcc15/src/fmpz_poly/mullow_SS_precache.c: In function '_fmpz_poly_mullow_SS_precache':
/home/rburing/src/flint-gcc15/src/fmpz_poly/mullow_SS_precache.c:117:5: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
117 | for (i = 0, ptr = (ulong *) ii + 4*pre->n; i < 4*pre->n; i++, ptr += size)
| ^~~
/home/rburing/src/flint-gcc15/src/fmpz_poly/mullow_SS_precache.c:119:5: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
119 | t1 = (ulong **) ptr;
| ^~
In file included from /home/rburing/src/flint-gcc15/src/nmod_mpoly/add.c:14:
/home/rburing/src/flint-gcc15/src/nmod_mpoly.h: In function 'evil_cast_nmod_poly_to_n_poly':
/home/rburing/src/flint-gcc15/src/nmod_mpoly.h:47:5: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
47 | return (n_poly_struct *) a;
| ^~~~~~
/home/rburing/src/flint-gcc15/src/nmod_mpoly.h: In function 'evil_const_cast_nmod_poly_to_n_poly':
/home/rburing/src/flint-gcc15/src/nmod_mpoly.h:53:5: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
53 | return (const n_poly_struct *) a;
| ^~~~~~
/home/rburing/src/flint-gcc15/src/fft/mul_mfa_truncate_sqrt2.c: In function 'mul_mfa_truncate_sqrt2':
/home/rburing/src/flint-gcc15/src/fft/mul_mfa_truncate_sqrt2.c:42:4: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
42 | for (i = 0, ptr = (mp_limb_t *) ii + 4*n; i < 4*n; i++, ptr += size)
| ^~~
/home/rburing/src/flint-gcc15/src/fft/mul_mfa_truncate_sqrt2.c:68:7: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
68 | for (i = 0, ptr = (mp_limb_t *) jj + 4*n; i < 4*n; i++, ptr += size)
| ^~~
/home/rburing/src/flint-gcc15/src/fft/mulmod_2expp1.c: In function '_fft_mulmod_2expp1':
/home/rburing/src/flint-gcc15/src/fft/mulmod_2expp1.c:50:4: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
50 | for (i = 0, ptr = (mp_limb_t *) ii + 2*n; i < 2*n; i++, ptr += size)
| ^~~
/home/rburing/src/flint-gcc15/src/fft/mulmod_2expp1.c:64:7: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
64 | for (i = 0, ptr = (mp_limb_t *) jj + 2*n; i < 2*n; i++, ptr += size)
| ^~~
CC fft/negmod_2expp1.c
/home/rburing/src/flint-gcc15/src/fft/mul_truncate_sqrt2.c: In function 'mul_truncate_sqrt2':
/home/rburing/src/flint-gcc15/src/fft/mul_truncate_sqrt2.c:34:4: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
34 | for (i = 0, ptr = (mp_limb_t *) ii + 4*n; i < 4*n; i++, ptr += size)
| ^~~
/home/rburing/src/flint-gcc15/src/fft/mul_truncate_sqrt2.c:46:7: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing]
46 | for (i = 0, ptr = (mp_limb_t *) jj + 4*n; i < 4*n; i++, ptr += size)
| ^~~
There are more than this, many probably false positives.
I could reproduce with GCC 15.2.0 when passing CFLAGS="-O2 -g" on an 7950X3D. However, when running the default flags, I get no error.
The (first?) error I get is
fmpz_mpoly_factor_wang...
FAIL:
factor is reducible
I guess we have to find the files of which we should push -fno-strict-aliasing.