This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR45212
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 9 Aug 2010 13:41:33 +0200 (CEST)
- Subject: [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" } } */