This patch add testcases for various aarch64 prologue/epilogue scenarios.

It will make sure our later frame code refine and improvement will not cause 
any regression.

OK for trunk?

Thanks.

gcc/testsuite/
 * gcc.target/aarch64/test_frame_common.h: New pattern file.
  * gcc.target/aarch64/test_frame_1.c: New testcase.
  * gcc.target/aarch64/test_frame_2.c: Likewise.
  * gcc.target/aarch64/test_frame_3.c: Likewise.
  * gcc.target/aarch64/test_frame_4.c: Likewise.
  * gcc.target/aarch64/test_frame_5.c: Likewise.
  * gcc.target/aarch64/test_frame_6.c: Likewise.
  * gcc.target/aarch64/test_frame_7.c: Likewise.
  * gcc.target/aarch64/test_frame_8.c: Likewise.
  * gcc.target/aarch64/test_frame_9.c: Likewise.
  * gcc.target/aarch64/test_frame_10.c: Likewise.
  * gcc.target/aarch64/test_frame_11.c: Likewise.
  * gcc.target/aarch64/test_frame_12.c: Likewise.
  * gcc.target/aarch64/test_frame_13.c: Likewise.
  * gcc.target/aarch64/test_frame_14.c: Likewise.
  * gcc.target/aarch64/test_frame_15.c: Likewise.
commit ec07ddf26d31696b61d6ffbff52227bb5e86bd2a
Author: Jiong Wang <jiong.w...@arm.com>
Date:   Fri Jun 6 10:18:19 2014 +0100

    [AArch64] Add a set of stack layout testcases.
    
      The following patch set will do various pro/epi code refine
    and optimization.
    
      Before these, we check in a set of testcases to guarantee no
    regression is caused by our following work.

diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_1.c b/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
new file mode 100644
index 0000000..feea7a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
@@ -0,0 +1,14 @@
+/* Verify:
+     * -fomit-frame-pointer.
+     * withoug outgoing.
+     * total frame size <= 256.
+     * number of callee-save reg == 1.
+     * optimized code should use "str !" for stack adjustment.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern (test1, 200, )
+t_frame_run (test1)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_10.c b/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
new file mode 100644
index 0000000..2892c5f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
@@ -0,0 +1,16 @@
+/* Verify:
+     * -fomit-frame-pointer.
+     * with outgoing.
+     * total frame size > 512.
+       area except outgoing <= 512
+     * number of callee-saved reg >= 2.
+     * Split stack adjustment into two subtractions.
+       the first subtractions could be optimized into "stp !".  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern_outgoing (test10, 480, "x19", 24, a[8], a[9], a[10])
+t_frame_run (test10)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_11.c b/gcc/testsuite/gcc.target/aarch64/test_frame_11.c
new file mode 100644
index 0000000..8b860dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_11.c
@@ -0,0 +1,16 @@
+/* Verify:
+     * without outgoing.
+     * total frame size <= 512.
+     * number of callee-save reg >= 2.
+     * optimized code should use "stp !" for stack adjustment.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern (test11, 400, )
+t_frame_run (test11)
+
+/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_12.c b/gcc/testsuite/gcc.target/aarch64/test_frame_12.c
new file mode 100644
index 0000000..3649527
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_12.c
@@ -0,0 +1,15 @@
+/* Verify:
+     * with outgoing.
+     * total frame size <= 512.
+     * number of callee-save reg >= 2.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern_outgoing (test12, 400, , 8, a[8])
+t_frame_run (test12)
+
+/* { dg-final { scan-assembler-times "sub\tsp, sp, #\[0-9\]+" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_13.c b/gcc/testsuite/gcc.target/aarch64/test_frame_13.c
new file mode 100644
index 0000000..25df08b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_13.c
@@ -0,0 +1,18 @@
+/* Verify:
+     * without outgoing.
+     * total frame size > 512.
+     * number of callee-save reg >= 2.
+     * split the stack adjustment into two substractions,
+       the second could be optimized into "stp !".  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern (test13, 700, )
+t_frame_run (test13)
+
+/* { dg-final { scan-assembler-times "sub\tsp, sp, #\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_14.c b/gcc/testsuite/gcc.target/aarch64/test_frame_14.c
new file mode 100644
index 0000000..78818de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_14.c
@@ -0,0 +1,12 @@
+/* Verify:
+     * with outgoing.
+     * total frame size > 512.
+     * number of callee-save reg >= 2.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern_outgoing (test14, 700, , 8, a[8])
+t_frame_run (test14)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_15.c b/gcc/testsuite/gcc.target/aarch64/test_frame_15.c
new file mode 100644
index 0000000..7ab1f20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_15.c
@@ -0,0 +1,19 @@
+/* Verify:
+     * with outgoing.
+     * total frame size > 512.
+       area except outgoing <= 512
+     * number of callee-save reg >= 2.
+     * split the stack adjustment into two substractions,
+       the first could be optimized into "stp !".  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern_outgoing (test15, 480, , 8, a[8])
+t_frame_run (test15)
+
+/* { dg-final { scan-assembler-times "sub\tsp, sp, #\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 3 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_2.c b/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
new file mode 100644
index 0000000..aa15dae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
@@ -0,0 +1,14 @@
+/* Verify:
+     * -fomit-frame-pointer.
+     * without outgoing.
+     * total frame size <= 256.
+     * number of callee-save regs >= 2.
+     * optimized code should use "stp !" for stack adjustment.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern (test2, 200, "x19")
+t_frame_run (test2)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_3.c b/gcc/testsuite/gcc.target/aarch64/test_frame_3.c
new file mode 100644
index 0000000..f90ea4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_3.c
@@ -0,0 +1,14 @@
+/* Verify:
+     * -fomit-frame-pointer.
+     * without outgoing.
+     * total frame size <= 512 but > 256.
+     * number of callee-save reg == 1.
+     * we can't use "str !" to optimize stack adjustment.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern (test3, 400, )
+t_frame_run (test3)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_4.c b/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
new file mode 100644
index 0000000..c45e740
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
@@ -0,0 +1,14 @@
+/* Verify:
+     * -fomit-frame-pointer.
+     * without outgoing.
+     * total frame size <= 512 but > 256.
+     * number of callee-save reg >= 2.
+     * we can use "stp !" to optimize stack adjustment.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern (test4, 400, "x19")
+t_frame_run (test4)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_5.c b/gcc/testsuite/gcc.target/aarch64/test_frame_5.c
new file mode 100644
index 0000000..0624b5b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_5.c
@@ -0,0 +1,13 @@
+/* Verify:
+     * -fomit-frame-pointer.
+     * with outgoing.
+     * total frame size <= 512.
+     * one subtraction of the whole frame size.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern_outgoing (test5, 300, "x19", 8, a[8])
+t_frame_run (test5)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_6.c b/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
new file mode 100644
index 0000000..54f646b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
@@ -0,0 +1,15 @@
+/* Verify:
+     * -fomit-frame-pointer.
+     * without outgoing.
+     * total frame size > 512.
+     * number of callee-saved reg == 1.
+     * split stack adjustment into two subtractions.
+       the second subtraction should use "str !".  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern (test6, 700, )
+t_frame_run (test6)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_7.c b/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
new file mode 100644
index 0000000..aa97bc0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
@@ -0,0 +1,15 @@
+/* Verify:
+     * -fomit-frame-pointer.
+     * without outgoing.
+     * total frame size > 512.
+     * number of callee-saved reg == 2.
+     * split stack adjustment into two subtractions.
+       the second subtraction should use "stp !".  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern (test7, 700, "x19")
+t_frame_run (test7)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_8.c b/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
new file mode 100644
index 0000000..f75f080
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
@@ -0,0 +1,13 @@
+/* Verify:
+     * -fomit-frame-pointer.
+     * with outgoing.
+     * total frame size bigger than 512.
+     * number of callee-saved reg == 1.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern_outgoing (test8, 700, , 8, a[8])
+t_frame_run (test8)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_9.c b/gcc/testsuite/gcc.target/aarch64/test_frame_9.c
new file mode 100644
index 0000000..0dffbf8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_9.c
@@ -0,0 +1,17 @@
+/* Verify:
+     * -fomit-frame-pointer.
+     * with outgoing.
+     * total frame size > 512.
+       area except outgoing <= 512
+     * number of callee-saved reg = 1.
+     * Split stack adjustment into two subtractions.
+       the first subtractions couldn't be optimized
+       into "str !" as it's > 256.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+#include "test_frame_common.h"
+
+t_frame_pattern_outgoing (test9, 480, , 24, a[8], a[9], a[10])
+t_frame_run (test9)
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_common.h b/gcc/testsuite/gcc.target/aarch64/test_frame_common.h
new file mode 100644
index 0000000..d7fed25
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_common.h
@@ -0,0 +1,94 @@
+extern void abort ();
+
+#define CVT(v) ((unsigned char)(v))
+
+static void __attribute__((noinline))
+check_args_8 (int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+	      int a8)
+{
+  if (a0 != 0
+      || a1 != 1
+      || a2 != 2
+      || a3 != 3
+      || a4 != 4
+      || a5 != 5
+      || a6 != 6
+      || a7 != 7
+      || a8 != 8)
+    abort ();
+}
+
+static void __attribute__((noinline))
+check_args_24 (int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+	       int a8, int a9, int a10)
+{
+  if (a0 != 0
+      || a1 != 1
+      || a2 != 2
+      || a3 != 3
+      || a4 != 4
+      || a5 != 5
+      || a6 != 6
+      || a7 != 7
+      || a8 != 8
+      || a9 != 9
+      || a10 != 10)
+    abort ();
+}
+
+void __attribute__ ((noinline))
+initialize_array (unsigned char *a, int len)
+{
+  int i;
+
+  for (i = 0; i < (len / 2); i++)
+    {
+      a[i] = i;
+      a[len - i - 1] = i;
+    }
+
+  return;
+}
+
+#define t_frame_pattern(name, local_size, callee_saved)\
+int \
+name (void)\
+{\
+  unsigned char a[local_size];\
+  initialize_array (a, local_size); \
+  __asm__ ("":::callee_saved); \
+  if (a[0] != a[local_size - 1] \
+      || a[0] != 0) \
+    return 0; \
+  if (a[local_size / 2 - 1] != a[local_size / 2] \
+      || a[local_size / 2 - 1] != CVT (local_size / 2 - 1)) \
+    return 0; \
+  return 1; \
+}
+
+#define t_frame_pattern_outgoing(name, local_size, callee_saved, out_going_num, ...)\
+int \
+name (void)\
+{\
+  unsigned char a[local_size];\
+  initialize_array (a, local_size); \
+  __asm__ ("":::callee_saved); \
+  if (a[0] != a[local_size - 1] \
+      || a[0] != 0) \
+    return 0; \
+  if (a[local_size / 2 - 1] != a[local_size / 2] \
+      || a[local_size / 2 - 1] != CVT (local_size / 2 - 1)) \
+    return 0; \
+  check_args_ ## out_going_num (a[0], a[1], a[2], a[3], a[4], a[5], a[6],\
+				a[7], __VA_ARGS__); \
+  return 1; \
+}
+
+#define t_frame_run(name) \
+int \
+main (int argc, char **argv) \
+{\
+  if (!name ())\
+    abort ();\
+  return 0;\
+}

Reply via email to