summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-11-15 15:37:57 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-11-15 15:37:57 +0000
commit05931b005878841524d6cb261e433fce4f04c7a6 (patch)
tree7662ff5594a836763616e0117a399806b2707628
parent749bd779032567a20ca707479d73a68311572d54 (diff)
downloadgcc-05931b005878841524d6cb261e433fce4f04c7a6.tar.gz
2008-11-15 Richard Guenther <rguenther@suse.de>
PR tree-optimization/38051 * tree-ssa-alias.c (update_alias_info_1): Manually find written variables. * gcc.c-torture/execute/pr38051.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141887 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr38051.c205
-rw-r--r--gcc/tree-ssa-alias.c35
4 files changed, 237 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a4e4609f57d..2e34022cf38 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2008-11-15 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/38051
+ * tree-ssa-alias.c (update_alias_info_1): Manually find
+ written variables.
+
2008-11-15 Joshua Kinard <kumba@gentoo.org>
* doc/invoke.texi (-mfix-r10000): Document.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1a4a0d29fe2..dac465123b1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2008-11-15 Richard Guenther <rguenther@suse.de>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/38051
+ * gcc.c-torture/execute/pr38051.c: New testcase.
+
2008-11-15 Joshua Kinard <kumba@gentoo.org>
Richard Sandiford <rdsandiford@goolemail.com>
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr38051.c b/gcc/testsuite/gcc.c-torture/execute/pr38051.c
new file mode 100644
index 00000000000..3437f730667
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr38051.c
@@ -0,0 +1,205 @@
+typedef __SIZE_TYPE__ size_t;
+static int mymemcmp1 (unsigned long int, unsigned long int)
+ __attribute__ ((__nothrow__));
+
+__inline static int
+mymemcmp1 (unsigned long int a, unsigned long int b)
+{
+ long int srcp1 = (long int) &a;
+ long int srcp2 = (long int) &b;
+ unsigned long int a0, b0;
+ do
+ {
+ a0 = ((unsigned char *) srcp1)[0];
+ b0 = ((unsigned char *) srcp2)[0];
+ srcp1 += 1;
+ srcp2 += 1;
+ }
+ while (a0 == b0);
+ return a0 - b0;
+}
+
+static int mymemcmp2 (long, long, size_t) __attribute__ ((__nothrow__));
+
+static int
+mymemcmp2 (long int srcp1, long int srcp2, size_t len)
+{
+ unsigned long int a0, a1;
+ unsigned long int b0, b1;
+ switch (len % 4)
+ {
+ default:
+ case 2:
+ a0 = ((unsigned long int *) srcp1)[0];
+ b0 = ((unsigned long int *) srcp2)[0];
+ srcp1 -= 2 * (sizeof (unsigned long int));
+ srcp2 -= 2 * (sizeof (unsigned long int));
+ len += 2;
+ goto do1;
+ case 3:
+ a1 = ((unsigned long int *) srcp1)[0];
+ b1 = ((unsigned long int *) srcp2)[0];
+ srcp1 -= (sizeof (unsigned long int));
+ srcp2 -= (sizeof (unsigned long int));
+ len += 1;
+ goto do2;
+ case 0:
+ if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
+ return 0;
+ a0 = ((unsigned long int *) srcp1)[0];
+ b0 = ((unsigned long int *) srcp2)[0];
+ goto do3;
+ case 1:
+ a1 = ((unsigned long int *) srcp1)[0];
+ b1 = ((unsigned long int *) srcp2)[0];
+ srcp1 += (sizeof (unsigned long int));
+ srcp2 += (sizeof (unsigned long int));
+ len -= 1;
+ if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
+ goto do0;
+ }
+ do
+ {
+ a0 = ((unsigned long int *) srcp1)[0];
+ b0 = ((unsigned long int *) srcp2)[0];
+ if (a1 != b1)
+ return mymemcmp1 ((a1), (b1));
+ do3:
+ a1 = ((unsigned long int *) srcp1)[1];
+ b1 = ((unsigned long int *) srcp2)[1];
+ if (a0 != b0)
+ return mymemcmp1 ((a0), (b0));
+ do2:
+ a0 = ((unsigned long int *) srcp1)[2];
+ b0 = ((unsigned long int *) srcp2)[2];
+ if (a1 != b1)
+ return mymemcmp1 ((a1), (b1));
+ do1:
+ a1 = ((unsigned long int *) srcp1)[3];
+ b1 = ((unsigned long int *) srcp2)[3];
+ if (a0 != b0)
+ return mymemcmp1 ((a0), (b0));
+ srcp1 += 4 * (sizeof (unsigned long int));
+ srcp2 += 4 * (sizeof (unsigned long int));
+ len -= 4;
+ }
+ while (len != 0);
+do0:
+ if (a1 != b1)
+ return mymemcmp1 ((a1), (b1));
+ return 0;
+}
+
+static int mymemcmp3 (long, long, size_t) __attribute__ ((__nothrow__));
+
+static int
+mymemcmp3 (long int srcp1, long int srcp2, size_t len)
+{
+ unsigned long int a0, a1, a2, a3;
+ unsigned long int b0, b1, b2, b3;
+ unsigned long int x;
+ int shl, shr;
+ shl = 8 * (srcp1 % (sizeof (unsigned long int)));
+ shr = 8 * (sizeof (unsigned long int)) - shl;
+ srcp1 &= -(sizeof (unsigned long int));
+ switch (len % 4)
+ {
+ default:
+ case 2:
+ a1 = ((unsigned long int *) srcp1)[0];
+ a2 = ((unsigned long int *) srcp1)[1];
+ b2 = ((unsigned long int *) srcp2)[0];
+ srcp1 -= 1 * (sizeof (unsigned long int));
+ srcp2 -= 2 * (sizeof (unsigned long int));
+ len += 2;
+ goto do1;
+ case 3:
+ a0 = ((unsigned long int *) srcp1)[0];
+ a1 = ((unsigned long int *) srcp1)[1];
+ b1 = ((unsigned long int *) srcp2)[0];
+ srcp2 -= 1 * (sizeof (unsigned long int));
+ len += 1;
+ goto do2;
+ case 0:
+ if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
+ return 0;
+ a3 = ((unsigned long int *) srcp1)[0];
+ a0 = ((unsigned long int *) srcp1)[1];
+ b0 = ((unsigned long int *) srcp2)[0];
+ srcp1 += 1 * (sizeof (unsigned long int));
+ goto do3;
+ case 1:
+ a2 = ((unsigned long int *) srcp1)[0];
+ a3 = ((unsigned long int *) srcp1)[1];
+ b3 = ((unsigned long int *) srcp2)[0];
+ srcp1 += 2 * (sizeof (unsigned long int));
+ srcp2 += 1 * (sizeof (unsigned long int));
+ len -= 1;
+ if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
+ goto do0;
+ }
+ do
+ {
+ a0 = ((unsigned long int *) srcp1)[0];
+ b0 = ((unsigned long int *) srcp2)[0];
+ x = (((a2) >> (shl)) | ((a3) << (shr)));
+ if (x != b3)
+ return mymemcmp1 ((x), (b3));
+ do3:
+ a1 = ((unsigned long int *) srcp1)[1];
+ b1 = ((unsigned long int *) srcp2)[1];
+ x = (((a3) >> (shl)) | ((a0) << (shr)));
+ if (x != b0)
+ return mymemcmp1 ((x), (b0));
+ do2:
+ a2 = ((unsigned long int *) srcp1)[2];
+ b2 = ((unsigned long int *) srcp2)[2];
+ x = (((a0) >> (shl)) | ((a1) << (shr)));
+ if (x != b1)
+ return mymemcmp1 ((x), (b1));
+ do1:
+ a3 = ((unsigned long int *) srcp1)[3];
+ b3 = ((unsigned long int *) srcp2)[3];
+ x = (((a1) >> (shl)) | ((a2) << (shr)));
+ if (x != b2)
+ return mymemcmp1 ((x), (b2));
+ srcp1 += 4 * (sizeof (unsigned long int));
+ srcp2 += 4 * (sizeof (unsigned long int));
+ len -= 4;
+ }
+ while (len != 0);
+do0:
+ x = (((a2) >> (shl)) | ((a3) << (shr)));
+ if (x != b3)
+ return mymemcmp1 ((x), (b3));
+ return 0;
+}
+
+__attribute__ ((noinline))
+int mymemcmp (const void *s1, const void *s2, size_t len)
+{
+ unsigned long int a0;
+ unsigned long int b0;
+ long int srcp1 = (long int) s1;
+ long int srcp2 = (long int) s2;
+ if (srcp1 % (sizeof (unsigned long int)) == 0)
+ return mymemcmp2 (srcp1, srcp2, len / (sizeof (unsigned long int)));
+ else
+ return mymemcmp3 (srcp1, srcp2, len / (sizeof (unsigned long int)));
+}
+
+char buf[256] __attribute__((aligned (16)));
+char buf2[256] __attribute__((aligned (16)));
+
+int
+main (void)
+{
+ __builtin_memcpy (buf + 9,
+"\x1\x37\x82\xa7\x55\x49\x9d\xbf\xf8\x44\xb6\x55\x17\x8e\xf9", 15);
+ __builtin_memcpy (buf2 + 24,
+"\x1\x37\x82\xa7\x55\x49\xd0\xf3\xb7\x2a\x6d\x23\x71\x49\x6a", 15);
+ if (mymemcmp (buf + 9, buf2 + 24, 33) != -51)
+ __builtin_abort ();
+ return 0;
+}
+
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 655056b53f7..83800ed5722 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2667,6 +2667,17 @@ update_alias_info_1 (gimple stmt, struct alias_info *ai)
mem_ref_stats->num_mem_stmts++;
+ /* Add all decls written to to the list of written variables. */
+ if (gimple_has_lhs (stmt)
+ && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME)
+ {
+ tree lhs = gimple_get_lhs (stmt);
+ while (handled_component_p (lhs))
+ lhs = TREE_OPERAND (lhs, 0);
+ if (DECL_P (lhs))
+ pointer_set_insert (ai->written_vars, lhs);
+ }
+
/* Notice that we only update memory reference stats for symbols
loaded and stored by the statement if the statement does not
contain pointer dereferences and it is not a call/asm site.
@@ -2689,25 +2700,19 @@ update_alias_info_1 (gimple stmt, struct alias_info *ai)
dereferences (e.g., MEMORY_VAR = *PTR) or if a call site has
memory symbols in its argument list, but these cases do not
occur so frequently as to constitute a serious problem. */
- if (gimple_stored_syms (stmt))
- EXECUTE_IF_SET_IN_BITMAP (gimple_stored_syms (stmt), 0, i, bi)
- {
- tree sym = referenced_var (i);
- pointer_set_insert (ai->written_vars, sym);
- if (!stmt_dereferences_ptr_p
- && stmt_escape_type != ESCAPE_TO_CALL
- && stmt_escape_type != ESCAPE_TO_PURE_CONST
- && stmt_escape_type != ESCAPE_TO_ASM)
- update_mem_sym_stats_from_stmt (sym, stmt, 0, 1);
- }
-
if (!stmt_dereferences_ptr_p
- && gimple_loaded_syms (stmt)
&& stmt_escape_type != ESCAPE_TO_CALL
&& stmt_escape_type != ESCAPE_TO_PURE_CONST
&& stmt_escape_type != ESCAPE_TO_ASM)
- EXECUTE_IF_SET_IN_BITMAP (gimple_loaded_syms (stmt), 0, i, bi)
- update_mem_sym_stats_from_stmt (referenced_var (i), stmt, 1, 0);
+ {
+ if (gimple_stored_syms (stmt))
+ EXECUTE_IF_SET_IN_BITMAP (gimple_stored_syms (stmt), 0, i, bi)
+ update_mem_sym_stats_from_stmt (referenced_var (i), stmt, 0, 1);
+
+ if (gimple_loaded_syms (stmt))
+ EXECUTE_IF_SET_IN_BITMAP (gimple_loaded_syms (stmt), 0, i, bi)
+ update_mem_sym_stats_from_stmt (referenced_var (i), stmt, 1, 0);
+ }
}
}