This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix the one entry mem{{,p}cpy,move,set} optimization aliasing issues (PR middle-end/29272)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 29 Sep 2006 03:50:35 -0400
- Subject: [PATCH] Fix the one entry mem{{,p}cpy,move,set} optimization aliasing issues (PR middle-end/29272)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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