This fixes PR53516 - we are happily vectorizing/memsetting stores to bitfields. That's obviously wrong.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2012-05-29 Richard Guenther <rguent...@suse.de> PR tree-optimization/53516 * tree-data-ref.c (stmt_with_adjacent_zero_store_dr_p): Reject bitfield accesses. * tree-vect-data-refs.c (vect_analyze_data_refs): Likewise. * gcc.dg/torture/pr53516.c: New testcase. Index: gcc/tree-data-ref.c =================================================================== *** gcc/tree-data-ref.c (revision 187943) --- gcc/tree-data-ref.c (working copy) *************** stores_from_loop (struct loop *loop, VEC *** 5255,5280 **** bool stmt_with_adjacent_zero_store_dr_p (gimple stmt) { ! tree op0, op1; bool res; struct data_reference *dr; if (!stmt || !gimple_vdef (stmt) ! || !is_gimple_assign (stmt) ! || !gimple_assign_single_p (stmt) ! || !(op1 = gimple_assign_rhs1 (stmt)) ! || !(integer_zerop (op1) || real_zerop (op1))) return false; dr = XCNEW (struct data_reference); - op0 = gimple_assign_lhs (stmt); DR_STMT (dr) = stmt; ! DR_REF (dr) = op0; res = dr_analyze_innermost (dr, loop_containing_stmt (stmt)) ! && stride_of_unit_type_p (DR_STEP (dr), TREE_TYPE (op0)); free_data_ref (dr); return res; --- 5255,5287 ---- bool stmt_with_adjacent_zero_store_dr_p (gimple stmt) { ! tree lhs, rhs; bool res; struct data_reference *dr; if (!stmt || !gimple_vdef (stmt) ! || !gimple_assign_single_p (stmt)) ! return false; ! ! lhs = gimple_assign_lhs (stmt); ! rhs = gimple_assign_rhs1 (stmt); ! ! /* If this is a bitfield store bail out. */ ! if (TREE_CODE (lhs) == COMPONENT_REF ! && DECL_BIT_FIELD (TREE_OPERAND (lhs, 1))) ! return false; ! ! if (!(integer_zerop (rhs) || real_zerop (rhs))) return false; dr = XCNEW (struct data_reference); DR_STMT (dr) = stmt; ! DR_REF (dr) = lhs; res = dr_analyze_innermost (dr, loop_containing_stmt (stmt)) ! && stride_of_unit_type_p (DR_STEP (dr), TREE_TYPE (lhs)); free_data_ref (dr); return res; Index: gcc/tree-vect-data-refs.c =================================================================== *** gcc/tree-vect-data-refs.c (revision 187943) --- gcc/tree-vect-data-refs.c (working copy) *************** vect_analyze_data_refs (loop_vec_info lo *** 2972,2981 **** return false; } - base = unshare_expr (DR_BASE_ADDRESS (dr)); - offset = unshare_expr (DR_OFFSET (dr)); - init = unshare_expr (DR_INIT (dr)); - if (stmt_can_throw_internal (stmt)) { if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) --- 2972,2977 ---- *************** vect_analyze_data_refs (loop_vec_info lo *** 2997,3002 **** --- 2993,3024 ---- return false; } + if (TREE_CODE (DR_REF (dr)) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (DR_REF (dr), 1))) + { + if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) + { + fprintf (vect_dump, "not vectorized: statement is bitfield " + "access "); + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); + } + + if (bb_vinfo) + { + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + stop_bb_analysis = true; + continue; + } + + if (gather) + free_data_ref (dr); + return false; + } + + base = unshare_expr (DR_BASE_ADDRESS (dr)); + offset = unshare_expr (DR_OFFSET (dr)); + init = unshare_expr (DR_INIT (dr)); + if (is_gimple_call (stmt)) { if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) Index: gcc/testsuite/gcc.dg/torture/pr53516.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr53516.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr53516.c (revision 0) *************** *** 0 **** --- 1,32 ---- + /* { dg-do run } */ + /* { dg-options "-ftree-vectorize -ftree-loop-distribute-patterns" } */ + + extern void abort (void); + + struct Foo + { + char a : 1; + char b : 7; + }; + + struct Foo x[256]; + int y[256]; + + void __attribute__((noinline,noclone)) bar (int n) + { + int i; + for (i = 0; i < n; ++i) + { + x[i].a = 0; + y[i] = 3; + } + } + + int main() + { + x[5].b = 7; + bar (256); + if (x[5].b != 7) + abort (); + return 0; + }