Hi! As discussed in the PR, because -mf16c implies -mavx, if the CPU has F16C (and AVX) support, but OS doesn't save YMM state, we shouldn't be passing -mf16c.
Also, as noticed by Uros, the clearing of has_fma4 and has_xop if OS doesn't save YMM state was done before it was set. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2014-02-17 Jakub Jelinek <ja...@redhat.com> Uros Bizjak <ubiz...@gmail.com> PR driver/60233 * config/i386/driver-i386.c (host_detect_local_cpu): If YMM state is not saved by the OS, also clear has_f16c. Move CPUID 0x80000001 handling before YMM state saving checking. --- gcc/config/i386/driver-i386.c.jj 2014-01-03 11:41:06.000000000 +0100 +++ gcc/config/i386/driver-i386.c 2014-02-17 10:46:30.572170077 +0100 @@ -495,6 +495,28 @@ const char *host_detect_local_cpu (int a has_xsaveopt = eax & bit_XSAVEOPT; } + /* Check cpuid level of extended features. */ + __cpuid (0x80000000, ext_level, ebx, ecx, edx); + + if (ext_level > 0x80000000) + { + __cpuid (0x80000001, eax, ebx, ecx, edx); + + has_lahf_lm = ecx & bit_LAHF_LM; + has_sse4a = ecx & bit_SSE4a; + has_abm = ecx & bit_ABM; + has_lwp = ecx & bit_LWP; + has_fma4 = ecx & bit_FMA4; + has_xop = ecx & bit_XOP; + has_tbm = ecx & bit_TBM; + has_lzcnt = ecx & bit_LZCNT; + has_prfchw = ecx & bit_PRFCHW; + + has_longmode = edx & bit_LM; + has_3dnowp = edx & bit_3DNOWP; + has_3dnow = edx & bit_3DNOW; + } + /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */ #define XCR_XFEATURE_ENABLED_MASK 0x0 #define XSTATE_FP 0x1 @@ -513,33 +535,12 @@ const char *host_detect_local_cpu (int a has_avx2 = 0; has_fma = 0; has_fma4 = 0; + has_f16c = 0; has_xop = 0; has_xsave = 0; has_xsaveopt = 0; } - /* Check cpuid level of extended features. */ - __cpuid (0x80000000, ext_level, ebx, ecx, edx); - - if (ext_level > 0x80000000) - { - __cpuid (0x80000001, eax, ebx, ecx, edx); - - has_lahf_lm = ecx & bit_LAHF_LM; - has_sse4a = ecx & bit_SSE4a; - has_abm = ecx & bit_ABM; - has_lwp = ecx & bit_LWP; - has_fma4 = ecx & bit_FMA4; - has_xop = ecx & bit_XOP; - has_tbm = ecx & bit_TBM; - has_lzcnt = ecx & bit_LZCNT; - has_prfchw = ecx & bit_PRFCHW; - - has_longmode = edx & bit_LM; - has_3dnowp = edx & bit_3DNOWP; - has_3dnow = edx & bit_3DNOW; - } - if (!arch) { if (vendor == signature_AMD_ebx Jakub