[Committed] S/390: Fix PR89775. Stackpointer save/restore instructions removed
Andreas Krebbel
krebbel@linux.ibm.com
Wed Mar 20 16:14:00 GMT 2019
Even if a global register is being clobbered in a function we usually
do not save and restore it. However, we still have to do this if it is
a special register. Most of the places in the backend handle this
correctly but not the prologue/epilogue optimization.
Bootstrapped and regression tested on s390x.
gcc/ChangeLog:
2019-03-20 Andreas Krebbel <krebbel@linux.ibm.com>
PR target/89775
* config/s390/s390.c (global_not_special_regno_p): Move to make it
available to ...
(s390_optimize_register_info): Use global_not_special_regno_p to
check for global regs.
2019-03-20 Jakub Jelinek <jakub@redhat.com>
PR target/89775
* gcc.target/s390/pr89775-1.c: New test.
* gcc.target/s390/pr89775-2.c: New test.
---
gcc/config/s390/s390.c | 34 ++++++++++++++++---------------
gcc/testsuite/gcc.target/s390/pr89775-1.c | 17 ++++++++++++++++
gcc/testsuite/gcc.target/s390/pr89775-2.c | 25 +++++++++++++++++++++++
3 files changed, 60 insertions(+), 16 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/s390/pr89775-1.c
create mode 100644 gcc/testsuite/gcc.target/s390/pr89775-2.c
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 41f2665..5f26437 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -9588,6 +9588,21 @@ s390_register_info ()
s390_register_info_stdarg_gpr ();
}
+/* Return true if REGNO is a global register, but not one
+ of the special ones that need to be saved/restored in anyway. */
+
+static inline bool
+global_not_special_regno_p (int regno)
+{
+ return (global_regs[regno]
+ /* These registers are special and need to be
+ restored in any case. */
+ && !(regno == STACK_POINTER_REGNUM
+ || regno == RETURN_REGNUM
+ || regno == BASE_REGNUM
+ || (flag_pic && regno == (int)PIC_OFFSET_TABLE_REGNUM)));
+}
+
/* This function is called by s390_optimize_prologue in order to get
rid of unnecessary GPR save/restore instructions. The register info
for the GPRs is re-computed and the ranges are re-calculated. */
@@ -9602,8 +9617,10 @@ s390_optimize_register_info ()
s390_regs_ever_clobbered (clobbered_regs);
+ /* Global registers do not need to be saved and restored unless it
+ is one of our special regs. (r12, r13, r14, or r15). */
for (i = 0; i < 32; i++)
- clobbered_regs[i] = clobbered_regs[i] && !global_regs[i];
+ clobbered_regs[i] = clobbered_regs[i] && !global_not_special_regno_p (i);
/* There is still special treatment needed for cases invisible to
s390_regs_ever_clobbered. */
@@ -10345,21 +10362,6 @@ restore_fpr (rtx base, int offset, int regnum)
return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
}
-/* Return true if REGNO is a global register, but not one
- of the special ones that need to be saved/restored in anyway. */
-
-static inline bool
-global_not_special_regno_p (int regno)
-{
- return (global_regs[regno]
- /* These registers are special and need to be
- restored in any case. */
- && !(regno == STACK_POINTER_REGNUM
- || regno == RETURN_REGNUM
- || regno == BASE_REGNUM
- || (flag_pic && regno == (int)PIC_OFFSET_TABLE_REGNUM)));
-}
-
/* Generate insn to save registers FIRST to LAST into
the register save area located at offset OFFSET
relative to register BASE. */
diff --git a/gcc/testsuite/gcc.target/s390/pr89775-1.c b/gcc/testsuite/gcc.target/s390/pr89775-1.c
new file mode 100644
index 0000000..2c0f6fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr89775-1.c
@@ -0,0 +1,17 @@
+/* PR target/89775 */
+/* { dg-do run } */
+/* { dg-options "-O0 -fomit-frame-pointer" } */
+/* { dg-additional-sources "pr89775-2.c" } */
+
+register void *sp __asm ("15");
+
+__attribute__((noipa)) int
+foo (const char *a, const char *b)
+{
+ while (1)
+ {
+ char c = *a++;
+ if (c != *b++) return 0;
+ if (c == '\0') return 1;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/s390/pr89775-2.c b/gcc/testsuite/gcc.target/s390/pr89775-2.c
new file mode 100644
index 0000000..645661e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr89775-2.c
@@ -0,0 +1,25 @@
+/* PR target/89775 */
+/* { dg-do compile } */
+
+extern int foo (const char *, const char *);
+
+__attribute__((noipa)) void
+bar (const char *p)
+{
+ static const char *x;
+ if (!x)
+ x = p;
+ else if (p != x)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ char a[8] = "abcdefg";
+ bar (a);
+ if (foo (a, a) != 1)
+ __builtin_abort ();
+ bar (a);
+ return 0;
+}
--
2.7.4
More information about the Gcc-patches
mailing list