diff options
author | J"orn Rennecke <joern.rennecke@st.com> | 2006-09-01 20:25:34 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2006-09-01 20:25:34 +0000 |
commit | 537b8a357cd1c24042180937b030bce255042d23 (patch) | |
tree | 73e61e20e7b99a9069c8edce11782f70fa49d2da | |
parent | cd709ec369752db0a7c8f9109e8faf2bc87f6c72 (diff) | |
download | gcc-537b8a357cd1c24042180937b030bce255042d23.zip gcc-537b8a357cd1c24042180937b030bce255042d23.tar.gz gcc-537b8a357cd1c24042180937b030bce255042d23.tar.bz2 |
re PR middle-end/27226 (Compiler looses track of alignment for emit_block_move)
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.
Co-Authored-By: Adam Nemet <anemet@caviumnetworks.com>
Co-Authored-By: Richard Guenther <rguenther@suse.de>
From-SVN: r116641
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/builtins.c | 49 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr27226.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/memcpy-1.c | 19 |
5 files changed, 95 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 242104b..077b1c3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +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. + 2006-09-01 Jason Merrill <jason@redhat.com> PR c++/28899 diff --git a/gcc/builtins.c b/gcc/builtins.c index 47c61cd..4aff7d0 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 530c23e..e4210b8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2006-09-01 J"orn Rennecke <joern.rennecke@st.com> + Richard Guenther <rguenther@suse.de> + Adam Nemet <anemet@caviumnetworks.com> + + PR middle-end/27226 + * gcc.target/mips/memcpy-1.c: New testcase. + * gcc.dg/pr27226.c: Likewise. + 2006-09-01 Nathan Sidwell <nathan@codesourcery.com> PR c++/28705 diff --git a/gcc/testsuite/gcc.dg/pr27226.c b/gcc/testsuite/gcc.dg/pr27226.c new file mode 100644 index 0000000..df77a8c --- /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 0000000..4e50b20 --- /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 <string.h> + +char c[10]; + +void +f1 () +{ + memcpy (c, "123456", 6); +} + +void +f2 () +{ + memcpy (c, &"12345678"[2], 6); +} |