aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2016-11-24 12:02:53 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2016-11-24 12:02:53 +0000
commit3b08cde8dd2b27740e04a6f0e531f2c086a9ec1b (patch)
treeff79e8ab3cb9680654f64078b74a188db96fca41
parentbf2df7a9b39897740e6b2fc8c03b1b195748c98f (diff)
downloadgcc-3b08cde8dd2b27740e04a6f0e531f2c086a9ec1b.zip
gcc-3b08cde8dd2b27740e04a6f0e531f2c086a9ec1b.tar.gz
gcc-3b08cde8dd2b27740e04a6f0e531f2c086a9ec1b.tar.bz2
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20161124-1.c22
-rw-r--r--gcc/tree.c6
-rw-r--r--gcc/tree.h18
5 files changed, 50 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b150362..61f35ae 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-11-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ 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 <mliska@suse.cz>
* print-tree.c (struct bucket): Remove.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 99412e2..a064644 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2016-11-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.c-torture/compile/20161124-1.c: New test.
+
2016-11-24 Jakub Jelinek <jakub@redhat.com>
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 0000000..93badb1
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20161124-1.c
@@ -0,0 +1,22 @@
+/* PR middle-end/78429 */
+/* Testcase by Chengnian Sun <chengniansun@gmail.com> */
+
+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 4f3d678..11e0abc 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 b4ec3fd..62cd7bb 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -5296,6 +5296,9 @@ wi::extended_tree <N>::get_len () const
namespace wi
{
template <typename T>
+ bool fits_to_boolean_p (const T &x, const_tree);
+
+ template <typename T>
bool fits_to_tree_p (const T &x, const_tree);
wide_int min_value (const_tree);
@@ -5305,14 +5308,21 @@ namespace wi
template <typename T>
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 <typename T>
+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)));