Odd behaviour of indirect_ref_may_alias_decl_p in vn oracle
Richard Biener
rguenther@suse.de
Mon Jun 3 13:59:00 GMT 2019
On Sat, 1 Jun 2019, Jan Hubicka wrote:
> Hi,
> while looking for the reason for extra disambiguations in
> aliasing_component_refs I have noticed an odd case. We newly disambiguate:
>
> MEM[(Element_t *)_27 + 4B];
>
> s.globalIDDataBase_m;
>
> <mem_ref 0x7fffe2f68f28
> type <integer_type 0x7ffff63ffd20 Element_t sizes-gimplified type_6 SI
> size <integer_cst 0x7ffff70ff078 constant 32>
> unit-size <integer_cst 0x7ffff70ff090 constant 4>
> align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff70fb5e8 precision:32 min <integer_cst 0x7ffff70ff030 -2147483648> max <integer_cst 0x7ffff70ff048 2147483647>
> pointer_to_this <pointer_type 0x7fffe55a3dc8>>
> tree_0 tree_2
> arg:0 <ssa_name 0x7fffe2f666c0
> type <pointer_type 0x7ffff62df888 type <record_type 0x7ffff658d930 Domain>
> public unsigned DI
> size <integer_cst 0x7ffff70dee28 constant 64>
> unit-size <integer_cst 0x7ffff70dee40 constant 8>
> align:64 warn_if_not_align:0 symtab:0 alias-set 216 canonical-type 0x7ffff62df888>
> visited
> def_stmt _27 = &MEM[(struct OneDomain_t *)&s].D.113982.domain_m[i_26].D.110783.D.44395;
> version:27
> ptr-info 0x7ffff5c66540>
> arg:1 <integer_cst 0x7fffe98babe8 type <pointer_type 0x7fffe55a3dc8> constant 4>>
> <component_ref 0x7ffff1b8d030
> type <pointer_type 0x7ffff494bf18
> type <record_type 0x7ffff494b7e0 GlobalIDDataBase addressable needs-constructing type_1 type_4 type_5 type_6 BLK
> size <integer_cst 0x7ffff4fe92d0 constant 576>
> unit-size <integer_cst 0x7ffff4fe9048 constant 72>
> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff494b7e0 fields <function_decl 0x7fffecee2000 __dt > context <translation_unit_decl 0x7ffff70eb168 /aux/hubicka/tramp3d-v4b.cpp>
> full-name "class GlobalIDDataBase"
> needs-constructor needs-destructor X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown
> pointer_to_this <pointer_type 0x7ffff494bf18> reference_to_this <reference_type 0x7fffecededc8> chain <type_decl 0x7ffff4948b48 GlobalIDDataBase>>
> sizes-gimplified public unsigned type_6 DI
> size <integer_cst 0x7ffff70dee28 constant 64>
> unit-size <integer_cst 0x7ffff70dee40 constant 8>
> align:64 warn_if_not_align:0 symtab:0 alias-set 484 canonical-type 0x7ffff494bf18
> pointer_to_this <pointer_type 0x7fffe4f220a8>>
>
> arg:0 <mem_ref 0x7fffe2f68fc8
> type <record_type 0x7ffff294d888 INode sizes-gimplified addressable needs-constructing type_1 type_4 type_5 type_6 BLK
> size <integer_cst 0x7ffff6f1aed0 constant 320>
> unit-size <integer_cst 0x7ffff72d4078 constant 40>
> align:64 warn_if_not_align:0 symtab:0 alias-set 604 canonical-type 0x7ffff294d888 fields <const_decl 0x7fffee5b8f50 dimensions> context <translation_unit_decl 0x7ffff70eb168 /aux/hubicka/tramp3d-v4b.cpp>
> full-name "class INode<3>"
> needs-constructor needs-destructor X() X(constX&) this=(X&) n_parents=0 use_template=1 interface-unknown
> pointer_to_this <pointer_type 0x7fffee1a1f18> reference_to_this <reference_type 0x7fffee1a61f8> chain <type_decl 0x7ffff294b850 INode>>
> tree_1 tree_2
> arg:0 <addr_expr 0x7ffff56641c0 type <pointer_type 0x7fffee1a1f18>
> arg:0 <var_decl 0x7fffec51a5a0 s>>
> arg:1 <integer_cst 0x7fffe945f960 constant 0>>
> arg:1 <field_decl 0x7fffede17c78 globalIDDataBase_m type <pointer_type 0x7ffff494bf18>
> used private unsigned nonlocal decl_3 DI /aux/hubicka/tramp3d-v4b.cpp:5583:21 size <integer_cst 0x7ffff70dee28 64> unit-size <integer_cst 0x7ffff70dee40 8>
> align:64 warn_if_not_align:0 offset_align 128
> offset <integer_cst 0x7ffff70dee88 constant 16> bit-offset <integer_cst 0x7ffff70dee28 64> context <record_type 0x7ffff294d888 INode>
> chain <field_decl 0x7fffede17d10 key_m type <integer_type 0x7fffede19690 NodeKey_t>
> used private nonlocal decl_3 SI /aux/hubicka/tramp3d-v4b.cpp:5584:13
> size <integer_cst 0x7ffff70ff078 constant 32>
> unit-size <integer_cst 0x7ffff70ff090 constant 4>
> align:32 warn_if_not_align:0 offset_align 128
> offset <integer_cst 0x7ffff70ff288 constant 32>
> bit-offset <integer_cst 0x7ffff70deea0 constant 0> context <record_type 0x7ffff294d888 INode> chain <type_decl 0x7fffede17428 INode>>>
> /aux/hubicka/tramp3d-v4b.cpp:5457:24 start: /aux/hubicka/tramp3d-v4b.cpp:5457:24 finish: /aux/hubicka/tramp3d-v4b.cpp:5457:24>
>
> that did not make sense to me becaue ref1 type is integer_type and ref2 is
> pointer_type so these should be disambiguated by usual TBAA querry earlier.
>
> What happens is the following. The analysis happens via vn_reference_lookup
> which does
> if (! tbaa_p)
> r.ref_alias_set = r.base_alias_set = 0;
> later this is passed as ref1 but because it reffers to decl the order is
> exchanged so it appears as ref2 in in indirect_ref_may_alias_decl_p.
> Now there is test:
> /* If the alias set for a pointer access is zero all bets are off. */
> if (base1_alias_set == 0)
> return true;
> which is ok, since base1_alias_set is non-0 (it is coming from indirect_ref).
>
> I think the code is not supposed to work this way :)
>
> I not convinced we realy want to give up on TBAA when ref is actual
> decl? At least polymorphic call analysis is using the assumption that
> placement news do not happen here.
>
> This patch fixes the odd case in conservative way and also reduces
> number of disambiguations noticeably:
>
> from
> aliasing_component_ref_p: 636 disambiguations, 15844 queries
> to
> aliasing_component_ref_p: 136 disambiguations, 13943 queries
>
> Can we construct valid placement new testcase where this matters?
I think the patch is correct. Consider the decl being accessed
via memcpy which will result in base2_alias_set == 0. The
GIMPLE memory model says decls are just random storage and thus
their dynamic type can change. This is also why there's the
"strange" (and also incomplete...) give-ups on "this looks like
a view-conversion" are there.
Note it's easiest to build GIMPLE testcases for simple disambiguations
these days ;) It's also best to quote what we disambiguate by
dumping the stmts with TDF_GIMPLE since that shows everything
semantically important.
But does the patch really make a difference?
if (base1_alias_set != base2_alias_set
&& !alias_sets_conflict_p (base1_alias_set, base2_alias_set))
return false;
Should catch this since everything conflicts with zero? So I
wonder how your statistcs can be correct? The base1_alias_set == 0
check is redundant as well apart from the case where both
are zero which is when we end up skipping the above test.
Richard.
> Honza
>
> * tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Also give up
> TBAA path when base2_alias_set is 0.
> Index: tree-ssa-alias.c
> ===================================================================
> --- tree-ssa-alias.c (revision 271813)
> +++ tree-ssa-alias.c (working copy)
> @@ -1295,7 +1296,7 @@ indirect_ref_may_alias_decl_p (tree ref1
> ptrtype1 = TREE_TYPE (TREE_OPERAND (base1, 1));
>
> /* If the alias set for a pointer access is zero all bets are off. */
> - if (base1_alias_set == 0)
> + if (base1_alias_set == 0 || base2_alias_set == 0)
> return true;
>
> /* When we are trying to disambiguate an access with a pointer dereference
>
--
Richard Biener <rguenther@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG NÌrnberg)
More information about the Gcc-patches
mailing list