aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@st.com>2006-09-01 20:25:34 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2006-09-01 20:25:34 +0000
commit537b8a357cd1c24042180937b030bce255042d23 (patch)
tree73e61e20e7b99a9069c8edce11782f70fa49d2da
parentcd709ec369752db0a7c8f9109e8faf2bc87f6c72 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/builtins.c49
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/pr27226.c19
-rw-r--r--gcc/testsuite/gcc.target/mips/memcpy-1.c19
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);
+}