This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR38051, alias partitioning related problem
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 15 Nov 2008 16:33:04 +0100 (CET)
- Subject: [PATCH] Fix PR38051, alias partitioning related problem
When partitioning partitions a variable in a second alias pass we
miss to consider that variable as written to because we ask the
stored_syms bitmap which only contains the MPT. This causes us
to disregard the variable for conflicts.
Fixed with the following - we can just look up the LHS decl ourselves.
Memory tags are marked as written by the pointer setup code, calls
and asms are handled by the fact that when we check the written
variables we also check the call clobber set.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
This problem is latent on the branch, but as a backport is non-trivial
I will not do it at this point.
Richard.
2008-11-07 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.
Index: gcc/testsuite/gcc.c-torture/execute/pr38051.c
===================================================================
*** gcc/testsuite/gcc.c-torture/execute/pr38051.c (revision 0)
--- gcc/testsuite/gcc.c-torture/execute/pr38051.c (revision 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;
+ }
+
Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c (revision 141714)
--- gcc/tree-ssa-alias.c (working copy)
*************** update_alias_info_1 (gimple stmt, struct
*** 2667,2672 ****
--- 2667,2683 ----
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.
*************** update_alias_info_1 (gimple stmt, struct
*** 2689,2713 ****
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);
}
}
--- 2700,2718 ----
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 (!stmt_dereferences_ptr_p
&& stmt_escape_type != ESCAPE_TO_CALL
&& stmt_escape_type != ESCAPE_TO_PURE_CONST
&& stmt_escape_type != ESCAPE_TO_ASM)
! {
! 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);
! }
}
}