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? 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