The following fixes a miscompilation of the linux kernel which does patching of instructions by accessing memory relative to function addresses (that's undefined in C and won't work for targets using function descriptors but hey - those guys say they know what they are doing).
Thus the following makes points-to analysis consider function and label addresses as pointing to global memory (rather than "readonly" data which we don't put into points-to sets because readonly data is not interesting for alias analysis purposes). We still don't consider this instruction data to hold valid pointers so if people will start to extract pointers from there and expect dereferences to alias say global symbols they'll still not get what they expect - if we were to handle this "correctly" as well we'd get negative effects from our analysis by getting NONLOCAL/ANYTHING bleed through the solution. The patch below doesn't suffer from anything like that because it only changes how we interpret the points-to result rather than changing its outcome. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2016-03-10 Richard Biener <rguent...@suse.de> PR tree-optimization/70128 * tree-ssa-structalias.c (set_uids_in_ptset): Set vars_contains_nonlocal for any FUNCTION_DECL or LABEL_DECL. * gcc.dg/tree-ssa/alias-34.c: New testcase. * gcc.dg/tree-ssa/alias-35.c: Likewise. Index: gcc/tree-ssa-structalias.c =================================================================== *** gcc/tree-ssa-structalias.c (revision 234025) --- gcc/tree-ssa-structalias.c (working copy) *************** set_uids_in_ptset (bitmap into, bitmap f *** 6280,6285 **** --- 6280,6295 ---- && ! auto_var_in_fn_p (vi->decl, fndecl))) pt->vars_contains_nonlocal = true; } + + else if (TREE_CODE (vi->decl) == FUNCTION_DECL + || TREE_CODE (vi->decl) == LABEL_DECL) + { + /* Nothing should read/write from/to code so we can + save bits by not including them in the points-to bitmaps. + Still mark the points-to set as containing global memory + to make code-patching possible - see PR70128. */ + pt->vars_contains_nonlocal = true; + } } } Index: gcc/testsuite/gcc.dg/tree-ssa/alias-34.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/alias-34.c (revision 0) --- gcc/testsuite/gcc.dg/tree-ssa/alias-34.c (working copy) *************** *** 0 **** --- 1,19 ---- + /* { dg-do compile } */ + /* { dg-options "-O2 -fno-strict-aliasing -fdump-tree-optimized" } */ + + void foo (int b) + { + void *p; + lab: + if (b) + p = &&lab; + else + { + lab2: + p = &&lab2; + } + *(char *)p = 1; + } + + /* We should keep the store to the label locations. */ + /* { dg-final { scan-tree-dump " = 1;" "optimized" } } */ Index: gcc/testsuite/gcc.dg/tree-ssa/alias-35.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/alias-35.c (revision 0) --- gcc/testsuite/gcc.dg/tree-ssa/alias-35.c (working copy) *************** *** 0 **** --- 1,18 ---- + /* PR70128 */ + /* { dg-do compile } */ + /* { dg-options "-O2 -fno-strict-aliasing -fdump-tree-optimized" } */ + + void foo (int b) + { + extern void bar (void); + extern void baz (void); + void *p; + if (b) + p = bar; + else + p = baz; + *(char *)p = 1; + } + + /* We should keep the store to the function locations. */ + /* { dg-final { scan-tree-dump " = 1;" "optimized" } } */