On Wed, Feb 19, 2020 at 3:20 PM Richard Biener <richard.guent...@gmail.com> wrote: > > On Wed, Feb 19, 2020 at 1:19 PM Richard Sandiford > <richard.sandif...@arm.com> wrote: > > > > What should we do about this? The PR is a wrong-code regression from > > GCC 9 and it doesn't look like we can remove the second offset_overlap_p > > check, given how many cases currently rely on it. > > Did you check whether we eventually disambiguate those via > rtx_refs_may_alias_p > (so using MEM_EXPR)? I would guess all but those that have no MEM_EXPR? > > Ideally we'd rely more on MEM_EXPR for alias disambiguation than the ad-hoc > ways of recovering "details" from the actual MEM. > > If numbers are still in the same ballpark when factoring in alias > disambiguations > run after memrefs_conflict_p calls then let's go with your patch, it > looks technically > correct if all the facts about section anchors are correct (where I > know not very much > about them or representational issues wrt aliasing).
See the patch attached to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49330 for how I did this kind of statistics for base_alias_check. But as said, counting !MEM_EXPR cases might be a good enough hint. Richard. > Thanks, > Richard. > > > Thanks, > > Richard > > > > Richard Sandiford <richard.sandif...@arm.com> writes: > > > Richard Biener <richard.guent...@gmail.com> writes: > > >> On Tue, Feb 4, 2020 at 6:44 PM Richard Sandiford > > >> <richard.sandif...@arm.com> wrote: > > >>> > > >>> Richard Sandiford <richard.sandif...@arm.com> writes: > > >>> > [...] > > >>> >> I'm not sure given the issues you've introduced if I could actually > > >>> >> fill out the matrix of answers without more underlying information. > > >>> >> ie, when can we get symbols without source level decls, > > >>> >> anchors+interposition issues, etc. > > >>> > > > >>> > OK. In that case, I wonder whether it would be safer to have a > > >>> > fourth state on top of the three above: > > >>> > > > >>> > - known distance apart > > >>> > - independent > > >>> > - known distance apart or independent > > >>> > - don't know > > >>> > > > >>> > with "don't know" being anything that involves bare symbols? > > >>> > > > >>> > Richard > > >>> > > >>> How does this look? Tested on aarch64-linux-gnu and > > >>> x86_64-linux-gnu. > > >>> > > >>> Full description from scratch: > > >>> > > >>> memrefs_conflict_p has a slightly odd structure. It first checks > > >>> whether two addresses based on SYMBOL_REFs refer to the same object, > > >>> with a tristate result: > > >>> > > >>> int cmp = compare_base_symbol_refs (x,y); > > >>> > > >>> If the addresses do refer to the same object, we can use offset-based > > >>> checks: > > >>> > > >>> /* If both decls are the same, decide by offsets. */ > > >>> if (cmp == 1) > > >>> return offset_overlap_p (c, xsize, ysize); > > >>> > > >>> But then, apart from the special case of forced address alignment, > > >>> we use an offset-based check even if we don't know whether the > > >>> addresses refer to the same object: > > >>> > > >>> /* Assume a potential overlap for symbolic addresses that went > > >>> through alignment adjustments (i.e., that have negative > > >>> sizes), because we can't know how far they are from each > > >>> other. */ > > >>> if (maybe_lt (xsize, 0) || maybe_lt (ysize, 0)) > > >>> return -1; > > >>> /* If decls are different or we know by offsets that there is no > > >>> overlap, > > >>> we win. */ > > >>> if (!cmp || !offset_overlap_p (c, xsize, ysize)) > > >>> return 0; > > >>> > > >>> This somewhat contradicts: > > >>> > > >>> /* In general we assume that memory locations pointed to by different > > >>> labels > > >>> may overlap in undefined ways. */ > > >> > > >> Sorry for not chiming in earlier but isn't the bug that > > >> > > >> > > >> > > >>> at the end of compare_base_symbol_refs. In other words, we're taking -1 > > >>> to mean that either (a) the symbols are equal (via aliasing) or (b) the > > >>> references access non-overlapping objects. > > >>> > > >>> But even assuming that's true for normal symbols, it doesn't cope > > >>> correctly with section anchors. If a symbol X at ANCHOR+OFFSET > > >>> is preemptible, either (a) X = ANDHOR+OFFSET or (b) X and ANCHOR > > >>> reference non-overlapping objects. > > >>> > > >>> And an offset-based comparison makes no sense for an anchor symbol > > >>> vs. a bare symbol with no decl. If the bare symbol is allowed to > > >>> alias other symbols then it can surely alias any symbol in the > > >>> anchor's block, so there are multiple anchor offsets that might > > >>> induce an alias. > > >> > > >> But then isn't the simple fix to honor the -1 and do > > >> > > >> diff --git a/gcc/alias.c b/gcc/alias.c > > >> index 3794f9b6a9e..bf13d37c0f7 100644 > > >> --- a/gcc/alias.c > > >> +++ b/gcc/alias.c > > >> @@ -2490,9 +2490,8 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, > > >> poly_int64 ysize, rtx y, > > >> other. */ > > >> if (maybe_lt (xsize, 0) || maybe_lt (ysize, 0)) > > >> return -1; > > >> - /* If decls are different or we know by offsets that there is no > > >> overlap, > > >> - we win. */ > > >> - if (!cmp || !offset_overlap_p (c, xsize, ysize)) > > >> + /* If decls are different, we win. */ > > >> + if (cmp == 0) > > >> return 0; > > >> /* Decls may or may not be different and offsets overlap....*/ > > >> return -1; > > >> > > >> ? > > > > > > The code was deliberately written this way from the ouset though > > > (rather than it ending up like this through many cuts). It was > > > added in g:54363f8a92920f5559c83ddd53e480a27205e6b7: > > > > > > 2015-12-08 Jan Hubicka <hubi...@ucw.cz> > > > > > > PR ipa/61886 > > > PR middle-end/25140 > > > * tree-ssa-alias.c (ptr_deref_may_alias_decl_p): Use > > > compare_base_decls > > > (nonoverlapping_component_refs_of_decl_p): Update sanity check. > > > (decl_refs_may_alias_p): Use compare_base_decls. > > > * alias.c: Include cgraph.h > > > (get_alias_set): Add cut-off for recursion. > > > (rtx_equal_for_memref_p): Use rtx_equal_for_memref_p. > > > (compare_base_decls): New function. > > > (base_alias_check): Likewise. > > > (memrefs_conflict_p): Likewise. > > > (nonoverlapping_memrefs_p): Likewise. > > > * alias.h (compare_base_decls): Declare. > > > > > > which included: > > > > > > - if (rtx_equal_for_memref_p (x, y)) > > > + if (GET_CODE (x) == SYMBOL_REF && GET_CODE (y) == SYMBOL_REF) > > > + { > > > + tree x_decl = SYMBOL_REF_DECL (x); > > > + tree y_decl = SYMBOL_REF_DECL (y); > > > + int cmp; > > > + > > > + if (!x_decl || !y_decl) > > > + { > > > + /* Label and normal symbol are never the same. */ > > > + if (x_decl != y_decl) > > > + return 0; > > > + return offset_overlap_p (c, xsize, ysize); > > > + } > > > + else > > > + cmp = compare_base_decls (x_decl, y_decl); > > > + > > > + /* If both decls are the same, decide by offsets. */ > > > + if (cmp == 1) > > > + return offset_overlap_p (c, xsize, ysize); > > > + /* If decls are different or we know by offsets that there is no > > > overlap, > > > + we win. */ > > > + if (!cmp || !offset_overlap_p (c, xsize, ysize)) > > > + return 0; > > > + /* Decls may or may not be different and offsets overlap....*/ > > > + return -1; > > > + } > > > + else if (rtx_equal_for_memref_p (x, y)) > > > > > > The only significant change since them was to add compare_base_symbol_refs > > > (g:73e48cb322152bf504ced8694fa748544ecaa6eb): > > > > > > if (GET_CODE (x) == SYMBOL_REF && GET_CODE (y) == SYMBOL_REF) > > > { > > > - tree x_decl = SYMBOL_REF_DECL (x); > > > - tree y_decl = SYMBOL_REF_DECL (y); > > > - int cmp; > > > - > > > - if (!x_decl || !y_decl) > > > - { > > > - /* Label and normal symbol are never the same. */ > > > - if (x_decl != y_decl) > > > - return 0; > > > - return offset_overlap_p (c, xsize, ysize); > > > - } > > > - else > > > - cmp = compare_base_decls (x_decl, y_decl); > > > + int cmp = compare_base_symbol_refs (x,y); > > > > > >>> This patch therefore replaces the current tristate: > > >>> > > >>> - known equal > > >>> - known independent (two accesses can't alias) > > >>> - equal or independent > > >>> > > >>> with: > > >>> > > >>> - known distance apart > > >>> - known independent (two accesses can't alias) > > >>> - known distance apart or independent > > >>> - don't know > > >>> > > >>> For safety, the patch puts all bare symbols in the "don't know" > > >>> category. If that turns out to be too conservative, we at least > > >>> need that behaviour for combinations involving a bare symbol > > >>> and a section anchor. > > >> > > >> This sounds complicated (for this stage). Do you have any statistics as > > >> to how it affects actual alias queries (thus outcome in > > >> {true,...}_dependence) > > >> when you do the "simple" fix? > > > > > > For a stage3 build of gcc on aarch64-linux-gnu I get: > > > > > > ("positive" == conflict, "negative" == no conflict) > > > > > > 16191 cmp == 1, disjoint offsets : true negative > > > 19698 cmp == 1, overlapping offsets : true positive > > > 79363 cmp == -1, disjoint offsets : true negative > > > 6965 cmp == -1, disjoint offsets : false negative <== bug > > > 48 cmp == -1, overlapping offsets : true positive > > > 928 cmp == -1, overlapping offsets : false positive <== missed opt > > > 123193 total queries > > > > > > where the cmp == -1 cases are divided into true and false results > > > according to whether we get the same answer when taking the (hopefully) > > > correct offset into account. cmp == 0 and what would be cmp == -2 never > > > occured. > > > > > > So it looks like we're relying on the cmp == -1 offset_overlap_p > > > check to get true "no conflict" results for ~64% of all queries > > > (or ~83% of all true "no conflict" results). I expect this is > > > very dependent on the fact that the port uses section anchors. > > > > > > The number of buggy cases seems surprisingly high, but I've tried > > > to re-check it a couple of times and it looks to be accurate. > > > They come from cases where we compare things like: > > > > > > x: (symbol_ref:DI ("*.LANCHOR0") [flags 0x182]) > > > y: (symbol_ref:DI ("_ZL23yy_last_accepting_state") [flags 0x82] <var_decl > > > ... yy_last_accepting_state>) > > > c: -48 > > > > > > where yy_last_accepting_state is at offset 48 from the anchor. > > > I haven't checked where the buggy queries are coming from though; > > > might be debug-related and so hard to spot. > > > > > > Thanks, > > > Richard