http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60790
Bug ID: 60790 Summary: libatomic convenience library selects IFUNC implementation before obtaining cpu info. Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: go Assignee: ian at airs dot com Reporter: gary at intrepid dot com CC: nenad at intrepid dot com, PHHargrove at lbl dot gov, rth at gcc dot gnu.org Created attachment 32569 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32569&action=edit libatomic cpuinfo patch We ran into this issue recently while implementing atomic memory support for GNU UPC. We followed an approach similar to libgo -- we included libatomic_convenience.a into libgupc.a. This lets libgupc access GCC's __atomic support without requiring the user to link explicitly with libatomic. While debugging the UPC AMO library on a modern X86-64 platform, we noticed that the locked implementation of compare-exchange-16 was being used in spite of the fact of that the CPU supports the CMPX16 operation directly. We determined that the IFUNC selector function was being called before the constructor function in init.c had run. Thus the libat_feat1_ecx variable was zero. Because the feature bit wasn't set, the selector function chose the CAS function which requires explicit locks. Interestingly, __atomic_is_lock_free(16, NULL) returns true, as expected on this platform because it is called after the init_cpuid() constructor is called. One way to fix this issue is to re-work the logic that queries the CPU feature register value, so that it explicitly initializes the value if it is zero. The assumption here is that __get_cpuid() will always return a non-zero value in the ECX feature register. A patch that implements this approach is attached.