When looking at the code generated for wide-int idioms on the branch again I noticed that we fail to eliminate quite some dead stores (on GIMPLE, eventually we recover from that at RTL level - I didn't check). This is caused by some old special-casing of union accesses during points-to analysis which eventually causes 'anything' to escape nearly everywhere in GCC (meh...). It turns out the ancient special-case for union is no longer necessary as we now properly transfer pointers through all sorts of weird obfuscation.
Thus, fixed with the following - bootstrapped and tested on x86_64-unknown-linux-gnu and applied to trunk. Richard. 2013-11-26 Richard Biener <rguent...@suse.de> PR tree-optimization/59287 * tree-ssa-structalias.c (get_constraint_for_component_ref): Remove no longer necessary special-casing of union accesses. * gcc.dg/tree-ssa/alias-29.c: New testcase. Index: gcc/tree-ssa-structalias.c =================================================================== *** gcc/tree-ssa-structalias.c (revision 205344) --- gcc/tree-ssa-structalias.c (working copy) *************** get_constraint_for_component_ref (tree t *** 3163,3191 **** return; } - /* Handle type-punning through unions. If we are extracting a pointer - from a union via a possibly type-punning access that pointer - points to anything, similar to a conversion of an integer to - a pointer. */ - if (!lhs_p) - { - tree u; - for (u = t; - TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF; - u = TREE_OPERAND (u, 0)) - if (TREE_CODE (u) == COMPONENT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) - { - struct constraint_expr temp; - - temp.offset = 0; - temp.var = anything_id; - temp.type = ADDRESSOF; - results->safe_push (temp); - return; - } - } - t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize); /* Pretend to take the address of the base, we'll take care of --- 3163,3168 ---- Index: gcc/testsuite/gcc.dg/tree-ssa/alias-29.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/alias-29.c (revision 0) --- gcc/testsuite/gcc.dg/tree-ssa/alias-29.c (working copy) *************** *** 0 **** --- 1,27 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fdump-tree-optimized" } */ + + union X { + int i; + void *p; + }; + void bar (int); + + int * __attribute__((noinline,noclone)) + baz (int *p) { return p; } + + void foo (union X *x) + { + struct Y { int i; } ystruct = {}; + ystruct.i = * baz (&ystruct.i); + bar (x->i); + } + + /* DSE and then DCE should be able to remove all uses of ystruct. + Formerly the union access for the parameter to bar let 'anything' + escape which made the call to bar possibly use ystruct and thus + prevent the store to ystruct.i from being eliminated. The call to + baz makes sure that ystruct has its address taken. */ + + /* { dg-final { scan-tree-dump-not "ystruct" "optimized" } } */ + /* { dg-final { cleanup-tree-dump "optimized" } } */