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][committed] Fix PR27226


Bootstrapped and tested on x86_64-unknown-linux-gnu.

Committed, as approved by Roger.

Richard.


2006-09-01  J"orn Rennecke  <joern.rennecke@st.com>
	Richard Guenther  <rguenther@suse.de>
	Adam Nemet  <anemet@caviumnetworks.com>

	PR middle-end/27226
	* builtins.c (get_pointer_alignment): Handle more forms
	of base addresses that can be used to derive more precise
	information about alignment.

	* gcc.target/mips/memcpy-1.c: New testcase.
	* gcc.dg/pr27226.c: Likewise.


Index: builtins.c
===================================================================
*** builtins.c	(revision 116634)
--- builtins.c	(working copy)
*************** get_pointer_alignment (tree exp, unsigne
*** 275,290 ****
  	  /* See what we are pointing at and look at its alignment.  */
  	  exp = TREE_OPERAND (exp, 0);
  	  inner = max_align;
! 	  while (handled_component_p (exp))
  	    {
! 	      /* Fields in a structure can be packed, honor DECL_ALIGN
! 		 of the FIELD_DECL.  For all other references the conservative
! 		 alignment is the element type alignment.  */
! 	      if (TREE_CODE (exp) == COMPONENT_REF)
! 		inner = MIN (inner, DECL_ALIGN (TREE_OPERAND (exp, 1)));
! 	      else
! 		inner = MIN (inner, TYPE_ALIGN (TREE_TYPE (exp)));
! 	      exp = TREE_OPERAND (exp, 0);
  	    }
  	  if (TREE_CODE (exp) == FUNCTION_DECL)
  	    align = FUNCTION_BOUNDARY;
--- 275,318 ----
  	  /* See what we are pointing at and look at its alignment.  */
  	  exp = TREE_OPERAND (exp, 0);
  	  inner = max_align;
! 	  if (handled_component_p (exp))
  	    {
! 	      HOST_WIDE_INT bitsize, bitpos;
! 	      tree offset;
! 	      enum machine_mode mode; 
! 	      int unsignedp, volatilep;
! 
! 	      exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
! 					 &mode, &unsignedp, &volatilep, true);
! 	      if (bitpos)
! 		inner = MIN (inner, (unsigned) (bitpos & -bitpos));
! 	      if (offset && TREE_CODE (offset) == PLUS_EXPR
! 		  && host_integerp (TREE_OPERAND (offset, 1), 1))
! 	        {
! 		  /* Any overflow in calculating offset_bits won't change
! 		     the alignment.  */
! 		  unsigned offset_bits
! 		    = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
! 		       * BITS_PER_UNIT);
! 
! 		  if (offset_bits)
! 		    inner = MIN (inner, (offset_bits & -offset_bits));
! 		  offset = TREE_OPERAND (offset, 0);
! 		}
! 	      if (offset && TREE_CODE (offset) == MULT_EXPR
! 		  && host_integerp (TREE_OPERAND (offset, 1), 1))
! 	        {
! 		  /* Any overflow in calculating offset_factor won't change
! 		     the alignment.  */
! 		  unsigned offset_factor
! 		    = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
! 		       * BITS_PER_UNIT);
! 
! 		  if (offset_factor)
! 		    inner = MIN (inner, (offset_factor & -offset_factor));
! 		}
! 	      else if (offset)
! 		inner = MIN (inner, BITS_PER_UNIT);
  	    }
  	  if (TREE_CODE (exp) == FUNCTION_DECL)
  	    align = FUNCTION_BOUNDARY;
*************** get_pointer_alignment (tree exp, unsigne
*** 294,299 ****
--- 322,330 ----
  	  else if (CONSTANT_CLASS_P (exp))
  	    align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
  #endif
+ 	  else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
+ 		   || TREE_CODE (exp) == INDIRECT_REF)
+ 	    align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
  	  else
  	    align = MIN (align, inner);
  	  return MIN (align, max_align);
Index: testsuite/gcc.target/mips/memcpy-1.c
===================================================================
*** testsuite/gcc.target/mips/memcpy-1.c	(revision 0)
--- testsuite/gcc.target/mips/memcpy-1.c	(revision 0)
***************
*** 0 ****
--- 1,19 ----
+ /* { dg-do compile } */
+ /* { dg-mips-options "-O2" } */
+ /* { dg-final { scan-assembler-not "\tlbu\t" } } */
+ 
+ #include <string.h>
+ 
+ char c[10];
+ 
+ void
+ f1 ()
+ {
+   memcpy (c, "123456", 6);
+ }
+ 
+ void
+ f2 ()
+ {
+   memcpy (c, &"12345678"[2], 6);
+ }
Index: testsuite/gcc.dg/pr27226.c
===================================================================
*** testsuite/gcc.dg/pr27226.c	(revision 0)
--- testsuite/gcc.dg/pr27226.c	(revision 0)
***************
*** 0 ****
--- 1,19 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2" } */
+ 
+ char *strcpy (char *, const char *);
+ 
+ extern void g ();
+ 
+ f ()
+ {
+   struct {
+     int i;
+     char str[31];
+   } s;
+ 
+   strcpy (s.str, "text text text text text text text text");
+   g (s.str);
+ }
+ 
+ /* { dg-final { scan-assembler-not "memcpy" } } */


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