From 3b08cde8dd2b27740e04a6f0e531f2c086a9ec1b Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 24 Nov 2016 12:02:53 +0000 Subject: [PATCH] re PR middle-end/78429 (ICE in set_value_range, at tree-vrp.c on non-standard boolean) PR middle-end/78429 * tree.h (wi::fits_to_boolean_p): New predicate. (wi::fits_to_tree_p): Use it for boolean types. * tree.c (int_fits_type_p): Likewise. From-SVN: r242829 --- gcc/ChangeLog | 7 ++++++ gcc/testsuite/ChangeLog | 4 ++++ .../gcc.c-torture/compile/20161124-1.c | 22 +++++++++++++++++++ gcc/tree.c | 6 ++--- gcc/tree.h | 18 +++++++++++---- 5 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/20161124-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1503626b47..61f35aee1e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-11-24 Eric Botcazou + + PR middle-end/78429 + * tree.h (wi::fits_to_boolean_p): New predicate. + (wi::fits_to_tree_p): Use it for boolean types. + * tree.c (int_fits_type_p): Likewise. + 2016-11-24 Martin Liska * print-tree.c (struct bucket): Remove. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 99412e21d46..a0646446232 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-11-24 Eric Botcazou + + * gcc.c-torture/compile/20161124-1.c: New test. + 2016-11-24 Jakub Jelinek PR bootstrap/78493 diff --git a/gcc/testsuite/gcc.c-torture/compile/20161124-1.c b/gcc/testsuite/gcc.c-torture/compile/20161124-1.c new file mode 100644 index 00000000000..93badb15755 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20161124-1.c @@ -0,0 +1,22 @@ +/* PR middle-end/78429 */ +/* Testcase by Chengnian Sun */ + +int a[6]; +char b; +unsigned c; +short d; +volatile int e; + +int foo (void) +{ + int f; + for (; c <= 2; c++) { + d = 3; + for (; d >= 0; d--) { + int g = b; + f = a[d] || b; + } + f || e; + } + return 0; +} diff --git a/gcc/tree.c b/gcc/tree.c index 4f3d678e08f..11e0abcbeb0 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -9144,10 +9144,10 @@ int_fits_type_p (const_tree c, const_tree type) bool ok_for_low_bound, ok_for_high_bound; signop sgn_c = TYPE_SIGN (TREE_TYPE (c)); - /* Short-circuit boolean types since various transformations assume that - they can only take values 0 and 1. */ + /* Non-standard boolean types can have arbitrary precision but various + transformations assume that they can only take values 0 and +/-1. */ if (TREE_CODE (type) == BOOLEAN_TYPE) - return integer_zerop (c) || integer_onep (c); + return wi::fits_to_boolean_p (c, type); retry: type_low_bound = TYPE_MIN_VALUE (type); diff --git a/gcc/tree.h b/gcc/tree.h index b4ec3fd0690..62cd7bb19c3 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5295,6 +5295,9 @@ wi::extended_tree ::get_len () const namespace wi { + template + bool fits_to_boolean_p (const T &x, const_tree); + template bool fits_to_tree_p (const T &x, const_tree); @@ -5303,16 +5306,23 @@ namespace wi wide_int from_mpz (const_tree, mpz_t, bool); } +template +bool +wi::fits_to_boolean_p (const T &x, const_tree type) +{ + return eq_p (x, 0) || eq_p (x, TYPE_UNSIGNED (type) ? 1 : -1); +} + template bool wi::fits_to_tree_p (const T &x, const_tree type) { - /* Short-circuit boolean types since various transformations assume that - they can only take values 0 and 1. */ + /* Non-standard boolean types can have arbitrary precision but various + transformations assume that they can only take values 0 and +/-1. */ if (TREE_CODE (type) == BOOLEAN_TYPE) - return eq_p (x, 0) || eq_p (x, 1); + return fits_to_boolean_p (x, type); - if (TYPE_SIGN (type) == UNSIGNED) + if (TYPE_UNSIGNED (type)) return eq_p (x, zext (x, TYPE_PRECISION (type))); else return eq_p (x, sext (x, TYPE_PRECISION (type))); -- 2.30.2