From 537b8a357cd1c24042180937b030bce255042d23 Mon Sep 17 00:00:00 2001 From: "J\"orn Rennecke" Date: Fri, 1 Sep 2006 20:25:34 +0000 Subject: [PATCH] re PR middle-end/27226 (Compiler looses track of alignment for emit_block_move) 2006-09-01 J"orn Rennecke Richard Guenther Adam Nemet 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. Co-Authored-By: Adam Nemet Co-Authored-By: Richard Guenther From-SVN: r116641 --- gcc/ChangeLog | 9 +++++ gcc/builtins.c | 49 +++++++++++++++++++----- gcc/testsuite/ChangeLog | 8 ++++ gcc/testsuite/gcc.dg/pr27226.c | 19 +++++++++ gcc/testsuite/gcc.target/mips/memcpy-1.c | 19 +++++++++ 5 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr27226.c create mode 100644 gcc/testsuite/gcc.target/mips/memcpy-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 242104b35e7..077b1c32a53 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2006-09-01 J"orn Rennecke + Richard Guenther + Adam Nemet + + 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. + 2006-09-01 Jason Merrill PR c++/28899 diff --git a/gcc/builtins.c b/gcc/builtins.c index 47c61cdb133..4aff7d09809 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -275,16 +275,44 @@ get_pointer_alignment (tree exp, unsigned int max_align) /* See what we are pointing at and look at its alignment. */ exp = TREE_OPERAND (exp, 0); inner = max_align; - while (handled_component_p (exp)) + if (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); + 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; @@ -294,6 +322,9 @@ get_pointer_alignment (tree exp, unsigned int max_align) 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 530c23e2aae..e4210b84567 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2006-09-01 J"orn Rennecke + Richard Guenther + Adam Nemet + + PR middle-end/27226 + * gcc.target/mips/memcpy-1.c: New testcase. + * gcc.dg/pr27226.c: Likewise. + 2006-09-01 Nathan Sidwell PR c++/28705 diff --git a/gcc/testsuite/gcc.dg/pr27226.c b/gcc/testsuite/gcc.dg/pr27226.c new file mode 100644 index 00000000000..df77a8c9665 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr27226.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/mips/memcpy-1.c b/gcc/testsuite/gcc.target/mips/memcpy-1.c new file mode 100644 index 00000000000..4e50b20cda6 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/memcpy-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2" } */ +/* { dg-final { scan-assembler-not "\tlbu\t" } } */ + +#include + +char c[10]; + +void +f1 () +{ + memcpy (c, "123456", 6); +} + +void +f2 () +{ + memcpy (c, &"12345678"[2], 6); +} -- 2.30.2