re PR middle-end/78429 (ICE in set_value_range, at tree-vrp.c on non-standard boolean)
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 24 Nov 2016 12:02:53 +0000 (12:02 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 24 Nov 2016 12:02:53 +0000 (12:02 +0000)
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
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20161124-1.c [new file with mode: 0644]
gcc/tree.c
gcc/tree.h

index b1503626b47c05807263eb01298dc26f1532ba8c..61f35aee1e0c595d74ecf02087c603d2e571f700 100644 (file)
@@ -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.
index 99412e21d469d181b11c6ad1c6352777e7b4bc35..a0646446232dc74afddb1a6d5c2520e0e704659a 100644 (file)
@@ -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 (file)
index 0000000..93badb1
--- /dev/null
@@ -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;
+}
index 4f3d678e08fb5ad989027c51ee7a28298f4e93a1..11e0abcbeb085668deea519c602c7666e7f1f0d5 100644 (file)
@@ -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);
index b4ec3fd069084bc1182f3a8c516187ee813a46b7..62cd7bb19c3a2ae41b13568b0020eaabac3e5cbb 100644 (file)
@@ -5295,6 +5295,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);
 
@@ -5303,16 +5306,23 @@ namespace wi
   wide_int from_mpz (const_tree, mpz_t, bool);
 }
 
+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)));