diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-03-20 09:14:42 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-03-20 09:14:42 +0100 |
commit | ae6dca8c651783208564001c56786f3abc762cf3 (patch) | |
tree | 434aa97e62aef6d534c2885c7c96fb7a40824a55 /libgcc | |
parent | 18c5bc3f908b51b44b1b35ece40052221122fe0c (diff) | |
download | gcc-ae6dca8c651783208564001c56786f3abc762cf3.zip gcc-ae6dca8c651783208564001c56786f3abc762cf3.tar.gz gcc-ae6dca8c651783208564001c56786f3abc762cf3.tar.bz2 |
re PR target/84945 (UBSAN: gcc/config/i386/i386.c:33312:22: runtime error: shift exponent 32 is too large for 32-bit type 'int')
PR target/84945
* config/i386/i386.c (fold_builtin_cpu): For features above 31
use __cpu_features2 variable instead of __cpu_model.__cpu_features[0].
Use 1U instead of 1. Formatting fixes.
* gcc.target/i386/pr84945.c: New test.
* config/i386/cpuinfo.h (__cpu_features2): Declare.
* config/i386/cpuinfo.c (__cpu_features2): New variable for
ifndef SHARED only.
(set_feature): Define.
(get_available_features): Use set_feature macro. Set __cpu_features2
to the second word of features ifndef SHARED.
From-SVN: r258673
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 10 | ||||
-rw-r--r-- | libgcc/config/i386/cpuinfo.c | 88 | ||||
-rw-r--r-- | libgcc/config/i386/cpuinfo.h | 1 |
3 files changed, 63 insertions, 36 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 40407ab..a3da8dc 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,13 @@ +2018-03-20 Jakub Jelinek <jakub@redhat.com> + + PR target/84945 + * config/i386/cpuinfo.h (__cpu_features2): Declare. + * config/i386/cpuinfo.c (__cpu_features2): New variable for + ifndef SHARED only. + (set_feature): Define. + (get_available_features): Use set_feature macro. Set __cpu_features2 + to the second word of features ifndef SHARED. + 2018-03-15 Julia Koval <julia.koval@intel.com> * config/i386/cpuinfo.c (get_available_features): Add diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c index 8a6eef5..4eb3f5c 100644 --- a/libgcc/config/i386/cpuinfo.c +++ b/libgcc/config/i386/cpuinfo.c @@ -39,6 +39,13 @@ int __cpu_indicator_init (void) struct __processor_model __cpu_model = { }; +#ifndef SHARED +/* We want to move away from __cpu_model in libgcc_s.so.1 and the + size of __cpu_model is part of ABI. So, new features that don't + fit into __cpu_model.__cpu_features[0] go into extra variables + in libgcc.a only, preferrably hidden. */ +unsigned int __cpu_features2; +#endif /* Get the specific type of AMD CPU. */ @@ -231,78 +238,82 @@ get_available_features (unsigned int ecx, unsigned int edx, unsigned int ext_level; unsigned int features = 0; + unsigned int features2 = 0; + +#define set_feature(f) \ + if (f < 32) features |= (1U << f); else features2 |= (1U << (f - 32)) if (edx & bit_CMOV) - features |= (1 << FEATURE_CMOV); + set_feature (FEATURE_CMOV); if (edx & bit_MMX) - features |= (1 << FEATURE_MMX); + set_feature (FEATURE_MMX); if (edx & bit_SSE) - features |= (1 << FEATURE_SSE); + set_feature (FEATURE_SSE); if (edx & bit_SSE2) - features |= (1 << FEATURE_SSE2); + set_feature (FEATURE_SSE2); if (ecx & bit_POPCNT) - features |= (1 << FEATURE_POPCNT); + set_feature (FEATURE_POPCNT); if (ecx & bit_AES) - features |= (1 << FEATURE_AES); + set_feature (FEATURE_AES); if (ecx & bit_PCLMUL) - features |= (1 << FEATURE_PCLMUL); + set_feature (FEATURE_PCLMUL); if (ecx & bit_SSE3) - features |= (1 << FEATURE_SSE3); + set_feature (FEATURE_SSE3); if (ecx & bit_SSSE3) - features |= (1 << FEATURE_SSSE3); + set_feature (FEATURE_SSSE3); if (ecx & bit_SSE4_1) - features |= (1 << FEATURE_SSE4_1); + set_feature (FEATURE_SSE4_1); if (ecx & bit_SSE4_2) - features |= (1 << FEATURE_SSE4_2); + set_feature (FEATURE_SSE4_2); if (ecx & bit_AVX) - features |= (1 << FEATURE_AVX); + set_feature (FEATURE_AVX); if (ecx & bit_FMA) - features |= (1 << FEATURE_FMA); + set_feature (FEATURE_FMA); /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */ if (max_cpuid_level >= 7) { __cpuid_count (7, 0, eax, ebx, ecx, edx); if (ebx & bit_BMI) - features |= (1 << FEATURE_BMI); + set_feature (FEATURE_BMI); if (ebx & bit_AVX2) - features |= (1 << FEATURE_AVX2); + set_feature (FEATURE_AVX2); if (ebx & bit_BMI2) - features |= (1 << FEATURE_BMI2); + set_feature (FEATURE_BMI2); if (ebx & bit_AVX512F) - features |= (1 << FEATURE_AVX512F); + set_feature (FEATURE_AVX512F); if (ebx & bit_AVX512VL) - features |= (1 << FEATURE_AVX512VL); + set_feature (FEATURE_AVX512VL); if (ebx & bit_AVX512BW) - features |= (1 << FEATURE_AVX512BW); + set_feature (FEATURE_AVX512BW); if (ebx & bit_AVX512DQ) - features |= (1 << FEATURE_AVX512DQ); + set_feature (FEATURE_AVX512DQ); if (ebx & bit_AVX512CD) - features |= (1 << FEATURE_AVX512CD); + set_feature (FEATURE_AVX512CD); if (ebx & bit_AVX512PF) - features |= (1 << FEATURE_AVX512PF); + set_feature (FEATURE_AVX512PF); if (ebx & bit_AVX512ER) - features |= (1 << FEATURE_AVX512ER); + set_feature (FEATURE_AVX512ER); if (ebx & bit_AVX512IFMA) - features |= (1 << FEATURE_AVX512IFMA); + set_feature (FEATURE_AVX512IFMA); if (ecx & bit_AVX512VBMI) - features |= (1 << FEATURE_AVX512VBMI); + set_feature (FEATURE_AVX512VBMI); if (ecx & bit_AVX512VBMI2) - features |= (1 << FEATURE_AVX512VBMI2); + set_feature (FEATURE_AVX512VBMI2); if (ecx & bit_GFNI) - features |= (1 << FEATURE_GFNI); + set_feature (FEATURE_GFNI); if (ecx & bit_VPCLMULQDQ) - features |= (1 << FEATURE_VPCLMULQDQ); + set_feature (FEATURE_VPCLMULQDQ); if (ecx & bit_AVX512VNNI) - features |= (1 << FEATURE_AVX512VNNI); + set_feature (FEATURE_AVX512VNNI); if (ecx & bit_AVX512BITALG) - features |= (1 << FEATURE_AVX512BITALG); + set_feature (FEATURE_AVX512BITALG); if (ecx & bit_AVX512VPOPCNTDQ) - features |= (1 << FEATURE_AVX512VPOPCNTDQ); + set_feature (FEATURE_AVX512VPOPCNTDQ); if (edx & bit_AVX5124VNNIW) - features |= (1 << FEATURE_AVX5124VNNIW); + set_feature (FEATURE_AVX5124VNNIW); if (edx & bit_AVX5124FMAPS) - features |= (1 << FEATURE_AVX5124FMAPS); + set_feature (FEATURE_AVX5124FMAPS); } /* Check cpuid level of extended features. */ @@ -313,14 +324,19 @@ get_available_features (unsigned int ecx, unsigned int edx, __cpuid (0x80000001, eax, ebx, ecx, edx); if (ecx & bit_SSE4a) - features |= (1 << FEATURE_SSE4_A); + set_feature (FEATURE_SSE4_A); if (ecx & bit_FMA4) - features |= (1 << FEATURE_FMA4); + set_feature (FEATURE_FMA4); if (ecx & bit_XOP) - features |= (1 << FEATURE_XOP); + set_feature (FEATURE_XOP); } __cpu_model.__cpu_features[0] = features; +#ifndef SHARED + __cpu_features2 = features2; +#else + (void) features2; +#endif } /* A constructor function that is sets __cpu_model and __cpu_features with diff --git a/libgcc/config/i386/cpuinfo.h b/libgcc/config/i386/cpuinfo.h index 371c8f6..ab2260c 100644 --- a/libgcc/config/i386/cpuinfo.h +++ b/libgcc/config/i386/cpuinfo.h @@ -124,3 +124,4 @@ extern struct __processor_model unsigned int __cpu_subtype; unsigned int __cpu_features[1]; } __cpu_model; +extern unsigned int __cpu_features2; |