[Patch] [arm] Fix 88714, Arm LDRD/STRD peepholes.
authorMatthew Malcomson <matthew.malcomson@arm.com>
Thu, 7 Feb 2019 14:54:15 +0000 (14:54 +0000)
committerMatthew Malcomson <matmal01@gcc.gnu.org>
Thu, 7 Feb 2019 14:54:15 +0000 (14:54 +0000)
commitc272bbda1af0f316c4c5e9a1d8b4d673c3b1bf58
treeec4335dc698fef1ba45737328212801e6b2a8115
parent5eb9ac1e272c9bcdc17dd0b7d4707e70021a4483
[Patch] [arm] Fix 88714, Arm LDRD/STRD peepholes.

These peepholes match a pair of SImode loads or stores that can be
implemented with a single LDRD or STRD instruction.
When compiling for TARGET_ARM, these peepholes originally created a set
pattern in DI mode to be caught by movdi patterns.

This approach failed to take into account the possibility that the two
matched insns operated on memory with different aliasing information.
The peepholes lost the aliasing information on one of the insns, which
could then cause the scheduler to make an invalid transformation.

This patch changes the peepholes so they generate a PARALLEL expression
of the two relevant loads or stores, which means the aliasing
information of both is kept.  Such a PARALLEL pattern is what the
peepholes currently produce for TARGET_THUMB2.

In order to match these new insn patterns, we add two new define_insn's.  These
define_insn's use the same checks as the peepholes to find valid insns.

Note that the patterns now created by the peepholes for LDRD and STRD
are very similar to those created by the peepholes for LDM and STM.
Many patterns could be matched by the LDM and STM define_insns, which
means we rely on the order the define_insn patterns are defined in the
machine description, with those for LDRD/STRD defined before those for
LDM/STM.

The difference between the peepholes for LDRD/STRD and those for LDM/STM
are mainly that those for LDRD/STRD have some logic to ensure that the
two registers are consecutive and the first one is even.

Bootstrapped and regtested on arm-none-linux-gnu.
Demonstrated fix of bug 88714 by bootstrapping on armv7l.

gcc/ChangeLog:

2019-02-07  Matthew Malcomson  <matthew.malcomson@arm.com>
    Jakub Jelinek  <jakub@redhat.com>

PR bootstrap/88714
* config/arm/arm-protos.h (valid_operands_ldrd_strd,
arm_count_ldrdstrd_insns): New declarations.
* config/arm/arm.c (mem_ok_for_ldrd_strd): Remove broken handling of
MINUS.
(valid_operands_ldrd_strd): New function.
(arm_count_ldrdstrd_insns): New function.
* config/arm/ldrdstrd.md: Change peepholes to generate PARALLEL SImode
sets instead of single DImode set and define new insns to match this.

gcc/testsuite/ChangeLog:

2019-02-07  Matthew Malcomson  <matthew.malcomson@arm.com>
    Jakub Jelinek  <jakub@redhat.com>

PR bootstrap/88714
* gcc.c-torture/execute/pr88714.c: New test.
* gcc.dg/rtl/arm/ldrd-peepholes.c: New test.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
From-SVN: r268644
gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/ldrdstrd.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr88714.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/rtl/arm/ldrd-peepholes.c [new file with mode: 0644]