From 05931b005878841524d6cb261e433fce4f04c7a6 Mon Sep 17 00:00:00 2001 From: rguenth Date: Sat, 15 Nov 2008 15:37:57 +0000 Subject: [PATCH] 2008-11-15 Richard Guenther 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 --- gcc/ChangeLog | 6 + gcc/testsuite/ChangeLog | 6 + gcc/testsuite/gcc.c-torture/execute/pr38051.c | 205 ++++++++++++++++++++++++++ gcc/tree-ssa-alias.c | 35 +++-- 4 files changed, 237 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr38051.c 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 + + PR tree-optimization/38051 + * tree-ssa-alias.c (update_alias_info_1): Manually find + written variables. + 2008-11-15 Joshua Kinard * 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 + Jakub Jelinek + + PR tree-optimization/38051 + * gcc.c-torture/execute/pr38051.c: New testcase. + 2008-11-15 Joshua Kinard Richard Sandiford 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); + } } } -- 2.11.4.GIT