[Bug rtl-optimization/49330] Integer arithmetic on addresses optimised with pointer arithmetic rules

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Jan 8 15:24:00 GMT 2019


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


More information about the Gcc-bugs mailing list