diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e8204e5dcd6..ef9c4800fe2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-11-29 Ira Rosen + + 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. + 2011-11-28 Richard Henderson * config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 467a4f1772b..f2e923685e0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-11-29 Ira Rosen + + PR tree-optimization/51301 + * gcc.dg/vect/pr51301.c: New test. + 2011-11-28 Uros Bizjak * g++.dg/cdce3.C: Use dg-additional-options. diff --git a/gcc/testsuite/gcc.dg/vect/pr51301.c b/gcc/testsuite/gcc.dg/vect/pr51301.c new file mode 100644 index 00000000000..c0000cad942 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr51301.c @@ -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" } } */ diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index d260e801bca..22414475f6f 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -1088,6 +1088,7 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts, 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, heap) **stmts, 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, heap) **stmts, { 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)