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); + }