[PATCH][committed] Fix PR27226
Richard Guenther
rguenther@suse.de
Fri Sep 1 20:22:00 GMT 2006
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" } } */
More information about the Gcc-patches
mailing list