Hi! When a bool store gets a pattern stmt, we need to update DR_STMT (otherwise the original rather than replaced stmts are used e.g. for interleaving etc.).
Bootstrapped/regtested on x86_64-linux and i686-linux, testcase tested on powerpc64-linux, ok for trunk? 2011-11-09 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/51000 * tree-vect-patterns.c (vect_recog_bool_pattern): If adding a pattern stmt for a bool store, adjust DR_STMT too. Don't handle bool conversions to single bit precision lhs. * tree-vect-stmts.c (vect_remove_stores): If next is a pattern stmt, remove its related stmt and free its stmt_vinfo. (free_stmt_vec_info): Free also pattern stmt's vinfo and pattern def stmt's vinfo. * tree-vect-loop.c (destroy_loop_vec_info): Don't try to free pattern stmt's vinfo here. (vect_transform_loop): When calling vect_remove_stores, do gsi_next first and don't call gsi_remove. If not strided store, free stmt vinfo for gsi_stmt (si) rather than stmt. * gcc.dg/vect/pr51000.c: New test. --- gcc/tree-vect-patterns.c.jj 2011-10-31 20:44:14.000000000 +0100 +++ gcc/tree-vect-patterns.c 2011-11-09 13:15:22.117748929 +0100 @@ -2041,7 +2041,8 @@ vect_recog_bool_pattern (VEC (gimple, he rhs_code = gimple_assign_rhs_code (last_stmt); if (CONVERT_EXPR_CODE_P (rhs_code)) { - if (TREE_CODE (TREE_TYPE (lhs)) != INTEGER_TYPE) + if (TREE_CODE (TREE_TYPE (lhs)) != INTEGER_TYPE + || TYPE_PRECISION (TREE_TYPE (lhs)) == 1) return NULL; vectype = get_vectype_for_scalar_type (TREE_TYPE (lhs)); if (vectype == NULL_TREE) @@ -2096,6 +2097,7 @@ vect_recog_bool_pattern (VEC (gimple, he STMT_VINFO_DR_STEP (pattern_stmt_info) = STMT_VINFO_DR_STEP (stmt_vinfo); STMT_VINFO_DR_ALIGNED_TO (pattern_stmt_info) = STMT_VINFO_DR_ALIGNED_TO (stmt_vinfo); + DR_STMT (STMT_VINFO_DATA_REF (stmt_vinfo)) = pattern_stmt; *type_out = vectype; *type_in = vectype; VEC_safe_push (gimple, heap, *stmts, last_stmt); --- gcc/tree-vect-stmts.c.jj 2011-11-08 23:35:12.000000000 +0100 +++ gcc/tree-vect-stmts.c 2011-11-09 15:53:51.558120065 +0100 @@ -5567,10 +5567,14 @@ vect_remove_stores (gimple first_stmt) while (next) { + stmt_vec_info stmt_info = vinfo_for_stmt (next); + + tmp = GROUP_NEXT_ELEMENT (stmt_info); + if (is_pattern_stmt_p (stmt_info)) + next = STMT_VINFO_RELATED_STMT (stmt_info); /* Free the attached stmt_vec_info and remove the stmt. */ next_si = gsi_for_stmt (next); gsi_remove (&next_si, true); - tmp = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next)); free_stmt_vec_info (next); next = tmp; } @@ -5660,6 +5664,22 @@ free_stmt_vec_info (gimple stmt) if (!stmt_info) return; + /* Check if this statement has a related "pattern stmt" + (introduced by the vectorizer during the pattern recognition + pass). Free pattern's stmt_vec_info and def stmt's stmt_vec_info + too. */ + if (STMT_VINFO_IN_PATTERN_P (stmt_info)) + { + stmt_vec_info patt_info + = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info)); + if (patt_info) + { + if (STMT_VINFO_PATTERN_DEF_STMT (patt_info)) + free_stmt_vec_info (STMT_VINFO_PATTERN_DEF_STMT (patt_info)); + free_stmt_vec_info (STMT_VINFO_RELATED_STMT (stmt_info)); + } + } + VEC_free (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmt_info)); set_vinfo_for_stmt (stmt, NULL); free (stmt_info); --- gcc/tree-vect-loop.c.jj 2011-11-07 12:40:56.000000000 +0100 +++ gcc/tree-vect-loop.c 2011-11-09 16:05:47.979550141 +0100 @@ -870,21 +870,8 @@ destroy_loop_vec_info (loop_vec_info loo for (si = gsi_start_bb (bb); !gsi_end_p (si); ) { gimple stmt = gsi_stmt (si); - stmt_vec_info stmt_info = vinfo_for_stmt (stmt); - - if (stmt_info) - { - /* Check if this statement has a related "pattern stmt" - (introduced by the vectorizer during the pattern recognition - pass). Free pattern's stmt_vec_info. */ - if (STMT_VINFO_IN_PATTERN_P (stmt_info) - && vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info))) - free_stmt_vec_info (STMT_VINFO_RELATED_STMT (stmt_info)); - - /* Free stmt_vec_info. */ - free_stmt_vec_info (stmt); - } - + /* Free stmt_vec_info. */ + free_stmt_vec_info (stmt); gsi_next (&si); } } @@ -5347,14 +5334,14 @@ vect_transform_loop (loop_vec_info loop_ /* Interleaving. If IS_STORE is TRUE, the vectorization of the interleaving chain was completed - free all the stores in the chain. */ + gsi_next (&si); vect_remove_stores (GROUP_FIRST_ELEMENT (stmt_info)); - gsi_remove (&si, true); continue; } else { /* Free the attached stmt_vec_info and remove the stmt. */ - free_stmt_vec_info (stmt); + free_stmt_vec_info (gsi_stmt (si)); gsi_remove (&si, true); continue; } --- gcc/testsuite/gcc.dg/vect/pr51000.c.jj 2011-11-09 16:12:02.470128612 +0100 +++ gcc/testsuite/gcc.dg/vect/pr51000.c 2011-11-09 16:12:21.554005264 +0100 @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +_Bool a[2048]; +int b[2048]; + +void +foo () +{ + int i; + for (i = 0; i < 2048; i += 4) + { + a[i] = b[i] <= 10; + a[i + 3] = b[i + 1] <= 10; + a[i + 2] = b[i + 2] <= 10; + a[i + 1] = b[i + 3] <= 10; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ Jakub