This fixes PR52493 by robustifying the ptr_derefs_may_alias_p code.
It should handle being passed &MEM[0 + 0] (which is a missed folding,
to be addressed by a separate patch).  The simplification code always
should recurse, we failed to do so for the &MEM_REF case.

Bootstrap & regtest pending on x86_64-unknown-linux-gnu.

Richard.

2012-03-06  Richard Guenther  <rguent...@suse.de>

        PR middle-end/52493
        * tree-ssa-alias.c (ptr_derefs_may_alias_p): Robustify.

        * gcc.dg/torture/pr52493.c: New testcase.

Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c        (revision 184981)
--- gcc/tree-ssa-alias.c        (working copy)
*************** ptr_derefs_may_alias_p (tree ptr1, tree
*** 236,252 ****
    STRIP_NOPS (ptr1);
    STRIP_NOPS (ptr2);
  
-   /* Anything we do not explicilty handle aliases.  */
-   if ((TREE_CODE (ptr1) != SSA_NAME
-        && TREE_CODE (ptr1) != ADDR_EXPR
-        && TREE_CODE (ptr1) != POINTER_PLUS_EXPR)
-       || (TREE_CODE (ptr2) != SSA_NAME
-         && TREE_CODE (ptr2) != ADDR_EXPR
-         && TREE_CODE (ptr2) != POINTER_PLUS_EXPR)
-       || !POINTER_TYPE_P (TREE_TYPE (ptr1))
-       || !POINTER_TYPE_P (TREE_TYPE (ptr2)))
-     return true;
- 
    /* Disregard pointer offsetting.  */
    if (TREE_CODE (ptr1) == POINTER_PLUS_EXPR)
      {
--- 236,241 ----
*************** ptr_derefs_may_alias_p (tree ptr1, tree
*** 275,281 ****
        if (base
          && (TREE_CODE (base) == MEM_REF
              || TREE_CODE (base) == TARGET_MEM_REF))
!       ptr1 = TREE_OPERAND (base, 0);
        else if (base
               && DECL_P (base))
        return ptr_deref_may_alias_decl_p (ptr2, base);
--- 264,270 ----
        if (base
          && (TREE_CODE (base) == MEM_REF
              || TREE_CODE (base) == TARGET_MEM_REF))
!       return ptr_derefs_may_alias_p (TREE_OPERAND (base, 0), ptr2);
        else if (base
               && DECL_P (base))
        return ptr_deref_may_alias_decl_p (ptr2, base);
*************** ptr_derefs_may_alias_p (tree ptr1, tree
*** 288,294 ****
        if (base
          && (TREE_CODE (base) == MEM_REF
              || TREE_CODE (base) == TARGET_MEM_REF))
!       ptr2 = TREE_OPERAND (base, 0);
        else if (base
               && DECL_P (base))
        return ptr_deref_may_alias_decl_p (ptr1, base);
--- 277,283 ----
        if (base
          && (TREE_CODE (base) == MEM_REF
              || TREE_CODE (base) == TARGET_MEM_REF))
!       return ptr_derefs_may_alias_p (ptr1, TREE_OPERAND (base, 0));
        else if (base
               && DECL_P (base))
        return ptr_deref_may_alias_decl_p (ptr1, base);
*************** ptr_derefs_may_alias_p (tree ptr1, tree
*** 296,301 ****
--- 285,297 ----
        return true;
      }
  
+   /* From here we require SSA name pointers.  Anything else aliases.  */
+   if (TREE_CODE (ptr1) != SSA_NAME
+       || TREE_CODE (ptr2) != SSA_NAME
+       || !POINTER_TYPE_P (TREE_TYPE (ptr1))
+       || !POINTER_TYPE_P (TREE_TYPE (ptr2)))
+     return true;
+ 
    /* We may end up with two empty points-to solutions for two same pointers.
       In this case we still want to say both pointers alias, so shortcut
       that here.  */
Index: gcc/testsuite/gcc.dg/torture/pr52493.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr52493.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr52493.c      (revision 0)
***************
*** 0 ****
--- 1,38 ----
+ /* { dg-do compile } */
+ 
+ struct Time {
+     long int sec;
+     long usec;
+ };
+ struct Flow {
+     unsigned short iif;
+     struct Time mtime;
+ };
+ struct NetFlow {
+     unsigned MaxFlows;
+     unsigned HeaderFields;
+     unsigned short *HeaderFormat;
+ };
+ static struct NetFlow *netflow;
+ static struct Time start_time;
+ static unsigned char emit_packet[1500];
+ inline long int cmpmtime(struct Time *t1, struct Time *t2)
+ {
+   return (t1->sec - t2->sec) * 1000 + (t1->usec - t2->usec) / 1000;
+ }
+ static void fill(int fields, unsigned short *format,
+                 struct Flow *flow, void *p)
+ {
+   int i;
+   for (i = 0; i < fields; i++)
+     if (format[i] == 21)
+       {
+       unsigned int __v;
+       __v = cmpmtime(&flow->mtime, &start_time);
+       *((unsigned int *) p) = __v;
+       }
+ }
+ void emit_thread()
+ {
+   fill(netflow->HeaderFields, netflow->HeaderFormat, 0, &emit_packet);
+ }

Reply via email to