aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/s390/s390.c62
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/s390/pr89952.c12
4 files changed, 86 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1c70df7..6d09649 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2019-04-24 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ PR target/89952
+ * config/s390/s390.c (s390_restore_gprs_from_fprs): Restore GPRs
+ from FPRs in reverse order. Generate REG_CFA_DEF_CFA note also
+ for restored hard frame pointer.
+ (s390_sched_dependencies_evaluation): Implement new target hook.
+ (TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK): New macro definition.
+
2019-04-24 Claudiu Zissulescu <claziss@sysnopsys.com>
* config/arc/arc-options.def: Fix typos and spelling mistakes.
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index ad8eacd..fc4571d 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -10685,7 +10685,11 @@ s390_restore_gprs_from_fprs (void)
if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf)
return;
- for (i = 6; i < 16; i++)
+ /* Restore the GPRs starting with the stack pointer. That way the
+ stack pointer already has its original value when it comes to
+ restoring the hard frame pointer. So we can set the cfa reg back
+ to the stack pointer. */
+ for (i = STACK_POINTER_REGNUM; i >= 6; i--)
{
rtx_insn *insn;
@@ -10701,7 +10705,13 @@ s390_restore_gprs_from_fprs (void)
df_set_regs_ever_live (i, true);
add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, i));
- if (i == STACK_POINTER_REGNUM)
+
+ /* If either the stack pointer or the frame pointer get restored
+ set the CFA value to its value at function start. Doing this
+ for the frame pointer results in .cfi_def_cfa_register 15
+ what is ok since if the stack pointer got modified it has
+ been restored already. */
+ if (i == STACK_POINTER_REGNUM || i == HARD_FRAME_POINTER_REGNUM)
add_reg_note (insn, REG_CFA_DEF_CFA,
plus_constant (Pmode, stack_pointer_rtx,
STACK_POINTER_OFFSET));
@@ -16294,6 +16304,49 @@ s390_case_values_threshold (void)
return default_case_values_threshold ();
}
+/* Evaluate the insns between HEAD and TAIL and do back-end to install
+ back-end specific dependencies.
+
+ Establish an ANTI dependency between r11 and r15 restores from FPRs
+ to prevent the instructions scheduler from reordering them since
+ this would break CFI. No further handling in the sched_reorder
+ hook is required since the r11 and r15 restore will never appear in
+ the same ready list with that change. */
+void
+s390_sched_dependencies_evaluation (rtx_insn *head, rtx_insn *tail)
+{
+ if (!frame_pointer_needed || !epilogue_completed)
+ return;
+
+ while (head != tail && DEBUG_INSN_P (head))
+ head = NEXT_INSN (head);
+
+ rtx_insn *r15_restore = NULL, *r11_restore = NULL;
+
+ for (rtx_insn *insn = tail; insn != head; insn = PREV_INSN (insn))
+ {
+ rtx set = single_set (insn);
+ if (!INSN_P (insn)
+ || !RTX_FRAME_RELATED_P (insn)
+ || set == NULL_RTX
+ || !REG_P (SET_DEST (set))
+ || !FP_REG_P (SET_SRC (set)))
+ continue;
+
+ if (REGNO (SET_DEST (set)) == HARD_FRAME_POINTER_REGNUM)
+ r11_restore = insn;
+
+ if (REGNO (SET_DEST (set)) == STACK_POINTER_REGNUM)
+ r15_restore = insn;
+ }
+
+ if (r11_restore == NULL || r15_restore == NULL)
+ return;
+ add_dependence (r11_restore, r15_restore, REG_DEP_ANTI);
+}
+
+
+
/* Initialize GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
@@ -16585,6 +16638,11 @@ s390_case_values_threshold (void)
#undef TARGET_CASE_VALUES_THRESHOLD
#define TARGET_CASE_VALUES_THRESHOLD s390_case_values_threshold
+#undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
+#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \
+ s390_sched_dependencies_evaluation
+
+
/* Use only short displacement, since long displacement is not available for
the floating point instructions. */
#undef TARGET_MAX_ANCHOR_OFFSET
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 42e7516..6a34f20 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-04-24 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ PR target/89952
+ * gcc.target/s390/pr89952.c: New test.
+
2019-04-24 Jakub Jelinek <jakub@redhat.com>
PR target/90187
diff --git a/gcc/testsuite/gcc.target/s390/pr89952.c b/gcc/testsuite/gcc.target/s390/pr89952.c
new file mode 100644
index 0000000..9f48e08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr89952.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=zEC12 -fno-omit-frame-pointer -Os" } */
+
+
+extern void j(int);
+
+void
+d(int e, long f, int g, int h, int i) {
+ if (h == 5 && i >= 4 && i <= 7)
+ h = e;
+ j(h);
+}