On Fri, 9 Jun 2023, Richard Biener wrote:
> The following makes sure that using TYPE_PRECISION on VECTOR_TYPE
> ICEs when tree checking is enabled. This should avoid wrong-code
> in cases like PR110182 and instead ICE.
>
> Bootstrap and regtest pending on x86_64-unknown-linux-gnu, I guess
> there will be some fallout of such change ...
The following is what I need to get it to boostrap on
x86_64-unknown-linux-gnu (with all languages enabled).
I think some cases warrant a TYPE_PRECISION_RAW but most
are fixing existing errors. For some cases I didn't dig
deep enough if the code also needs to compare TYPE_VECTOR_SUBPARTS.
The testsuite is running and shows more issues ...
I put this on hold for the moment but hope to get back to it at
some point. I'll followup with the testresults though.
Richard.
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 9c8eed5442a..34566a342bd 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -1338,6 +1338,10 @@ shorten_binary_op (tree result_type, tree op0, tree op1,
bool bitwise)
int uns;
tree type;
+ /* Do not shorten vector operations. */
+ if (VECTOR_TYPE_P (result_type))
+ return result_type;
+
/* Cast OP0 and OP1 to RESULT_TYPE. Doing so prevents
excessive narrowing when we call get_narrower below. For
example, suppose that OP0 is of unsigned int extended
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 3f3c6685bb3..a8c033ba008 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -12574,10 +12574,10 @@ fold_binary_loc (location_t loc, enum tree_code code,
tree type,
tree targ1 = strip_float_extensions (arg1);
tree newtype = TREE_TYPE (targ0);
- if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
+ if (element_precision (TREE_TYPE (targ1)) > element_precision (newtype))
newtype = TREE_TYPE (targ1);
- if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
+ if (element_precision (newtype) < element_precision (TREE_TYPE (arg0)))
return fold_build2_loc (loc, code, type,
fold_convert_loc (loc, newtype, targ0),
fold_convert_loc (loc, newtype, targ1));
@@ -14540,7 +14540,8 @@ tree_expr_maybe_real_minus_zero_p (const_tree x)
static bool
tree_simple_nonnegative_warnv_p (enum tree_code code, tree type)
{
- if ((TYPE_PRECISION (type) != 1 || TYPE_UNSIGNED (type))
+ if (!VECTOR_TYPE_P (type)
+ && (TYPE_PRECISION (type) != 1 || TYPE_UNSIGNED (type))
&& truth_value_p (code))
/* Truth values evaluate to 0 or 1, which is nonnegative unless we
have a signed:1 type (where the value is -1 and 0). */
diff --git a/gcc/tree-ssa-scopedtables.cc b/gcc/tree-ssa-scopedtables.cc
index 528ddf2a2ab..e698ef97343 100644
--- a/gcc/tree-ssa-scopedtables.cc
+++ b/gcc/tree-ssa-scopedtables.cc
@@ -574,7 +574,7 @@ hashable_expr_equal_p (const struct hashable_expr *expr0,
&& (TREE_CODE (type0) == ERROR_MARK
|| TREE_CODE (type1) == ERROR_MARK
|| TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)
- || TYPE_PRECISION (type0) != TYPE_PRECISION (type1)
+ || element_precision (type0) != element_precision (type1)
|| TYPE_MODE (type0) != TYPE_MODE (type1)))
return false;
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 8e144bc090e..4b43e209c6e 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -13423,7 +13423,10 @@ verify_type_variant (const_tree t, tree tv)
}
verify_variant_match (TYPE_NEEDS_CONSTRUCTING);
}
- verify_variant_match (TYPE_PRECISION);
+ /* ??? Need a TYPE_PRECISION_RAW here? TYPE_VECTOR_SUBPARTS
+ is a poly-int. */
+ if (!VECTOR_TYPE_P (t))
+ verify_variant_match (TYPE_PRECISION);
if (RECORD_OR_UNION_TYPE_P (t))
verify_variant_match (TYPE_TRANSPARENT_AGGR);
else if (TREE_CODE (t) == ARRAY_TYPE)
@@ -13701,8 +13704,12 @@ gimple_canonical_types_compatible_p (const_tree t1,
const_tree t2,
|| TREE_CODE (t1) == OFFSET_TYPE
|| POINTER_TYPE_P (t1))
{
- /* Can't be the same type if they have different recision. */
- if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2))
+ /* Can't be the same type if they have different precision. */
+ /* ??? TYPE_PRECISION_RAW for speed. */
+ if ((VECTOR_TYPE_P (t1)
+ && maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2)))
+ || (!VECTOR_TYPE_P (t1)
+ && TYPE_PRECISION (t1) != TYPE_PRECISION (t2)))
return false;
/* In some cases the signed and unsigned types are required to be