Commit 63894637 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/38051 (Miscompilation of glibc's memcmp)

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.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>

From-SVN: r141887
parent ee9a72e5
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> 2008-11-15 Joshua Kinard <kumba@gentoo.org>
* doc/invoke.texi (-mfix-r10000): Document. * doc/invoke.texi (-mfix-r10000): Document.
......
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> 2008-11-15 Joshua Kinard <kumba@gentoo.org>
Richard Sandiford <rdsandiford@goolemail.com> Richard Sandiford <rdsandiford@goolemail.com>
......
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;
}
...@@ -2667,6 +2667,17 @@ update_alias_info_1 (gimple stmt, struct alias_info *ai) ...@@ -2667,6 +2667,17 @@ update_alias_info_1 (gimple stmt, struct alias_info *ai)
mem_ref_stats->num_mem_stmts++; 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 /* Notice that we only update memory reference stats for symbols
loaded and stored by the statement if the statement does not loaded and stored by the statement if the statement does not
contain pointer dereferences and it is not a call/asm site. 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) ...@@ -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 dereferences (e.g., MEMORY_VAR = *PTR) or if a call site has
memory symbols in its argument list, but these cases do not memory symbols in its argument list, but these cases do not
occur so frequently as to constitute a serious problem. */ 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 if (!stmt_dereferences_ptr_p
&& gimple_loaded_syms (stmt)
&& stmt_escape_type != ESCAPE_TO_CALL && stmt_escape_type != ESCAPE_TO_CALL
&& stmt_escape_type != ESCAPE_TO_PURE_CONST && stmt_escape_type != ESCAPE_TO_PURE_CONST
&& stmt_escape_type != ESCAPE_TO_ASM) && 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);
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment