+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.
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);
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 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)));