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" } } */