[PATCH] Fix PR53516

Richard Guenther rguenther@suse.de
Tue May 29 14:01:00 GMT 2012


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  <rguenther@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;
+ }



More information about the Gcc-patches mailing list