diff options
author | Wilco Dijkstra <wdijkstr@arm.com> | 2017-10-26 16:34:03 +0000 |
---|---|---|
committer | Wilco Dijkstra <wilco@gcc.gnu.org> | 2017-10-26 16:34:03 +0000 |
commit | 37e4d57b99efe65710bb4a000093c596ab3f5124 (patch) | |
tree | c50f11ebc27468dce659470f8cae33c57099bdf4 /gcc | |
parent | 9eaf97d6d7f1511638fb9209b7acf30e8f26a060 (diff) | |
download | gcc-37e4d57b99efe65710bb4a000093c596ab3f5124.zip gcc-37e4d57b99efe65710bb4a000093c596ab3f5124.tar.gz gcc-37e4d57b99efe65710bb4a000093c596ab3f5124.tar.bz2 |
Improve addressing of TI/TFmode
In https://gcc.gnu.org/ml/gcc-patches/2017-06/msg01125.html Jiong
pointed out some addressing inefficiencies due to a recent change in
regcprop (https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00775.html).
This patch improves aarch64_legitimize_address_displacement to split
unaligned offsets of TImode and TFmode accesses. The resulting code
is better and no longer relies on the original regcprop optimization.
For the test we now produce:
add x1, sp, 4
stp xzr, xzr, [x1, 24]
rather than:
mov x1, sp
add x1, x1, 28
stp xzr, xzr, [x1]
gcc/
* config/aarch64/aarch64.c (aarch64_legitimize_address_displacement):
Improve unaligned TImode/TFmode base/offset split.
testsuite/
* gcc.target/aarch64/ldp_stp_unaligned_2.c: New file.
From-SVN: r254111
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c | 18 |
4 files changed, 35 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4d5c9d2..7e0417b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2017-10-26 Wilco Dijkstra <wdijkstr@arm.com> + + * config/aarch64/aarch64.c (aarch64_legitimize_address_displacement): + Improve unaligned TImode/TFmode base/offset split. + 2017-10-26 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index d1aaf19..83630fc 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -4727,16 +4727,20 @@ aarch64_legitimate_address_p (machine_mode mode, rtx x, /* Split an out-of-range address displacement into a base and offset. Use 4KB range for 1- and 2-byte accesses and a 16KB range otherwise to increase opportunities for sharing the base address of different sizes. - For unaligned accesses and TI/TF mode use the signed 9-bit range. */ + Unaligned accesses use the signed 9-bit range, TImode/TFmode use + the intersection of signed scaled 7-bit and signed 9-bit offset. */ static bool aarch64_legitimize_address_displacement (rtx *disp, rtx *off, machine_mode mode) { HOST_WIDE_INT offset = INTVAL (*disp); - HOST_WIDE_INT base = offset & ~(GET_MODE_SIZE (mode) < 4 ? 0xfff : 0x3ffc); + HOST_WIDE_INT base; - if (mode == TImode || mode == TFmode - || (offset & (GET_MODE_SIZE (mode) - 1)) != 0) + if (mode == TImode || mode == TFmode) + base = (offset + 0x100) & ~0x1f8; + else if ((offset & (GET_MODE_SIZE (mode) - 1)) != 0) base = (offset + 0x100) & ~0x1ff; + else + base = offset & ~(GET_MODE_SIZE (mode) < 4 ? 0xfff : 0x3ffc); *off = GEN_INT (base); *disp = GEN_INT (offset - base); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 01824b3..283c787 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-10-26 Wilco Dijkstra <wdijkstr@arm.com> + + * gcc.target/aarch64/ldp_stp_unaligned_2.c: New file. + 2017-10-26 James Greenhalgh <james.greenhalgh@arm.com> * gcc.target/arm/require-pic-register-loc.c: Use wider regex for diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c new file mode 100644 index 0000000..1e46755 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c @@ -0,0 +1,18 @@ +/* { dg-options "-O2 -fomit-frame-pointer" } */ + +/* Check that we split unaligned LDP/STP into base and aligned offset. */ + +typedef struct +{ + int a, b, c, d, e; +} S; + +void foo (S *); + +void test (int x) +{ + S s = { .a = x }; + foo (&s); +} + +/* { dg-final { scan-assembler-not "mov\tx\[0-9\]+, sp" } } */ |