Hi,

In vectorizer's over-widening pattern recognition the last statement
is expected to be a type demotion, but the check for that was
incomplete. We now check that the resulting type is not bigger than
the original type of the computation.

Bootstrapped and tested on powerpc64-suse-linux, tested on
arm-linux-gnueabi (cross).
Committed.

Ira

ChangeLog:

        PR tree-optimization/51301
        * tree-vect-patterns.c (vect_recog_over_widening_pattern): Check that
        the last statement doesn't convert to a bigger type than the original
        type of the computation.

testsuite/ChangeLog:

        PR tree-optimization/51301
        * gcc.dg/vect/pr51301.c: New test.

Index: tree-vect-patterns.c
===================================================================
--- tree-vect-patterns.c        (revision 181796)
+++ tree-vect-patterns.c        (working copy)
@@ -1088,6 +1088,7 @@ vect_recog_over_widening_pattern (VEC (gimple, hea
   tree var = NULL_TREE, new_type = NULL_TREE, tmp, new_oprnd;
   bool first;
   struct loop *loop = (gimple_bb (stmt))->loop_father;
+  tree type = NULL;

   first = true;
   while (1)
@@ -1150,6 +1151,7 @@ vect_recog_over_widening_pattern (VEC (gimple, hea
           print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
         }

+      type = gimple_expr_type (stmt);
       prev_stmt = stmt;
       stmt = use_stmt;

@@ -1165,9 +1167,11 @@ vect_recog_over_widening_pattern (VEC (gimple, hea
     {
       use_lhs = gimple_assign_lhs (use_stmt);
       use_type = TREE_TYPE (use_lhs);
-      /* Support only type promotion or signedess change.  */
+      /* Support only type promotion or signedess change.  Check that USE_TYPE
+        is not bigger than the original type.  */
       if (!INTEGRAL_TYPE_P (use_type)
-          || TYPE_PRECISION (new_type) > TYPE_PRECISION (use_type))
+          || TYPE_PRECISION (new_type) > TYPE_PRECISION (use_type)
+         || TYPE_PRECISION (type) < TYPE_PRECISION (use_type))
         return NULL;

       if (TYPE_UNSIGNED (new_type) != TYPE_UNSIGNED (use_type)
Index: testsuite/gcc.dg/vect/pr51301.c
===================================================================
--- testsuite/gcc.dg/vect/pr51301.c     (revision 0)
+++ testsuite/gcc.dg/vect/pr51301.c     (revision 0)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+typedef signed char int8_t;
+typedef signed long long int64_t;
+int64_t
+f0a (int8_t * __restrict__ arg1)
+{
+  int idx;
+  int64_t result = 0;
+  for (idx = 0; idx < 416; idx += 1)
+    result += arg1[idx] << (arg1[idx] == arg1[idx]);
+  return result;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */

Reply via email to