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 PR45212


When Eric fixed set_mem_attributes_minus_bitpos not to use the
alias type of MEM_REFs for alignment but the value type we
forgot to move alignment adjustment by the MEM_REF offset
just to the cases we use the alignment of the contained object.

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

Richard.

2010-08-09  Richard Guenther  <rguenther@suse.de>

	PR middle-end/45212
	* emit-rtl.c (set_mem_attributes_minus_bitpos): Adjust
	alignment from MEM_REF offset only if we took it from the
	base object.

	* gcc.target/i386/pr24178.c: New testcase.

Index: gcc/emit-rtl.c
===================================================================
*** gcc/emit-rtl.c	(revision 163027)
--- gcc/emit-rtl.c	(working copy)
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1587,1615 ****
    else if (TREE_CODE (t) == MEM_REF)
      {
        tree op0 = TREE_OPERAND (t, 0);
!       unsigned HOST_WIDE_INT aoff = BITS_PER_UNIT;
!       if (host_integerp (TREE_OPERAND (t, 1), 1))
  	{
! 	  unsigned HOST_WIDE_INT ioff = TREE_INT_CST_LOW (TREE_OPERAND (t, 1));
! 	  aoff = (ioff & -ioff) * BITS_PER_UNIT;
! 	}
!       if (TREE_CODE (op0) == ADDR_EXPR && DECL_P (TREE_OPERAND (op0, 0)))
! 	align = MAX (align, DECL_ALIGN (TREE_OPERAND (op0, 0)));
!       else if (TREE_CODE (op0) == ADDR_EXPR
! 	       && CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)))
! 	{
! 	  align = TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (op0, 0)));
  #ifdef CONSTANT_ALIGNMENT
! 	  align = CONSTANT_ALIGNMENT (TREE_OPERAND (op0, 0), align);
  #endif
  	}
        else
  	/* ??? This isn't fully correct, we can't set the alignment from the
  	   type in all cases.  */
  	align = MAX (align, TYPE_ALIGN (type));
- 
-       if (!integer_zerop (TREE_OPERAND (t, 1)) && aoff < align)
- 	align = aoff;
      }
  
    else if (TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
--- 1587,1617 ----
    else if (TREE_CODE (t) == MEM_REF)
      {
        tree op0 = TREE_OPERAND (t, 0);
!       if (TREE_CODE (op0) == ADDR_EXPR
! 	  && (DECL_P (TREE_OPERAND (op0, 0))
! 	      || CONSTANT_CLASS_P (TREE_OPERAND (op0, 0))))
  	{
! 	  if (DECL_P (TREE_OPERAND (op0, 0)))
! 	    align = DECL_ALIGN (TREE_OPERAND (op0, 0));
! 	  else if (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)))
! 	    {
! 	      align = TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (op0, 0)));
  #ifdef CONSTANT_ALIGNMENT
! 	      align = CONSTANT_ALIGNMENT (TREE_OPERAND (op0, 0), align);
  #endif
+ 	    }
+ 	  if (TREE_INT_CST_LOW (TREE_OPERAND (t, 1)) != 0)
+ 	    {
+ 	      unsigned HOST_WIDE_INT ioff
+ 		= TREE_INT_CST_LOW (TREE_OPERAND (t, 1));
+ 	      unsigned HOST_WIDE_INT aoff = (ioff & -ioff) * BITS_PER_UNIT;
+ 	      align = MIN (aoff, align);
+ 	    }
  	}
        else
  	/* ??? This isn't fully correct, we can't set the alignment from the
  	   type in all cases.  */
  	align = MAX (align, TYPE_ALIGN (type));
      }
  
    else if (TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
Index: gcc/testsuite/gcc.target/i386/pr24178.c
===================================================================
*** gcc/testsuite/gcc.target/i386/pr24178.c	(revision 0)
--- gcc/testsuite/gcc.target/i386/pr24178.c	(revision 0)
***************
*** 0 ****
--- 1,16 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-rtl-expand" } */
+ 
+ struct S {
+     int l;
+     unsigned char c;
+ };
+ unsigned long f(unsigned char *p10) {
+     struct S *p = (struct S *) (p10 + 10);
+     return p->c;
+ }
+ 
+ /* The p->c memory access should have alignment of 4 bytes.  */
+ 
+ /* { dg-final { scan-rtl-dump "MEM\[^\\n\]*A32" "expand" } } */
+ /* { dg-final { cleanup-rtl-dump "expand" } } */


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