diff mbox

Fix PR middle-end/78429

Message ID 73997113.6Wmqtae7MJ@polaris
State New
Headers show

Commit Message

Eric Botcazou Nov. 23, 2016, 9:59 a.m. UTC
Hi,

this is an ICE present on the mainline and 6 branch, a regression introduced 
by r241529 which added the consistency check for boolean values.  So it turns 
out that Ada is not the only producer of non-standard boolean types, there is 
even a helper function to do it in tree.c (build_nonstandard_boolean_type) and 
it builds even weirder boolean types than Ada since they are signed.

The problem is that -1 is not considered as a valid value for them any more 
and this confuses VRP.  Therefore the attached patch adjusts the consistency 
check to accept -1 instead of +1 for them.

Tested on x86_64-suse-linux, OK for the mainline and 6 branch?


2016-11-23  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-23  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.c-torture/compile/20161123-1.c: New test.

-- 
Eric Botcazou

Comments

Richard Biener Nov. 23, 2016, 11:39 a.m. UTC | #1
On Wed, Nov 23, 2016 at 10:59 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> Hi,

>

> this is an ICE present on the mainline and 6 branch, a regression introduced

> by r241529 which added the consistency check for boolean values.  So it turns

> out that Ada is not the only producer of non-standard boolean types, there is

> even a helper function to do it in tree.c (build_nonstandard_boolean_type) and

> it builds even weirder boolean types than Ada since they are signed.

>

> The problem is that -1 is not considered as a valid value for them any more

> and this confuses VRP.  Therefore the attached patch adjusts the consistency

> check to accept -1 instead of +1 for them.

>

> Tested on x86_64-suse-linux, OK for the mainline and 6 branch?


Ok.

Thanks,
Richard.

>

> 2016-11-23  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-23  Eric Botcazou  <ebotcazou@adacore.com>

>

>         * gcc.c-torture/compile/20161123-1.c: New test.

>

> --

> Eric Botcazou
diff mbox

Patch

Index: tree.h
===================================================================
--- tree.h	(revision 242632)
+++ tree.h	(working copy)
@@ -5294,6 +5294,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);
@@ -5303,14 +5306,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)));
Index: tree.c
===================================================================
--- tree.c	(revision 242632)
+++ tree.c	(working copy)
@@ -9092,10 +9092,10 @@  int_fits_type_p (const_tree c, const_tre
   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);