aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2020-07-03 13:49:51 +0800
committerKito Cheng <kito.cheng@sifive.com>2020-07-09 14:29:29 +0800
commit4c0d1322033ce979532425d336530b217f6b5fd3 (patch)
tree2231cca0d2c4bb3fd18d79df4ae435364f8edcf8 /gcc
parent50873cc588fcc20384212b6dddca74393023a0e3 (diff)
downloadgcc-4c0d1322033ce979532425d336530b217f6b5fd3.zip
gcc-4c0d1322033ce979532425d336530b217f6b5fd3.tar.gz
gcc-4c0d1322033ce979532425d336530b217f6b5fd3.tar.bz2
RISC-V: Disable remove unneeded save-restore call optimization if there are any arguments on stack.
- This optimization will adjust stack, but it not check/update other stack pointer use-site, the example is when the arguments put on stack, the offset become wrong after optimization. - However adjust stack frame usage after register allocation could be error prone, so we decide to turn off this optimization for such case. - Ye-Ting Kuo report this issue on github: https://github.com/riscv/riscv-gcc/pull/192 gcc/ChangeLog: * config/riscv/riscv-sr.c (riscv_remove_unneeded_save_restore_calls): Abort if any arguments on stack. gcc/testsuite/ChangeLog * gcc.target/riscv/save-restore-9.c: New.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/riscv-sr.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/save-restore-9.c23
2 files changed, 29 insertions, 0 deletions
diff --git a/gcc/config/riscv/riscv-sr.c b/gcc/config/riscv/riscv-sr.c
index 9af50ef..694f90c 100644
--- a/gcc/config/riscv/riscv-sr.c
+++ b/gcc/config/riscv/riscv-sr.c
@@ -244,6 +244,12 @@ check_for_no_return_call (rtx_insn *prologue)
void
riscv_remove_unneeded_save_restore_calls (void)
{
+ /* We'll adjust stack size after this optimization, that require update every
+ sp use site, which could be unsafe, so we decide to turn off this
+ optimization if there are any arguments put on stack. */
+ if (crtl->args.size != 0)
+ return;
+
/* Will point to the first instruction of the function body, after the
prologue end note. */
rtx_insn *body = NULL;
diff --git a/gcc/testsuite/gcc.target/riscv/save-restore-9.c b/gcc/testsuite/gcc.target/riscv/save-restore-9.c
new file mode 100644
index 0000000..2567dae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/save-restore-9.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msave-restore" } */
+
+int
+__attribute__((noinline,noclone))
+foo (int u)
+{
+ return u + 1;
+}
+
+int
+__attribute__((noinline,noclone))
+bar (int a, int b, int c, int d, int e, int f, int g, int h, int u)
+{
+ return foo (u);
+}
+
+int main()
+{
+ if (bar (1, 2, 3, 4, 5, 6, 7, 8, 9) != 10)
+ __builtin_abort();
+ return 0;
+}