This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix 18291
- From: Diego Novillo <dnovillo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 1 Dec 2004 14:17:12 -0500
- Subject: Fix 18291
- Organization: Red Hat Canada
When a pointer Q_j is copy-propagated into another P_i, all uses
of P_i are rewritten to use Q_j and we call merge_alias_info to
make sure that Q_j has the appropriate name tags (needed to
propagate into INDIRECT_REF sites).
What we do for type tags is to make sure that both VAR_DECLs P
and Q have the same type tag. However, the same approach doesn't
work for name tags. We used to test that both P_i and Q_j had
the exact same name tag, but that is not necessarily right
because P_i and Q_j could actually be pointing to different
variables.
In this case, the pointed-to sets will never be completely
different, they will always intersect because we are reaching
this point after copy-propagation, so the two pointers must have
something in common.
So, if Q_j already has a name tag (i.e., it has been
dereferenced), we just continue to use it. Otherwise, we give
Q_j the same name tag that P_i had. There is no real need of
updating P_i's information, since the pointer is being discarded
by the propagation (the same is not true of the type-based
information, which is associated to the VAR_DECL not the
SSA_NAME).
Bootstrapped and tested x86, x86-64 and ppc.
Diego.
PR tree-optimization/18291
* tree-ssa-copy.c (merge_alias_info): Fix merging of
flow-sensitive alias information. If the new pointer has no
name tag, copy it from the original pointer. Otherwise, make
sure that the pointed-to sets have a common intersection.
testsuite/ChangeLog
PR tree-optimization/18291
* testsuite/gcc.c-torture/compile/pr18291.c: New test.
Index: tree-ssa-copy.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-copy.c,v
retrieving revision 2.20
diff -d -c -p -u -r2.20 tree-ssa-copy.c
--- tree-ssa-copy.c 14 Nov 2004 23:35:02 -0000 2.20
+++ tree-ssa-copy.c 1 Dec 2004 16:24:16 -0000
@@ -178,7 +178,6 @@ merge_alias_info (tree orig, tree new)
tree orig_sym = SSA_NAME_VAR (orig);
var_ann_t new_ann = var_ann (new_sym);
var_ann_t orig_ann = var_ann (orig_sym);
- struct ptr_info_def *new_ptr_info;
struct ptr_info_def *orig_ptr_info;
gcc_assert (POINTER_TYPE_P (TREE_TYPE (orig)));
@@ -203,18 +202,41 @@ merge_alias_info (tree orig, tree new)
else
gcc_assert (new_ann->type_mem_tag == orig_ann->type_mem_tag);
- /* Synchronize flow sensitive alias information. If both pointers
- had flow information and they are inconsistent, then something
- has gone wrong. */
- new_ptr_info = get_ptr_info (new);
- orig_ptr_info = get_ptr_info (orig);
+ orig_ptr_info = SSA_NAME_PTR_INFO (orig);
+ if (orig_ptr_info && orig_ptr_info->name_mem_tag)
+ {
+ struct ptr_info_def *new_ptr_info = get_ptr_info (new);
- if (new_ptr_info->name_mem_tag == NULL_TREE)
- memcpy (new_ptr_info, orig_ptr_info, sizeof (*new_ptr_info));
- else if (orig_ptr_info->name_mem_tag == NULL_TREE)
- memcpy (orig_ptr_info, new_ptr_info, sizeof (*orig_ptr_info));
- else if (orig_ptr_info->name_mem_tag != new_ptr_info->name_mem_tag)
- abort ();
+ if (new_ptr_info->name_mem_tag == NULL_TREE)
+ {
+ /* If ORIG had a name tag, it means that was dereferenced in
+ the code, and since pointer NEW will now replace every
+ occurrence of ORIG, we have to make sure that NEW has an
+ appropriate tag. If, NEW did not have a name tag, get it
+ from ORIG. */
+ memcpy (new_ptr_info, orig_ptr_info, sizeof (*new_ptr_info));
+ new_ptr_info->pt_vars = BITMAP_GGC_ALLOC ();
+ bitmap_copy (new_ptr_info->pt_vars, orig_ptr_info->pt_vars);
+ new_ptr_info->name_mem_tag = orig_ptr_info->name_mem_tag;
+ }
+ else
+ {
+ /* If NEW already had a name tag, nothing needs to be done.
+ Note that pointer NEW may actually have a different set of
+ pointed-to variables.
+
+ However, since NEW is being copy-propagated into ORIG, it must
+ always be true that the pointed-to set for pointer NEW is the
+ same, or a subset, of the pointed-to set for pointer ORIG. If
+ this isn't the case, we shouldn't have been able to do the
+ propagation of NEW into ORIG. */
+#if defined ENABLE_CHECKING
+ if (orig_ptr_info->pt_vars && new_ptr_info->pt_vars)
+ gcc_assert (bitmap_intersect_p (new_ptr_info->pt_vars,
+ orig_ptr_info->pt_vars));
+#endif
+ }
+ }
}
Index: testsuite/gcc.c-torture/compile/pr18291.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/pr18291.c
diff -N testsuite/gcc.c-torture/compile/pr18291.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.c-torture/compile/pr18291.c 1 Dec 2004 16:24:18 -0000
@@ -0,0 +1,12 @@
+int baz(int k2)
+{
+ int i, j, *p, k = 1, k1 = 0;
+ if (k2)
+ p = &j;
+ else
+ p = &i;
+ if (k1)
+ *p = 0 , p = &k;
+ *p = 1;
+ return k;
+}