This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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);
! 	}
      }
  }
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]