This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix the one entry mem{{,p}cpy,move,set} optimization aliasing issues (PR middle-end/29272)
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Diego Novillo <dnovillo at redhat dot com>, Ian Lance Taylor <iant at google dot com>, gcc-patches at gcc dot gnu dot org
- Date: Sat, 7 Oct 2006 09:57:30 +0200
- Subject: Re: [PATCH] Fix the one entry mem{{,p}cpy,move,set} optimization aliasing issues (PR middle-end/29272)
- References: <20060929075035.GQ20982@devserv.devel.redhat.com> <200610041508.13836.ebotcazou@adacore.com> <20061004134044.GV20982@devserv.devel.redhat.com>
> True, but that really doesn't make any difference.
Of course, the dereference is optimized out by the gimplifier.
You need to set the ref-all flag on p, since the problematic access is p->t:
foo (s)
{
struct T * D.1535;
struct T * p;
p = (struct T *) s;
D.1535 = t.t;
p->t = D.1535;
}
Aliasing rules are clearly violated after the memcpy optimization so p must be
ref-all for this to work. The Ada compiler would automatically set it upon
parsing the wild (unchecked) conversion:
p = (struct T *) s;
Minimal patch attached. In .gimple:
foo (s)
{
struct T * {ref-all} p.0;
struct T * D.1536;
struct T * p;
p = (struct T *) s;
p.0 = (struct T * {ref-all}) p;
D.1536 = t.t;
p.0->t = D.1536;
p.0 = (struct T * {ref-all}) p;
}
--
Eric Botcazou
Index: builtins.c
===================================================================
--- builtins.c (revision 117403)
+++ builtins.c (working copy)
@@ -7995,7 +7995,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,
@@ -8036,6 +8036,20 @@ 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 (TREE_CODE (inner) == INDIRECT_REF)
+ {
+ tree ref_all
+ = build_pointer_type_for_mode (TREE_TYPE (inner), ptr_mode, true);
+ TREE_OPERAND (inner, 0)
+ = fold_convert (ref_all, TREE_OPERAND (inner, 0));
+ }
+
srcvar = src;
STRIP_NOPS (srcvar);
if (TREE_CODE (srcvar) != ADDR_EXPR)