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 PR47621


This fixes PR47621, while we can in theory handle some 
component-references when writing vars into SSA form (in particular
indirects through union types) an earlier patch enabled pre-existing
code by chance and that code was broken with regarding to
component-ref handing.  The following patch makes us conservative again,
not handling component-refs for now, but keeping the original intent
of the code.

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

Richard.

2011-02-07  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/47621
	* tree-ssa.c (non_rewritable_lvalue_p): New function, split out from
	two duplicates ...
	(execute_update_addresses_taken): ... here.  Make it more
	conservative in what we accept.

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

Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c.orig	2011-01-14 13:27:05.000000000 +0100
--- gcc/tree-ssa.c	2011-02-07 11:30:43.000000000 +0100
*************** non_rewritable_mem_ref_base (tree ref)
*** 1885,1890 ****
--- 1885,1918 ----
    return NULL_TREE;
  }
  
+ /* For an lvalue tree LHS return true if it cannot be rewritten into SSA form.
+    Otherwise return true.  */
+ 
+ static bool 
+ non_rewritable_lvalue_p (tree lhs)
+ {
+   /* A plain decl is always rewritable.  */
+   if (DECL_P (lhs))
+     return false;
+ 
+   /* A decl that is wrapped inside a MEM-REF that covers
+      it full is also rewritable.
+      ???  The following could be relaxed allowing component
+      references that do not change the access size.  */ ;
+   if (TREE_CODE (lhs) == MEM_REF
+       && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR
+       && integer_zerop (TREE_OPERAND (lhs, 1)))
+     {
+       tree decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
+       if (DECL_P (decl)
+ 	  && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (lhs))
+ 	  && (TREE_THIS_VOLATILE (decl) == TREE_THIS_VOLATILE (lhs)))
+ 	return false;
+     }
+ 
+   return true;
+ }
+ 
  /* When possible, clear TREE_ADDRESSABLE bit or set DECL_GIMPLE_REG_P bit and
     mark the variable VAR for conversion into SSA.  Return true when updating
     stmts is required.  */
*************** execute_update_addresses_taken (void)
*** 1978,2006 ****
  	  if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
  	    {
                tree lhs = gimple_get_lhs (stmt);
! 
!               /* A plain decl does not need it set.  */
!               if (lhs && !DECL_P (lhs))
  		{
! 		  tree orig_lhs = lhs;
! 
! 		  while (handled_component_p (lhs))
! 		    lhs = TREE_OPERAND (lhs, 0);
! 
!                   if (DECL_P (lhs))
!                     bitmap_set_bit (not_reg_needs, DECL_UID (lhs));
! 		  else if (TREE_CODE (lhs) == MEM_REF
! 			   && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR)
! 		    {
! 		      decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
! 		      if (DECL_P (decl)
! 			  && (!integer_zerop (TREE_OPERAND (lhs, 1))
! 			      || (DECL_SIZE (decl)
! 				  != TYPE_SIZE (TREE_TYPE (orig_lhs)))
! 			      || (TREE_THIS_VOLATILE (lhs)
! 				  != TREE_THIS_VOLATILE (decl))))
! 			bitmap_set_bit (not_reg_needs, DECL_UID (decl));
! 		    }
                  }
  	    }
  
--- 2006,2018 ----
  	  if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
  	    {
                tree lhs = gimple_get_lhs (stmt);
!               if (lhs
! 		  && TREE_CODE (lhs) != SSA_NAME
! 		  && non_rewritable_lvalue_p (lhs))
  		{
! 		  decl = get_base_address (lhs);
! 		  if (DECL_P (decl))
! 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
                  }
  	    }
  
*************** execute_update_addresses_taken (void)
*** 2027,2055 ****
  		{
  		  tree link = gimple_asm_output_op (stmt, i);
  		  tree lhs = TREE_VALUE (link);
! 
! 		  /* A plain decl does not need it set.  */
! 		  if (!DECL_P (lhs))
  		    {
! 		      tree orig_lhs = lhs;
! 
! 		      while (handled_component_p (lhs))
! 			lhs = TREE_OPERAND (lhs, 0);
! 		  
! 		      if (DECL_P (lhs))
! 			bitmap_set_bit (not_reg_needs, DECL_UID (lhs));
! 		      else if (TREE_CODE (lhs) == MEM_REF
! 			       && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR)
! 			{
! 			  decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
! 			  if (DECL_P (decl)
! 			      && (!integer_zerop (TREE_OPERAND (lhs, 1))
! 				  || (TYPE_MAIN_VARIANT (TREE_TYPE (decl))
! 				      != TYPE_MAIN_VARIANT (TREE_TYPE (orig_lhs)))
! 				  || (TREE_THIS_VOLATILE (lhs)
! 				      != TREE_THIS_VOLATILE (decl))))
! 			    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
! 			}
  		    }
  		}
  	      for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
--- 2039,2050 ----
  		{
  		  tree link = gimple_asm_output_op (stmt, i);
  		  tree lhs = TREE_VALUE (link);
! 		  if (TREE_CODE (lhs) != SSA_NAME
! 		      && non_rewritable_lvalue_p (lhs))
  		    {
! 		      decl = get_base_address (lhs);
! 		      if (DECL_P (decl))
! 			bitmap_set_bit (not_reg_needs, DECL_UID (decl));
  		    }
  		}
  	      for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
Index: gcc/testsuite/gcc.dg/torture/pr47621.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/torture/pr47621.c	2011-02-07 11:29:43.000000000 +0100
***************
*** 0 ****
--- 1,14 ----
+ /* { dg-do run } */
+ 
+ extern void abort (void);
+ 
+ int
+ main (void)
+ {
+   int data = 1;
+   struct ptr { int val; } *ptr = (struct ptr *) &data;
+   ptr->val = 0;
+   if (data != 0)
+     abort ();
+   return 0;
+ }


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