aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorWilco Dijkstra <wdijkstr@arm.com>2017-10-26 16:34:03 +0000
committerWilco Dijkstra <wilco@gcc.gnu.org>2017-10-26 16:34:03 +0000
commit37e4d57b99efe65710bb4a000093c596ab3f5124 (patch)
treec50f11ebc27468dce659470f8cae33c57099bdf4 /gcc
parent9eaf97d6d7f1511638fb9209b7acf30e8f26a060 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/config/aarch64/aarch64.c12
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c18
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" } } */