This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR43784


We're not being careful enough wrt NRV.  Caused by cleanup during
IPA-PTA merge.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2010-07-23  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/43784
	* tree-nrv.c (dest_safe_for_nrv_p): It's not safe to NRV
	if the destination is used by the call.

	* gcc.c-torture/execute/pr43784.c: New testcase.
	* g++.dg/torture/pr43784.C: Likewise.

Index: gcc/tree-nrv.c
===================================================================
*** gcc/tree-nrv.c	(revision 162535)
--- gcc/tree-nrv.c	(working copy)
*************** struct gimple_opt_pass pass_nrv =
*** 296,302 ****
     optimization, where DEST is expected to be the LHS of a modify
     expression where the RHS is a function returning an aggregate.
  
!    DEST is available if it is not clobbered by the call.  */
  
  static bool
  dest_safe_for_nrv_p (gimple call)
--- 296,302 ----
     optimization, where DEST is expected to be the LHS of a modify
     expression where the RHS is a function returning an aggregate.
  
!    DEST is available if it is not clobbered or used by the call.  */
  
  static bool
  dest_safe_for_nrv_p (gimple call)
*************** dest_safe_for_nrv_p (gimple call)
*** 310,316 ****
    if (TREE_CODE (dest) == SSA_NAME)
      return true;
  
!   if (call_may_clobber_ref_p (call, dest))
      return false;
  
    return true;
--- 310,317 ----
    if (TREE_CODE (dest) == SSA_NAME)
      return true;
  
!   if (call_may_clobber_ref_p (call, dest)
!       || ref_maybe_used_by_stmt_p (call, dest))
      return false;
  
    return true;
*************** execute_return_slot_opt (void)
*** 345,352 ****
  	      && gimple_call_lhs (stmt)
  	      && !gimple_call_return_slot_opt_p (stmt)
  	      && aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)),
! 				    gimple_call_fndecl (stmt))
! 	     )
  	    {
  	      /* Check if the location being assigned to is
  	         clobbered by the call.  */
--- 346,352 ----
  	      && gimple_call_lhs (stmt)
  	      && !gimple_call_return_slot_opt_p (stmt)
  	      && aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)),
! 				    gimple_call_fndecl (stmt)))
  	    {
  	      /* Check if the location being assigned to is
  	         clobbered by the call.  */
Index: gcc/testsuite/gcc.c-torture/execute/pr43784.c
===================================================================
*** gcc/testsuite/gcc.c-torture/execute/pr43784.c	(revision 0)
--- gcc/testsuite/gcc.c-torture/execute/pr43784.c	(revision 0)
***************
*** 0 ****
--- 1,33 ----
+ struct s {
+   unsigned char a[256];
+ };
+ union u {
+   struct { struct s b; int c; } d;
+   struct { int c; struct s b; } e;
+ };
+ 
+ static union u v;
+ static struct s *p = &v.d.b;
+ static struct s *q = &v.e.b;
+ 
+ static struct s __attribute__((noinline)) rp(void)
+ {
+   return *p;
+ }
+ 
+ static void qp(void)
+ {
+   *q = rp();
+ }
+ 
+ int main()
+ {
+   int i;
+   for (i = 0; i < 256; i++)
+     p->a[i] = i;
+   qp();
+   for (i = 0; i < 256; i++)
+     if (q->a[i] != i)
+       __builtin_abort();
+   return 0;
+ }
Index: gcc/testsuite/g++.dg/torture/pr43784.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr43784.C	(revision 0)
--- gcc/testsuite/g++.dg/torture/pr43784.C	(revision 0)
***************
*** 0 ****
--- 1,24 ----
+ /* { dg-do run } */
+ /* { dg-options "-fno-tree-sra" } */
+ 
+ struct S {int x, y, makemelarge[5];};
+ S __attribute__((noinline)) f (S &s) {
+     S r;
+     r.x = s.y;
+     r.y = s.x;
+     return r;
+ }
+ int __attribute__((noinline)) glob (int a, int b)
+ {
+   S local = { a, b };
+   local = f (local);
+   return local.y;
+ }
+ extern "C" void abort (void);
+ int main (void)
+ {
+   if (glob (1, 3) != 1)
+     abort ();
+   return 0;
+ }
+ 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]