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:
Jakub Jelinek 2018-03-20 09:14:42 +01:00 committed by Jakub Jelinek
parent 18c5bc3f90
commit ae6dca8c65
7 changed files with 108 additions and 41 deletions

View File

@ -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.

View File

@ -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));

View File

@ -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

View 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;
}

View File

@ -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

View File

@ -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

View File

@ -124,3 +124,4 @@ extern struct __processor_model
unsigned int __cpu_subtype;
unsigned int __cpu_features[1];
} __cpu_model;
extern unsigned int __cpu_features2;