The following patch fixes store sinking to properly account for
self-assignments in the same way DSE does (which means this patch
also enhances store-sinking).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2013-05-21  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/57303
        * tree-ssa-sink.c (statement_sink_location): Improve killing
        stmt detection and properly handle self-assignments.

        * gcc.dg/torture/pr57303.c: New testcase.

Index: gcc/tree-ssa-sink.c
===================================================================
*** gcc/tree-ssa-sink.c (revision 199004)
--- gcc/tree-ssa-sink.c (working copy)
*************** statement_sink_location (gimple stmt, ba
*** 331,341 ****
          gimple use_stmt = USE_STMT (use_p);
  
          /* A killing definition is not a use.  */
!         if (gimple_assign_single_p (use_stmt)
!             && gimple_vdef (use_stmt)
!             && operand_equal_p (gimple_assign_lhs (stmt),
!                                 gimple_assign_lhs (use_stmt), 0))
!           continue;
  
          if (gimple_code (use_stmt) != GIMPLE_PHI)
            return false;
--- 331,349 ----
          gimple use_stmt = USE_STMT (use_p);
  
          /* A killing definition is not a use.  */
!         if ((gimple_has_lhs (use_stmt)
!              && operand_equal_p (gimple_assign_lhs (stmt),
!                                  gimple_get_lhs (use_stmt), 0))
!             || stmt_kills_ref_p (use_stmt, gimple_assign_lhs (stmt)))
!           {
!             /* If use_stmt is or might be a nop assignment then USE_STMT
!                acts as a use as well as definition.  */
!             if (stmt != use_stmt
!                 && ref_maybe_used_by_stmt_p (use_stmt,
!                                              gimple_assign_lhs (stmt)))
!               return false;
!             continue;
!           }
  
          if (gimple_code (use_stmt) != GIMPLE_PHI)
            return false;
Index: gcc/testsuite/gcc.dg/torture/pr57303.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr57303.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr57303.c      (working copy)
***************
*** 0 ****
--- 1,33 ----
+ /* { dg-do run } */
+ 
+ void abort (void);
+ 
+ struct S0
+ {
+   int f0;
+ };
+ struct S1
+ {
+   struct S0 f0;
+ };
+ 
+ struct S1 x = { {0} };
+ struct S1 y = { {1} };
+ 
+ static void
+ foo (struct S0 p)
+ {
+   struct S0 *l = &y.f0;
+   *l = x.f0;
+   if (p.f0)
+     *l = *l;
+ }
+ 
+ int
+ main ()
+ {
+   foo(y.f0);
+   if (y.f0.f0 != 0)
+     abort ();
+   return 0;
+ }

Reply via email to