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 /gcc | |
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 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr84945.c | 16 |
4 files changed, 45 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6716270..f782976 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index f45c756..5b1e962 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d141e99..3058d91 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.target/i386/pr84945.c b/gcc/testsuite/gcc.target/i386/pr84945.c new file mode 100644 index 0000000..9599867 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr84945.c @@ -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; +} |