https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49330
--- Comment #19 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Richard Biener from comment #18) > So for find_base_term to compute sth conservative we'd need to track > RTX_SURELY_NON_POINTER (what RTX is surely _not_ based on a pointer > and thus can be ignored). And when find_base_term ever figures > two bases in say a PLUS it has to conservatively return 0. > > I fear the existing REG_POINTER does not help at all. For the testcase > we have > > (plus:DI (reg:DI 83 [ d.0_2 ]) > (symbol_ref:DI ("y") [flags 0x2] <var_decl 0x7ffff7fefb40 y>)) > > where reg:DI 83 is not marked with REG_POINTER and find_base_term > doesn't find it to be an alternate base. For the testcase the > offending MEM has a MEM_EXPR and we have proper points-to info. > > IMHO the proper solution is to kill base_alias_check or all problematic > cases in find_base_term (binary ops with more than one non-CONST_INT > operand). > > And eventually make sure to more properly preserve MEM_EXPRs. > > Maybe sth as "simple" as the following which of course fixes the > testcase but will make find_base_term fail on any variable-indexed > thing. > > diff --git a/gcc/alias.c b/gcc/alias.c > index 93f53543d12..3a66e10b431 100644 > --- a/gcc/alias.c > +++ b/gcc/alias.c > @@ -2009,12 +2009,14 @@ find_base_term (rtx x, vec<std::pair<cselib_val *, > rtx base = find_base_term (tmp1, visited_vals); > if (base != NULL_RTX > && ((REG_P (tmp1) && REG_POINTER (tmp1)) > - || known_base_value_p (base))) > + || known_base_value_p (base)) > + && CONST_INT_P (tmp2)) > return base; > base = find_base_term (tmp2, visited_vals); > if (base != NULL_RTX > && ((REG_P (tmp2) && REG_POINTER (tmp2)) > - || known_base_value_p (base))) > + || known_base_value_p (base)) > + && CONST_INT_P (tmp1)) > return base; > > /* We could not determine which of the two operands was the "benchmarking" this by comparing cc1 with/without shows a difference mostly in scheduling (but the number of differences is comparatively small!). Also overall text size shrinks with the patch (whatever that means). On GIMPLE we try hard to not construct addresses "based" on the wrong object, in fact IVOPTs has code to avoid building IVs based on things like &a - &b and propagation avoids turning unintptr_t arithmetic into pointer arithmetic even if it can see the converted from addresses. All those things cannot be done on RTL since we lost the distinction between pointers and integers and there's only PLUS. So I have a _very_ hard time seeing how RTL can ever be fixed to discover bases for alias analysis purposes without just resorting to MEM_EXPRs. That is, unless we want to live with this kind of wrong-code bugs. Similarly fishy is may_be_sp_based_p.