https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88805
Florian Weimer <fw at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |NEW CC| |fw at gcc dot gnu.org --- Comment #5 from Florian Weimer <fw at gcc dot gnu.org> --- I can reproduce this using g++ and gcc-8.3.1-2.fc29.x86_64, with this test file: static int implementation_avx2 (void) { return 1; } static int implementation (void) { return 0; } static __typeof__ (implementation) * resolver (void) __asm__ ("resolver"); static __typeof__ (implementation) * resolver (void) { __builtin_cpu_init (); if (__builtin_cpu_supports ("avx2")) return implementation_avx2; else return implementation; } int magic (void) __attribute__ ((ifunc ("resolver"))); Compile with: g++ -O2 -fpic -shared The assembler output contains a reference to __cpu_model: resolver: subq $8, %rsp call __cpu_indicator_init movl $_ZL19implementation_avx2v, %eax movl $_ZL14implementationv, %edx testb $4, __cpu_model+13(%rip) cmove %rdx, %rax addq $8, %rsp ret __cpu_model is a compat symbol in libgcc_s.so.1 (with a single @ in the version): $ eu-readelf -s /usr/lib64/libgcc_s.so.1 | grep cpu_model 151: 000000000001a190 16 OBJECT GLOBAL DEFAULT 27 __cpu_model@GCC_4.8.0 This means that the link editor will not use this symbol and leave it unversioned and undefined: $ eu-readelf -s a.out | grep cpu_model 3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UNDEF __cpu_model 49: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UNDEF __cpu_model I think the expectation is that the definition from libgcc.a is used instead: A local definition has to be used because relocations in IFUNC resolvers are invalid (see bug 70082). But g++ (and presumably gfortran) do not link against libgcc.a. gcc links against libgcc.a and does not have this problem: $ eu-readelf -s a.out | grep cpu_model 44: 0000000000004030 16 OBJECT LOCAL DEFAULT 22 __cpu_model