Improve addressing of TI/TFmode
authorWilco Dijkstra <wdijkstr@arm.com>
Thu, 26 Oct 2017 16:34:03 +0000 (16:34 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Thu, 26 Oct 2017 16:34:03 +0000 (16:34 +0000)
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

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c [new file with mode: 0644]

index 4d5c9d2c66a2a98e04d096d469b39be016a6f01c..7e0417ba60ca72842b9093917e5417adb40c2945 100644 (file)
@@ -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>
index d1aaf19038a061b601e9584ec41f399417b498db..83630fce1cce85b4d5beece2fa303ab09b9ac4dd 100644 (file)
@@ -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);
index 01824b3249df54609dfe4b0eff8f185e54d68911..283c78718a9724b045c71a39a8158405a0cdb616 100644 (file)
@@ -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 (file)
index 0000000..1e46755
--- /dev/null
@@ -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" } } */