Fix 22591

Diego Novillo dnovillo@redhat.com
Tue Jul 26 20:03:00 GMT 2005


We were taking an invalid shortcut inside may_alias_p.  If the
pointer and the variable were pointers of the same alias set, we
were thinking that the pointer could not possibly point to the
variable.

This is wrong, as this PR shows, pointers inside structures break
this predicate.  Unfortunately, this same weak predicate was
papering over another problem exposed in tree-ssa/20030807-7.c,
where a parameter that is never modified is thought to point to a
local variable.

I had to XFAIL this test case and create a PR for it (23086).
With any luck, we could address this new PR for 4.1 without major
changes, but I'll have to think about it a bit.  In the meantime,
the short cut needs to disappear because it can lead to wrong
code generation.


Bootstrapped and tested x86, x86-64, ia64, ppc64.




	PR 22591
	* tree-ssa-alias.c (may_alias_p): Remove shortcut that tests
	whether a pointer of type T * may point to objects of type T *.


testsuite/ChangeLog

	* gcc.dg/tree-ssa/pr22591.c: New test.
	* gcc.dg/tree-ssa/20030807-7.c: XFAIL everywhere.

Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v
retrieving revision 2.107
diff -d -u -p -r2.107 tree-ssa-alias.c
--- tree-ssa-alias.c	25 Jul 2005 12:04:50 -0000	2.107
+++ tree-ssa-alias.c	26 Jul 2005 19:50:17 -0000
@@ -1511,23 +1511,6 @@ may_alias_p (tree ptr, HOST_WIDE_INT mem
 
   alias_stats.tbaa_queries++;
 
-  /* If VAR is a pointer with the same alias set as PTR, then dereferencing
-     PTR can't possibly affect VAR.  Note, that we are specifically testing
-     for PTR's alias set here, not its pointed-to type.  We also can't
-     do this check with relaxed aliasing enabled.  */
-  if (POINTER_TYPE_P (TREE_TYPE (var))
-      && var_alias_set != 0
-      && mem_alias_set != 0)
-    {
-      HOST_WIDE_INT ptr_alias_set = get_alias_set (ptr);
-      if (ptr_alias_set == var_alias_set)
-	{
-	  alias_stats.alias_noalias++;
-	  alias_stats.tbaa_resolved++;
-	  return false;
-	}
-    }
-
   /* If the alias sets don't conflict then MEM cannot alias VAR.  */
   if (!alias_sets_conflict_p (mem_alias_set, var_alias_set))
     {
Index: testsuite/gcc.dg/tree-ssa/20030807-7.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/tree-ssa/20030807-7.c,v
retrieving revision 1.4
diff -d -u -p -r1.4 20030807-7.c
--- testsuite/gcc.dg/tree-ssa/20030807-7.c	31 Mar 2005 18:34:15 -0000	1.4
+++ testsuite/gcc.dg/tree-ssa/20030807-7.c	26 Jul 2005 19:50:22 -0000
@@ -34,5 +34,5 @@ simplify_condition (cond_p)
 
 /* There should be exactly one IF conditional.  TBAA is not able to 
    determine that 'decl' and 'cond' can't alias.  */
-/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
+/* { dg-final { scan-tree-dump-times "if " 1 "dom3" { xfail *-*-* } } } */
 /* { dg-final { cleanup-tree-dump "dom3" } } */
Index: testsuite/gcc.dg/tree-ssa/pr22591.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/pr22591.c
diff -N testsuite/gcc.dg/tree-ssa/pr22591.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/tree-ssa/pr22591.c	26 Jul 2005 19:50:22 -0000
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+void abort (); 
+ 
+typedef struct _Node 
+{ 
+  struct _Node *next, *prev; 
+} Node; 
+ 
+void __attribute__ ((noinline)) append (Node * q, Node * p) 
+{ 
+  p->next = q; 
+  p->prev = q; 
+  q->next = p; 
+  q->prev = p; 
+} 
+ 
+inline void 
+swap (Node ** a, Node ** b) 
+{ 
+  Node *tmp = *a; 
+  *a = *b; 
+  *b = tmp; 
+} 
+ 
+/* Miscompilation seems to happen here. If one removes the if condition 
+   (which should be true) the program works fine.  */ 
+void 
+ListSwap (Node * x, Node * y) 
+{ 
+  Node *tmp; 
+  if (x->next) 
+    { 
+      swap (&x->next, &y->next); 
+      swap (&x->prev, &y->prev); 
+      x->next->prev = x->prev->next = x; 
+      y->next->prev = y->prev->next = y; 
+    } 
+} 
+ 
+int 
+main () 
+{ 
+  Node A, A1, B, B1; 
+ 
+  append (&A, &A1); 
+  append (&B, &B1); 
+ 
+  ListSwap (&A, &B); 
+ 
+  if (&A != A.next->prev) 
+    abort (); 
+
+  return 0;
+}



More information about the Gcc-patches mailing list