This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix points-to analysis wrt union accesses, PR59287
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 26 Nov 2013 10:03:38 +0100 (CET)
- Subject: [PATCH] Fix points-to analysis wrt union accesses, PR59287
- Authentication-results: sourceware.org; auth=none
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 <rguenther@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" } } */