aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-03-20 09:14:42 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-03-20 09:14:42 +0100
commitae6dca8c651783208564001c56786f3abc762cf3 (patch)
tree434aa97e62aef6d534c2885c7c96fb7a40824a55 /gcc
parent18c5bc3f908b51b44b1b35ece40052221122fe0c (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/config/i386/i386.c24
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr84945.c16
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;
+}