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 the one entry mem{{,p}cpy,move,set} optimization aliasing issues (PR middle-end/29272)


Hi!

While the PR29272 testcase is IMHO violating the strict aliasing rules
(my reading of 6.5 is that for the heap object the first memcpy call gives the
object struct Node * effective type, so it shouldn't then be accessed as
int), I believe it is possible to come up with a standard conforming
testcase for this (e.g. when the object is not allocated, we access it
mostly through its original type but additionall with memcpy through an
aliasing incompatible pointer).  The following patch restricts the optimization
only to addresses of variables or components thereof, in which case it is clear
what the effective type of the object is and that doesn't ever change,
so I believe it is ok to use object's effective type's alias set for the
copy.
So, after this patch we only optimize e.g.:
int i; float f;
struct S { int i; } s, *p;
...
memcpy (&i, &f, sizeof (i));
memcpy (&s.i, &f, sizeof (s.i));
but not e.g.
memcpy (&p->i, &f, sizeof (p->i));
I think we could optimize the latter if we arranged for the store (and/or
read) to be done in alias set 0, but am not sure how exactly to arrange it
now.

Bootstrapped/regtested on 7 ilnux arches.
Ok for trunk?

2006-09-29  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/29272
	* builtins.c (fold_builtin_memset, fold_builtin_memory_op): Restrict
	single entry optimization to variables and components thereof.

--- gcc/builtins.c.jj	2006-09-22 10:29:55.000000000 +0200
+++ gcc/builtins.c	2006-09-28 20:31:30.000000000 +0200
@@ -7905,7 +7905,7 @@ fold_builtin_exponent (tree fndecl, tree
 static tree
 fold_builtin_memset (tree arglist, tree type, bool ignore)
 {
-  tree dest, c, len, var, ret;
+  tree dest, c, len, var, ret, inner;
   unsigned HOST_WIDE_INT length, cval;
 
   if (!validate_arglist (arglist,
@@ -7939,6 +7939,15 @@ fold_builtin_memset (tree arglist, tree 
       && !POINTER_TYPE_P (TREE_TYPE (var)))
     return 0;
 
+  /* If var is a VAR_DECL or a component thereof,
+     we can use its alias set, otherwise we'd need to make
+     sure we go through alias set 0.  */
+  inner = var;
+  while (handled_component_p (inner))
+    inner = TREE_OPERAND (inner, 0);
+  if (! SSA_VAR_P (inner))
+    return 0;
+
   length = tree_low_cst (len, 1);
   if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
       || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
@@ -8009,7 +8018,7 @@ fold_builtin_bzero (tree arglist, bool i
 static tree
 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
 {
-  tree dest, src, len, destvar, srcvar, expr;
+  tree dest, src, len, destvar, srcvar, expr, inner;
   unsigned HOST_WIDE_INT length;
 
   if (! validate_arglist (arglist,
@@ -8050,6 +8059,15 @@ fold_builtin_memory_op (tree arglist, tr
 	  && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar)))
 	return 0;
 
+      /* If destvar is a VAR_DECL or a component thereof,
+	 we can use its alias set, otherwise we'd need to make
+	 sure we go through alias set 0.  */
+      inner = destvar;
+      while (handled_component_p (inner))
+	inner = TREE_OPERAND (inner, 0);
+      if (! SSA_VAR_P (inner))
+	return 0;
+
       srcvar = src;
       STRIP_NOPS (srcvar);
       if (TREE_CODE (srcvar) != ADDR_EXPR)
@@ -8064,6 +8082,15 @@ fold_builtin_memory_op (tree arglist, tr
 	  && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar)))
 	return 0;
 
+      /* If srcvar is a VAR_DECL or a component thereof,
+	 we can use its alias set, otherwise we'd need to make
+	 sure we go through alias set 0.  */
+      inner = srcvar;
+      while (handled_component_p (inner))
+	inner = TREE_OPERAND (inner, 0);
+      if (! SSA_VAR_P (inner))
+	return 0;
+
       length = tree_low_cst (len, 1);
       if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length
 	  || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT

	Jakub


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