On Thu, Mar 29, 2018 at 2:43 PM, H.J. Lu <hongjiu...@intel.com> wrote: > Enable AVX and AVX512 features only if their states are supported by > OSXSAVE. > > OK for trunk and release branches? > > > H.J. > --- > PR target/85100 > * config/i386/cpuinfo.c (XCR_XFEATURE_ENABLED_MASK): New. > (XSTATE_FP): Likewise. > (XSTATE_SSE): Likewise. > (XSTATE_YMM): Likewise. > (XSTATE_OPMASK): Likewise. > (XSTATE_ZMM): Likewise. > (XSTATE_HI_ZMM): Likewise. > (XCR_AVX_ENABLED_MASK): Likewise. > (XCR_AVX512F_ENABLED_MASK): Likewise. > (get_available_features): Enable AVX and AVX512 features only > if their states are supported by OSXSAVE
OK for trunk and release branches after a couple of days without problems in trunk. Thanks, Uros. > --- > libgcc/config/i386/cpuinfo.c | 134 > +++++++++++++++++++++++++++++-------------- > 1 file changed, 90 insertions(+), 44 deletions(-) > > diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c > index 4eb3f5cd944..1dac110a79a 100644 > --- a/libgcc/config/i386/cpuinfo.c > +++ b/libgcc/config/i386/cpuinfo.c > @@ -240,6 +240,40 @@ get_available_features (unsigned int ecx, unsigned int > edx, > unsigned int features = 0; > unsigned int features2 = 0; > > + /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */ > +#define XCR_XFEATURE_ENABLED_MASK 0x0 > +#define XSTATE_FP 0x1 > +#define XSTATE_SSE 0x2 > +#define XSTATE_YMM 0x4 > +#define XSTATE_OPMASK 0x20 > +#define XSTATE_ZMM 0x40 > +#define XSTATE_HI_ZMM 0x80 > + > +#define XCR_AVX_ENABLED_MASK \ > + (XSTATE_SSE | XSTATE_YMM) > +#define XCR_AVX512F_ENABLED_MASK \ > + (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM) > + > + /* Check if AVX and AVX512 are usable. */ > + int avx_usable = 0; > + int avx512_usable = 0; > + if ((ecx & bit_OSXSAVE)) > + { > + /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and > + ZMM16-ZMM31 states are supported by OSXSAVE. */ > + unsigned int xcrlow; > + unsigned int xcrhigh; > + asm (".byte 0x0f, 0x01, 0xd0" > + : "=a" (xcrlow), "=d" (xcrhigh) > + : "c" (XCR_XFEATURE_ENABLED_MASK)); > + if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK) > + { > + avx_usable = 1; > + avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK) > + == XCR_AVX512F_ENABLED_MASK); > + } > + } > + > #define set_feature(f) \ > if (f < 32) features |= (1U << f); else features2 |= (1U << (f - 32)) > > @@ -265,10 +299,13 @@ get_available_features (unsigned int ecx, unsigned int > edx, > set_feature (FEATURE_SSE4_1); > if (ecx & bit_SSE4_2) > set_feature (FEATURE_SSE4_2); > - if (ecx & bit_AVX) > - set_feature (FEATURE_AVX); > - if (ecx & bit_FMA) > - set_feature (FEATURE_FMA); > + if (avx_usable) > + { > + if (ecx & bit_AVX) > + set_feature (FEATURE_AVX); > + if (ecx & bit_FMA) > + set_feature (FEATURE_FMA); > + } > > /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */ > if (max_cpuid_level >= 7) > @@ -276,44 +313,50 @@ get_available_features (unsigned int ecx, unsigned int > edx, > __cpuid_count (7, 0, eax, ebx, ecx, edx); > if (ebx & bit_BMI) > set_feature (FEATURE_BMI); > - if (ebx & bit_AVX2) > - set_feature (FEATURE_AVX2); > + if (avx_usable) > + { > + if (ebx & bit_AVX2) > + set_feature (FEATURE_AVX2); > + } > if (ebx & bit_BMI2) > set_feature (FEATURE_BMI2); > - if (ebx & bit_AVX512F) > - set_feature (FEATURE_AVX512F); > - if (ebx & bit_AVX512VL) > - set_feature (FEATURE_AVX512VL); > - if (ebx & bit_AVX512BW) > - set_feature (FEATURE_AVX512BW); > - if (ebx & bit_AVX512DQ) > - set_feature (FEATURE_AVX512DQ); > - if (ebx & bit_AVX512CD) > - set_feature (FEATURE_AVX512CD); > - if (ebx & bit_AVX512PF) > - set_feature (FEATURE_AVX512PF); > - if (ebx & bit_AVX512ER) > - set_feature (FEATURE_AVX512ER); > - if (ebx & bit_AVX512IFMA) > - set_feature (FEATURE_AVX512IFMA); > - if (ecx & bit_AVX512VBMI) > - set_feature (FEATURE_AVX512VBMI); > - if (ecx & bit_AVX512VBMI2) > - set_feature (FEATURE_AVX512VBMI2); > - if (ecx & bit_GFNI) > - set_feature (FEATURE_GFNI); > - if (ecx & bit_VPCLMULQDQ) > - set_feature (FEATURE_VPCLMULQDQ); > - if (ecx & bit_AVX512VNNI) > - set_feature (FEATURE_AVX512VNNI); > - if (ecx & bit_AVX512BITALG) > - set_feature (FEATURE_AVX512BITALG); > - if (ecx & bit_AVX512VPOPCNTDQ) > - set_feature (FEATURE_AVX512VPOPCNTDQ); > - if (edx & bit_AVX5124VNNIW) > - set_feature (FEATURE_AVX5124VNNIW); > - if (edx & bit_AVX5124FMAPS) > - set_feature (FEATURE_AVX5124FMAPS); > + if (avx512_usable) > + { > + if (ebx & bit_AVX512F) > + set_feature (FEATURE_AVX512F); > + if (ebx & bit_AVX512VL) > + set_feature (FEATURE_AVX512VL); > + if (ebx & bit_AVX512BW) > + set_feature (FEATURE_AVX512BW); > + if (ebx & bit_AVX512DQ) > + set_feature (FEATURE_AVX512DQ); > + if (ebx & bit_AVX512CD) > + set_feature (FEATURE_AVX512CD); > + if (ebx & bit_AVX512PF) > + set_feature (FEATURE_AVX512PF); > + if (ebx & bit_AVX512ER) > + set_feature (FEATURE_AVX512ER); > + if (ebx & bit_AVX512IFMA) > + set_feature (FEATURE_AVX512IFMA); > + if (ecx & bit_AVX512VBMI) > + set_feature (FEATURE_AVX512VBMI); > + if (ecx & bit_AVX512VBMI2) > + set_feature (FEATURE_AVX512VBMI2); > + if (ecx & bit_GFNI) > + set_feature (FEATURE_GFNI); > + if (ecx & bit_VPCLMULQDQ) > + set_feature (FEATURE_VPCLMULQDQ); > + if (ecx & bit_AVX512VNNI) > + set_feature (FEATURE_AVX512VNNI); > + if (ecx & bit_AVX512BITALG) > + set_feature (FEATURE_AVX512BITALG); > + if (ecx & bit_AVX512VPOPCNTDQ) > + set_feature (FEATURE_AVX512VPOPCNTDQ); > + if (edx & bit_AVX5124VNNIW) > + set_feature (FEATURE_AVX5124VNNIW); > + if (edx & bit_AVX5124FMAPS) > + set_feature (FEATURE_AVX5124FMAPS); > + } > } > > /* Check cpuid level of extended features. */ > @@ -325,10 +368,13 @@ get_available_features (unsigned int ecx, unsigned int > edx, > > if (ecx & bit_SSE4a) > set_feature (FEATURE_SSE4_A); > - if (ecx & bit_FMA4) > - set_feature (FEATURE_FMA4); > - if (ecx & bit_XOP) > - set_feature (FEATURE_XOP); > + if (avx_usable) > + { > + if (ecx & bit_FMA4) > + set_feature (FEATURE_FMA4); > + if (ecx & bit_XOP) > + set_feature (FEATURE_XOP); > + } > } > > __cpu_model.__cpu_features[0] = features; > -- > 2.14.3 >