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
This commit is contained in:
parent
18c5bc3f90
commit
ae6dca8c65
7 changed files with 108 additions and 41 deletions
|
@ -1,5 +1,10 @@
|
|||
2018-03-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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.
|
||||
|
||||
PR c/84953
|
||||
* builtins.c (fold_builtin_strpbrk): For strpbrk(x, "") use type
|
||||
instead of TREE_TYPE (s1) for the return value.
|
||||
|
|
|
@ -33265,8 +33265,8 @@ fold_builtin_cpu (tree fndecl, tree *args)
|
|||
}
|
||||
|
||||
/* Get the appropriate field in __cpu_model. */
|
||||
ref = build3 (COMPONENT_REF, TREE_TYPE (field), __cpu_model_var,
|
||||
field, NULL_TREE);
|
||||
ref = build3 (COMPONENT_REF, TREE_TYPE (field), __cpu_model_var,
|
||||
field, NULL_TREE);
|
||||
|
||||
/* Check the value. */
|
||||
final = build2 (EQ_EXPR, unsigned_type_node, ref,
|
||||
|
@ -33296,20 +33296,34 @@ fold_builtin_cpu (tree fndecl, tree *args)
|
|||
return integer_zero_node;
|
||||
}
|
||||
|
||||
if (isa_names_table[i].feature >= 32)
|
||||
{
|
||||
tree __cpu_features2_var = make_var_decl (unsigned_type_node,
|
||||
"__cpu_features2");
|
||||
|
||||
varpool_node::add (__cpu_features2_var);
|
||||
field_val = (1U << (isa_names_table[i].feature - 32));
|
||||
/* Return __cpu_features2 & field_val */
|
||||
final = build2 (BIT_AND_EXPR, unsigned_type_node,
|
||||
__cpu_features2_var,
|
||||
build_int_cstu (unsigned_type_node, field_val));
|
||||
return build1 (CONVERT_EXPR, integer_type_node, final);
|
||||
}
|
||||
|
||||
field = TYPE_FIELDS (__processor_model_type);
|
||||
/* Get the last field, which is __cpu_features. */
|
||||
while (DECL_CHAIN (field))
|
||||
field = DECL_CHAIN (field);
|
||||
|
||||
/* Get the appropriate field: __cpu_model.__cpu_features */
|
||||
ref = build3 (COMPONENT_REF, TREE_TYPE (field), __cpu_model_var,
|
||||
field, NULL_TREE);
|
||||
ref = build3 (COMPONENT_REF, TREE_TYPE (field), __cpu_model_var,
|
||||
field, NULL_TREE);
|
||||
|
||||
/* Access the 0th element of __cpu_features array. */
|
||||
array_elt = build4 (ARRAY_REF, unsigned_type_node, ref,
|
||||
integer_zero_node, NULL_TREE, NULL_TREE);
|
||||
|
||||
field_val = (1 << isa_names_table[i].feature);
|
||||
field_val = (1U << isa_names_table[i].feature);
|
||||
/* Return __cpu_model.__cpu_features[0] & field_val */
|
||||
final = build2 (BIT_AND_EXPR, unsigned_type_node, array_elt,
|
||||
build_int_cstu (unsigned_type_node, field_val));
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2018-03-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/84945
|
||||
* gcc.target/i386/pr84945.c: New test.
|
||||
|
||||
2018-03-20 Christophe Lyon <christophe.lyon@linaro.org>
|
||||
|
||||
PR target/81647
|
||||
|
|
16
gcc/testsuite/gcc.target/i386/pr84945.c
Normal file
16
gcc/testsuite/gcc.target/i386/pr84945.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* PR target/84945 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
/* AVX512_VNNI instructions are all EVEX encoded, so if
|
||||
__builtin_cpu_supports says avx512vnni is available and avx512f is not,
|
||||
this is a GCC bug. Ditto for AVX512_BITALG */
|
||||
if (!__builtin_cpu_supports ("avx512f")
|
||||
&& (__builtin_cpu_supports ("avx512vnni")
|
||||
|| __builtin_cpu_supports ("avx512bitalg")))
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -124,3 +124,4 @@ extern struct __processor_model
|
|||
unsigned int __cpu_subtype;
|
||||
unsigned int __cpu_features[1];
|
||||
} __cpu_model;
|
||||
extern unsigned int __cpu_features2;
|
||||
|
|
Loading…
Add table
Reference in a new issue