https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49330
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed|2018-06-04 00:00:00 |2019-1-8 Known to fail| |9.0 --- Comment #18 from Richard Biener <rguenth at gcc dot gnu.org> --- 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