Hi all! I reduced my array aliasing libstdc++ failures to the following testcase:
struct iterator { int* ptr; iterator(int* _ptr) : ptr(_ptr) {} }; struct container { int* first; container(int* _first) : first(_first) {} iterator begin() { return iterator(first); } }; bool includes(const iterator&); bool test4() { int array[] = {2, 4}; container con(array); return includes(con.begin()); } the weird thing now is, that the alias1 dump contains # SFT.2_19 = V_MAY_DEF <SFT.2_2>; # SFT.4_20 = V_MAY_DEF <SFT.4_15>; D.1797_16 = includes (&D.1794); i.e. it misses the V_MAY_DEF for SFT.1 (array, UID 1783, int[2], is addressable, sub-vars: { SFT.2 SFT.1 }), while the alias2 dump is ok: # SFT.1_9 = V_MAY_DEF <SFT.1_3>; # SFT.2_19 = V_MAY_DEF <SFT.2_2>; # SFT.4_20 = V_MAY_DEF <SFT.4_15>; D.1797_16 = includes (&D.1794); unfortunately, at that time DCE already decided to remove the array[1] initialization. The difference seems to be in the Pointed-to sets; alias1 contains SFT.0_10 SFT.3_6 SFT.4_14 SFT.5_12 _first_5, its value escapes, points-to vars: { SFT.2 } D.1810_8, points-to vars: { SFT.2 } _ptr_9, its value escapes, points-to vars: { SFT.2 } while alias2 is only SFT.0_10 SFT.3_6 SFT.4_14 SFT.5_12 _ptr_8, points-to vars: { } So maybe from there we miscompute flow-insensitive alias information which differs in only - SFT.1, UID 1815, int, is addressable, default def: SFT.1_3 + SFT.1, UID 1815, int, is addressable, call clobbered, default def: SFT.1_3 I attached the two alias dumps for reference. Maybe you can point out what is going wrong - I'm somewhat lost here. Thanks, Richard.
;; Function bool test4() (_Z5test4v) Points-to analysis Constraints: ANYTHING = &ANYTHING READONLY = &ANYTHING INTEGER = &ANYTHING ANYOFFSET = &ANYOFFSET _first_5 = &array con = _first_5 D.1810_8 = con _ptr_9 = D.1810_8 D.1809 = _ptr_9 D.1796 = D.1809 D.1794 = D.1796 D.1797_16 = &ANYTHING Collapsing static cycles and doing variable substitution: Collapsing con into _first_5 Collapsing D.1810_8 into _first_5 Collapsing _ptr_9 into _first_5 Collapsing D.1809 into _first_5 Collapsing D.1796 into _first_5 Collapsing D.1794 into _first_5 Solving graph: Points-to sets NULL = { } ANYTHING = { ANYTHING } READONLY = { ANYTHING } INTEGER = { ANYTHING } ANYOFFSET = { ANYOFFSET } _first_5 = { array } array = { } array.1 = { } con = { array } D.1810_8 = { array } _ptr_9 = { array } D.1809 = { array } D.1796 = { array } D.1794 = { array } D.1797_16 = { ANYTHING } test4: Total number of aliased vops: 0 Referenced variables in test4: 17 Variable: SFT.0, UID 1814, int *, default def: SFT.0_10 Variable: SFT.1, UID 1815, int, is addressable, default def: SFT.1_3 Variable: _first, UID 1808, int * Variable: D.1809, UID 1809, struct iterator, sub-vars: { SFT.0 } Variable: D.1810, UID 1810, int * Variable: _ptr, UID 1811, int * Variable: <retval>, UID 1782, int Variable: array, UID 1783, int[2], is addressable, sub-vars: { SFT.2 SFT.1 } Variable: con, UID 1784, struct container, sub-vars: { SFT.3 } Variable: SFT.2, UID 1816, int, is addressable, call clobbered, default def: SFT.2_1 Variable: SFT.3, UID 1817, int *, default def: SFT.3_6 Variable: SFT.4, UID 1818, int *, is addressable, call clobbered, default def: SFT.4_14 Variable: SFT.5, UID 1819, int *, default def: SFT.5_12 Variable: D.1794, UID 1794, struct iterator, is addressable, sub-vars: { SFT.4 } Variable: D.1795, UID 1795, int Variable: D.1796, UID 1796, struct iterator, sub-vars: { SFT.5 } Variable: D.1797, UID 1797, bool Pointed-to sets for pointers in bool test4() SFT.0_10 SFT.3_6 SFT.4_14 SFT.5_12 _first_5, its value escapes, points-to vars: { SFT.2 } D.1810_8, points-to vars: { SFT.2 } _ptr_9, its value escapes, points-to vars: { SFT.2 } Flow-insensitive alias information for bool test4() Aliased symbols SFT.1, UID 1815, int, is addressable, default def: SFT.1_3 array, UID 1783, int[2], is addressable, sub-vars: { SFT.2 SFT.1 } SFT.2, UID 1816, int, is addressable, call clobbered, default def: SFT.2_1 SFT.4, UID 1818, int *, is addressable, call clobbered, default def: SFT.4_14 D.1794, UID 1794, struct iterator, is addressable, sub-vars: { SFT.4 } Dereferenced pointers Type memory tags Flow-sensitive alias information for bool test4() SSA_NAME pointers Name memory tags Registering new PHI nodes in block #-1 Registering new PHI nodes in block #0 Updating SSA information for statement array[0] = 2; Updating SSA information for statement array[1] = 4; Updating SSA information for statement con.first = _first_5; Updating SSA information for statement D.1810_8 = con.first; Updating SSA information for statement D.1809.ptr = _ptr_9; Updating SSA information for statement D.1796 = D.1809; Updating SSA information for statement D.1794 = D.1796; Updating SSA information for statement D.1797_16 = includes (&D.1794); Symbols to be put in SSA form array con D.1794 D.1809 SFT.0 SFT.1 SFT.2 SFT.3 SFT.4 Incremental SSA update started at block: -1 Number of blocks in CFG: 1 Number of blocks to update: 1 (100%) Affected blocks: 0 bool test4() () { int * _ptr; struct iterator D.1809; int * D.1810; struct iterator D.1809; int * _first; struct container con; int array[2]; bool D.1797; struct iterator D.1796; struct iterator D.1794; int D.1795; <bb 0>: # SFT.2_2 = V_MUST_DEF <SFT.2_1>; array[0] = 2; # SFT.1_4 = V_MUST_DEF <SFT.1_3>; array[1] = 4; _first_5 = &array[0]; # SFT.3_7 = V_MUST_DEF <SFT.3_6>; con.first = _first_5; # VUSE <SFT.3_7>; D.1810_8 = con.first; _ptr_9 = D.1810_8; # SFT.0_11 = V_MUST_DEF <SFT.0_10>; D.1809.ptr = _ptr_9; # SFT.5_13 = V_MUST_DEF <SFT.5_12>; # VUSE <SFT.0_11>; D.1796 = D.1809; # SFT.4_15 = V_MUST_DEF <SFT.4_14>; # VUSE <SFT.5_13>; D.1794 = D.1796; # SFT.2_19 = V_MAY_DEF <SFT.2_2>; # SFT.4_20 = V_MAY_DEF <SFT.4_15>; D.1797_16 = includes (&D.1794); D.1795_17 = (int) D.1797_16; return D.1795_17; }
;; Function bool test4() (_Z5test4v) Points-to analysis Constraints: ANYTHING = &ANYTHING READONLY = &ANYTHING INTEGER = &ANYTHING ANYOFFSET = &ANYOFFSET con = &array _ptr_8 = &array D.1809 = &array D.1796 = D.1809 D.1794 = D.1796 D.1797_16 = &ANYTHING Collapsing static cycles and doing variable substitution: Collapsing D.1796 into D.1809 Collapsing D.1794 into D.1809 Solving graph: Points-to sets NULL = { } ANYTHING = { ANYTHING } READONLY = { ANYTHING } INTEGER = { ANYTHING } ANYOFFSET = { ANYOFFSET } con = { array } array = { } array.1 = { } _ptr_8 = { array } D.1809 = { array } D.1796 = { array } D.1794 = { array } D.1797_16 = { ANYTHING } test4: Total number of aliased vops: 0 Referenced variables in test4: 17 Variable: SFT.0, UID 1814, int *, default def: SFT.0_10 Variable: SFT.1, UID 1815, int, is addressable, call clobbered, default def: SFT.1_3 Variable: _first, UID 1808, int * Variable: D.1809, UID 1809, struct iterator, sub-vars: { SFT.0 } Variable: D.1810, UID 1810, int * Variable: _ptr, UID 1811, int * Variable: <retval>, UID 1782, int Variable: array, UID 1783, int[2], is addressable, sub-vars: { SFT.2 SFT.1 } Variable: con, UID 1784, struct container, sub-vars: { SFT.3 } Variable: SFT.2, UID 1816, int, is addressable, call clobbered, default def: SFT.2_1 Variable: SFT.3, UID 1817, int *, default def: SFT.3_6 Variable: SFT.4, UID 1818, int *, is addressable, call clobbered, default def: SFT.4_14 Variable: SFT.5, UID 1819, int *, default def: SFT.5_12 Variable: D.1794, UID 1794, struct iterator, is addressable, sub-vars: { SFT.4 } Variable: D.1795, UID 1795, int Variable: D.1796, UID 1796, struct iterator, sub-vars: { SFT.5 } Variable: D.1797, UID 1797, bool Pointed-to sets for pointers in bool test4() SFT.0_10 SFT.3_6 SFT.4_14 SFT.5_12 _ptr_8, points-to vars: { } Flow-insensitive alias information for bool test4() Aliased symbols SFT.1, UID 1815, int, is addressable, call clobbered, default def: SFT.1_3 array, UID 1783, int[2], is addressable, sub-vars: { SFT.2 SFT.1 } SFT.2, UID 1816, int, is addressable, call clobbered, default def: SFT.2_1 SFT.4, UID 1818, int *, is addressable, call clobbered, default def: SFT.4_14 D.1794, UID 1794, struct iterator, is addressable, sub-vars: { SFT.4 } Dereferenced pointers Type memory tags Flow-sensitive alias information for bool test4() SSA_NAME pointers Name memory tags Registering new PHI nodes in block #-1 Registering new PHI nodes in block #0 Updating SSA information for statement array[0] = 2; Updating SSA information for statement D.1794 = D.1796; Updating SSA information for statement D.1797_16 = includes (&D.1794); Symbols to be put in SSA form array D.1794 SFT.1 SFT.2 SFT.4 Incremental SSA update started at block: -1 Number of blocks in CFG: 1 Number of blocks to update: 1 (100%) Affected blocks: 0 bool test4() () { int * _ptr; struct iterator D.1809; int * D.1810; struct iterator D.1809; int * _first; struct container con; int array[2]; bool D.1797; struct iterator D.1796; struct iterator D.1794; int D.1795; <bb 0>: # SFT.2_2 = V_MUST_DEF <SFT.2_1>; array[0] = 2; # SFT.3_7 = V_MUST_DEF <SFT.3_6>; con.first = &array[0]; _ptr_8 = &array[0]; # SFT.0_11 = V_MUST_DEF <SFT.0_10>; D.1809.ptr = &array[0]; # SFT.5_13 = V_MUST_DEF <SFT.5_12>; # VUSE <SFT.0_11>; D.1796 = D.1809; # SFT.4_15 = V_MUST_DEF <SFT.4_14>; # VUSE <SFT.5_13>; D.1794 = D.1796; # SFT.1_9 = V_MAY_DEF <SFT.1_3>; # SFT.2_19 = V_MAY_DEF <SFT.2_2>; # SFT.4_20 = V_MAY_DEF <SFT.4_15>; D.1797_16 = includes (&D.1794); D.1795_17 = (int) D.1797_16; return D.1795_17; }