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 <ebotca...@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 <ebotca...@adacore.com>
* gcc.c-torture/compile/20161123-1.c: New test.
--
Eric Botcazou
/* PR middle-end/78429 */
/* Testcase by Chengnian Sun <chengnian...@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: 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);