This fixes PR58956 where we TER a load into a call statement lhs
that is modified by the call.  TER already has measures to avoid
doing this for regular assignments so the following simply
extends it to arbitrary stmts (including ASMs).

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

Richard.

2013-11-19  Richard Biener  <rguent...@suse.de>

        PR middle-end/58956
        * tree-ssa-ter.c (find_replaceable_in_bb): Avoid forwarding
        loads into stmts that may clobber it.

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

Index: gcc/tree-ssa-ter.c
===================================================================
*** gcc/tree-ssa-ter.c  (revision 205009)
--- gcc/tree-ssa-ter.c  (working copy)
*************** find_replaceable_in_bb (temp_expr_table_
*** 601,608 ****
              /* If the stmt does a memory store and the replacement
                 is a load aliasing it avoid creating overlapping
                 assignments which we cannot expand correctly.  */
!             if (gimple_vdef (stmt)
!                 && gimple_assign_single_p (stmt))
                {
                  gimple def_stmt = SSA_NAME_DEF_STMT (use);
                  while (is_gimple_assign (def_stmt)
--- 607,613 ----
              /* If the stmt does a memory store and the replacement
                 is a load aliasing it avoid creating overlapping
                 assignments which we cannot expand correctly.  */
!             if (gimple_vdef (stmt))
                {
                  gimple def_stmt = SSA_NAME_DEF_STMT (use);
                  while (is_gimple_assign (def_stmt)
*************** find_replaceable_in_bb (temp_expr_table_
*** 611,618 ****
                      = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
                  if (gimple_vuse (def_stmt)
                      && gimple_assign_single_p (def_stmt)
!                     && refs_may_alias_p (gimple_assign_lhs (stmt),
!                                          gimple_assign_rhs1 (def_stmt)))
                    same_root_var = true;
                }
  
--- 616,623 ----
                      = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
                  if (gimple_vuse (def_stmt)
                      && gimple_assign_single_p (def_stmt)
!                     && stmt_may_clobber_ref_p (stmt,
!                                                gimple_assign_rhs1 (def_stmt)))
                    same_root_var = true;
                }
  
Index: gcc/testsuite/gcc.dg/torture/pr58956.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr58956.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr58956.c      (working copy)
***************
*** 0 ****
--- 1,30 ----
+ /* { dg-do run } */
+ 
+ extern void abort (void);
+ 
+ struct S
+ {
+   int f0;
+ } a = {1}, b, g, *c = &b, **f = &c;
+ 
+ int *d, **e = &d, h;
+ 
+ struct S
+ foo ()
+ {
+   *e = &h;
+   if (!d) 
+     __builtin_unreachable ();
+   *f = &g;
+   return a;
+ }
+ 
+ int
+ main ()
+ {
+   struct S *i = c;
+   *i = foo ();
+   if (b.f0 != 1)
+     abort ();
+   return 0;
+ }

Reply via email to