This fixes PR56695 where we ICEd because expand_vec_cond_expr
doesn't expect that the result of a vector comparison is of
TYPE_UNSIGNED type. So we unconditionally build a signed type now.
We know that the result of vec comparison is e.g. { -1, 0, -1}
and that all elements have to be SI types.
This patch does one more thing - in verify_gimple_comparison we now
explicitly check whether the result of a vec comparison is signed.
Regtested/bootstrapped on x86_64-unknown-linux-gnu, ok for trunk?
2013-03-27 Marek Polacek <[email protected]>
Richard Biener <[email protected]>
PR tree-optimization/56695
* tree-vect-stmts.c (vectorizable_condition): Unconditionally
build signed result of a vector comparison.
* tree-cfg.c (verify_gimple_comparison): Check that a result
of a vector comparison has signed type.
* gcc.dg/vect/pr56695.c: New test.
--- gcc/tree-vect-stmts.c.mp 2013-03-27 15:19:43.928738801 +0100
+++ gcc/tree-vect-stmts.c 2013-03-27 15:20:12.485832946 +0100
@@ -5265,7 +5265,7 @@ vectorizable_condition (gimple stmt, gim
vec<tree> vec_oprnds1 = vNULL;
vec<tree> vec_oprnds2 = vNULL;
vec<tree> vec_oprnds3 = vNULL;
- tree vec_cmp_type = vectype;
+ tree vec_cmp_type;
if (slp_node || PURE_SLP_STMT (stmt_info))
ncopies = 1;
@@ -5338,14 +5338,12 @@ vectorizable_condition (gimple stmt, gim
&& TREE_CODE (else_clause) != FIXED_CST)
return false;
- if (!INTEGRAL_TYPE_P (TREE_TYPE (vectype)))
- {
- unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype)));
- tree cmp_type = build_nonstandard_integer_type (prec, 1);
- vec_cmp_type = get_same_sized_vectype (cmp_type, vectype);
- if (vec_cmp_type == NULL_TREE)
- return false;
- }
+ unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype)));
+ /* The result of a vector comparison should be signed type. */
+ tree cmp_type = build_nonstandard_integer_type (prec, 0);
+ vec_cmp_type = get_same_sized_vectype (cmp_type, vectype);
+ if (vec_cmp_type == NULL_TREE)
+ return false;
if (!vec_stmt)
{
--- gcc/tree-cfg.c.mp 2013-03-27 15:19:59.144788303 +0100
+++ gcc/tree-cfg.c 2013-03-27 15:20:12.475832906 +0100
@@ -3191,7 +3191,10 @@ verify_gimple_comparison (tree type, tre
if (TYPE_VECTOR_SUBPARTS (type) != TYPE_VECTOR_SUBPARTS (op0_type)
|| (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type)))
- != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0_type)))))
+ != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0_type))))
+ /* The result of a vector comparison is of signed
+ integral type. */
+ || TYPE_UNSIGNED (TREE_TYPE (type)))
{
error ("invalid vector comparison resulting type");
debug_generic_expr (type);
--- gcc/testsuite/gcc.dg/vect/pr56695.c.mp 2013-03-27 15:19:06.901618407
+0100
+++ gcc/testsuite/gcc.dg/vect/pr56695.c 2013-03-27 15:19:00.132596666 +0100
@@ -0,0 +1,14 @@
+/* PR tree-optimization/56695 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+int a, b, i;
+
+void
+f (void)
+{
+ for (i = 0; i < 8; ++i)
+ a |= !(i |= b %= 1);
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
Marek