This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, rtl-optimization] Fix PR63475, Postreload CSE propagates aliased memory operand


Hello!

Attached patch fixes PR63475, where postreload CSE propagates aliased
memory operand.

The core of the problem was with the call to base_alias_check when
VALUE RTXes are involved. Before the call, find_base_term is used to
extract the base of x_addr and mem_addr. Please note that
find_base_term is able to extract the bases from VALUE RTXes. These
extracted bases were passed to base_alias_check, together with
original VALUE RTXes x_addr and mem_addr.

The problem begins here. base_alias_check doesn't handle VALUE RTXes,
and uses e.g. canon_rtx on VALUEs and various GET_CODE accessors to
determine various properties of passed x_addr and mem_addr. One of
these check checks for the AND alignment addresses to prevent:

  /* Differing symbols not accessed via AND never alias.  */
  if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
    return 0;

early exit. However, when x and y are passed as VALUE RTXes (that
corresponds and hides the address with AND), and preceding calls to
find_base_term are nevertheless able to extract the bases of x and y,
this condition fires erroneously and invalid return value is returned
(with 0 meaning that the addresses X and Y are known to point to
different objects).

The solution is to always extract values for x_addr and mem_addr and
use them in the calls to find_base_term and base_alias_check.

[It can happen that get_addr is not able to match VALUE RTX with some
address, so it is not possible to simply add a bunch of "GET_CODE (x)
!= VALUE" asserts in base_alias_check. But in this case find_base_term
returns ADDRESS RTX, so we stay in sync as far as base_alias_check is
concerned (see the quoted code above).]

Added benefit of the patch is, that canon_rtx now works as expected.
canon_rtx does NOT handle VALUE RTXes.

A small optimization is also present. If the address is already
canonicalized, we pass original address to memrefs_conflict_p, but we
have to extract original address for preceding functions nevertheless.
Also, we use extracted original address in recently added check for
AND aligned addresses when checking for MEM_READONLY_P.

The patch also removes a couple of unneeded and unused calls to
canon_rtx, also to show the level of bitrot in this area ...

2014-10-14  Uros Bizjak  <ubizjak@gmail.com>

    PR rtl-optimization/63475
    * alias.c (true_dependence_1): Always use get_addr to extract
    true address operands from x_addr and mem_addr.  Use extracted
    address operands to check for references with alignment ANDs.
    Use extracted address operands with find_base_term and
    base_alis_check. For noncanonicalized operands call canon_rtx with
    extracted address operand.
    (write_dependence_1): Ditto.
    (may_alias_p): Ditto.  Remove unused calls to canon_rtx.

Patch was thoroughly tested on x86_64-linux-gnu {,-m32} and
alpha-linux-gnu for all default languages plus obj-c++ and go. While
there was no differences on x86_64-linux-gnu (as expected),
alpha-linux-gnu improved the result [1] for some hundred of PASSes in
gfortran testsuite [2].

OK for mainline?

[1] https://gcc.gnu.org/ml/gcc-testresults/2014-10/msg01151.html
[2] https://gcc.gnu.org/ml/gcc-testresults/2014-10/msg01478.html

Uros.

Attachment: alias-7.diff.txt
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]