Bugzilla – Bug 1160986
gcc9 -fPIC creates unreproducible assembler code
Last modified: 2021-04-06 03:08:59 UTC
Created attachment 827567 [details] test1.c While working on reproducible builds for openSUSE, I found that our darktables package had multiple unreproducible .o files that resulted in unreproducible .so output. I used gcc -E $MANYARGS introspection_toneequal.c to produce the attached test1.c reproducer. Steps to Reproduce: for i in 1 2 ; do gcc-9 -fPIC -S test1.c && md5sum test1.s ; done Actual Result: produces a different md5sum output for every run. Expected Result: output should be fully deterministic. same for gcc
Confirmed. Differences are all in ifunc resolver calls: - call dt_simd_memcpy._GLOBAL___t.i_3D085019_0x561944bc33c36f7b.ifunc@PLT + call dt_simd_memcpy._GLOBAL___t.i_3D085019_0x2106691e4ac81b0a.ifunc@PLT where without -fPIC we don't "mangle" the symbols this way: call dt_simd_memcpy._GLOBAL___dt_module_dt_version.ifunc the testcase uses __attribute__((target_clones("default", "sse2", "sse3", "sse4.1", "sse4.2", "popcnt", "avx", "avx2", "avx512f", "fma4"))) static inline void dt_simd_memcpy(const float *const __restrict__ in, float *const __restrict__ out, const size_t num_elem) { that the function is static is important, the following is a reduced testcase: __attribute__((target_clones("default", "sse3"))) static void dt_simd_memcpy (const float *const __restrict__ in, float *const __restrict__ out, const int num_elem) { for(int k = 0; k < num_elem; k++) out[k] = in[k]; } void bar(float *in, float *out, int num_elem) { dt_simd_memcpy (in, out, num_elem); }
A workaround is to avoind making dt_simd_memcpy and friends 'static'. GCC has to make the ifunc resolver globally visible and has to choose a "unique" name for this purpose. Which is of course hard, so it tries with randomness.
should be fixed in gcc10
indeed, darktable builds reproducibly since gcc10