+tree
+c_common_bool_type (unsigned int precision, bool unsigned_p)
+{
+ /* Standard boolean types. */
+ if (precision == TYPE_PRECISION (boolean_type_node)
+ && unsigned_p == TYPE_UNSIGNED (boolean_type_node))
+ return boolean_type_node;
+
+ /* Non-standard boolean types created by targets. */
+ for (tree t = registered_builtin_types; t; t = TREE_CHAIN (t))
+ {
+ tree type = TREE_VALUE (t);
+ if (VECTOR_BOOLEAN_TYPE_P (type)
+ && precision == TYPE_PRECISION (TREE_TYPE (type))
+ && unsigned_p == TYPE_UNSIGNED (type))
It seems weird to look up normal bool and vector bool in the same
function based on "precision" without reference to whether or not it's
expected to be a vector. It seems like you're only using it to look up
vectors, so it seems simplest to remove normal bool and call the
function c_common_vector_bool_type.
But also I'm not sure why this is needed; see my comment below in
cp_build_binary_op.
+ return type;
+ }
+
+ return NULL_TREE;
+}
+
/* Return a fixed-point type that has at least IBIT ibits and FBIT
fbits
that is unsigned if UNSIGNEDP is nonzero, otherwise signed;
and saturating if SATP is nonzero, otherwise not saturating. */
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/
aarch64.cc
index 0485f695941..a2bc88bb7e2 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -22878,6 +22878,24 @@ aarch64_autovectorize_vector_modes
(vector_modes *modes, bool)
return flags;
}
+/* Implement TARGET_CONVERT_TO_TYPE. Convert EXPR to TYPE. */
+
+static tree
+aarch64_convert_to_type (tree type, tree expr)
+{
+ /* If TYPE is a non-standard boolean type invented by the target,
check if
+ EXPR can be converted to TYPE. */
+ if (TREE_CODE (type) == BOOLEAN_TYPE
+ && TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE
+ && !VECTOR_TYPE_P (type)
+ && !VECTOR_TYPE_P (TREE_TYPE (expr))
+ && TYPE_CANONICAL (type) != TYPE_CANONICAL (TREE_TYPE (expr)))
What is this for? Are there non-standard non-vector boolean types?
+ return build1 (VIEW_CONVERT_EXPR, type, expr);
+
+ /* Use standard rules. */
+ return NULL_TREE;
+}
+
/* Implement TARGET_MANGLE_TYPE. */
static const char *
diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
index 55be12db951..b5c2e07c6f8 100644
--- a/gcc/cp/cvt.cc
+++ b/gcc/cp/cvt.cc
@@ -885,15 +885,22 @@ ocp_convert (tree type, tree expr, int convtype,
int flags,
if (SCOPED_ENUM_P (intype) && (convtype & CONV_STATIC))
e = build_nop (ENUM_UNDERLYING_TYPE (intype), e);
if (complain & tf_warning)
- return cp_truthvalue_conversion (e, complain);
+ e = cp_truthvalue_conversion (e, complain);
else
{
/* Prevent bogus -Wint-in-bool-context warnings coming
from c_common_truthvalue_conversion down the line. */
warning_sentinel w (warn_int_in_bool_context);
warning_sentinel c (warn_sign_compare);
- return cp_truthvalue_conversion (e, complain);
+ e = cp_truthvalue_conversion (e, complain);
}
+
+ /* Sometimes boolean types don't match if a non-standard boolean
+ type has been invented by the target. */
+ tree e2 = targetm.convert_to_type (type, e);
How can this happen?
+ if (e2)
+ return e2;
+ return e;
}
converted = convert_to_integer_maybe_fold (type, e, dofold);
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index a604511db71..29e1fc9fea6 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -6253,18 +6253,26 @@ cp_build_binary_op (const op_location_t
&location,
return error_mark_node;
}
- /* Always construct signed integer vector type. */
- intt = c_common_type_for_size
- (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type0))), 0);
- if (!intt)
+ if (VECTOR_BOOLEAN_TYPE_P (type0) && VECTOR_BOOLEAN_TYPE_P
(type1))
+ result_type = c_common_bool_type
+ (TYPE_PRECISION (TREE_TYPE (type0)),
+ TYPE_UNSIGNED (TREE_TYPE (type0)));
Why not result_type = boolean_type_node and fall through to
build_opaque_vector_type?