s390.c (s390_register_info): Make the call-saved FPR loop to work also for 31bit...
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>
Mon, 7 Oct 2013 07:52:25 +0000 (07:52 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Mon, 7 Oct 2013 07:52:25 +0000 (07:52 +0000)
2013-10-07  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

* config/s390/s390.c (s390_register_info): Make the call-saved FPR
loop to work also for 31bit ABI.
Save the stack pointer for frame_size > 0.

2013-10-07  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

* gcc.target/s390/htm-nofloat-2.c: New testcase.

From-SVN: r203240

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/htm-nofloat-2.c [new file with mode: 0644]

index d91beec..d54cf03 100644 (file)
@@ -1,5 +1,11 @@
 2013-10-07  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
+       * config/s390/s390.c (s390_register_info): Make the call-saved FPR
+       loop to work also for 31bit ABI.
+       Save the stack pointer for frame_size > 0.
+
+2013-10-07  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
        * config/s390/s390.md ("tbegin", "tbegin_nofloat", "tbegin_retry")
        ("tbegin_retry_nofloat", "tend", "tabort", "tx_assist"): Remove
        constraint letters from expanders.
index 898e683..338a09e 100644 (file)
@@ -7509,8 +7509,11 @@ s390_register_info (int clobbered_regs[])
     {
       cfun_frame_layout.fpr_bitmap = 0;
       cfun_frame_layout.high_fprs = 0;
-      if (TARGET_64BIT)
-       for (i = FPR8_REGNUM; i <= FPR15_REGNUM; i++)
+
+      for (i = FPR0_REGNUM; i <= FPR15_REGNUM; i++)
+       {
+         if (call_really_used_regs[i])
+           continue;
          /* During reload we have to use the df_regs_ever_live infos
             since reload is marking FPRs used as spill slots there as
             live before actually making the code changes.  Without
@@ -7523,8 +7526,11 @@ s390_register_info (int clobbered_regs[])
              && !global_regs[i])
            {
              cfun_set_fpr_save (i);
-             cfun_frame_layout.high_fprs++;
+
+             if (i >= FPR8_REGNUM)
+               cfun_frame_layout.high_fprs++;
            }
+       }
     }
 
   for (i = 0; i < 16; i++)
@@ -7554,6 +7560,7 @@ s390_register_info (int clobbered_regs[])
        || TARGET_TPF_PROFILING
        || cfun_save_high_fprs_p
        || get_frame_size () > 0
+       || (reload_completed && cfun_frame_layout.frame_size > 0)
        || cfun->calls_alloca
        || cfun->stdarg);
 
@@ -7652,14 +7659,6 @@ s390_register_info (int clobbered_regs[])
            cfun_set_fpr_save (i + FPR0_REGNUM);
        }
     }
-
-  if (!TARGET_64BIT)
-    {
-      if (df_regs_ever_live_p (FPR4_REGNUM) && !global_regs[FPR4_REGNUM])
-       cfun_set_fpr_save (FPR4_REGNUM);
-      if (df_regs_ever_live_p (FPR6_REGNUM) && !global_regs[FPR6_REGNUM])
-       cfun_set_fpr_save (FPR6_REGNUM);
-    }
 }
 
 /* Fill cfun->machine with info about frame of current function.  */
index 5dccbe7..2d3561d 100644 (file)
@@ -1,5 +1,9 @@
 2013-10-07  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
+       * gcc.target/s390/htm-nofloat-2.c: New testcase.
+
+2013-10-07  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
        * gcc.target/s390/htm-1.c: Add more tests to cover different
        operand types.
 
diff --git a/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c b/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c
new file mode 100644 (file)
index 0000000..db90642
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -mhtm -Wa,-march=zEC12 --save-temps" } */
+
+/* __builtin_tbegin has to emit clobbers for all FPRs since the tbegin
+   instruction does not automatically preserves them.  If the
+   transaction body is fully contained in a function the backend tries
+   after reload to get rid of the FPR save/restore operations
+   triggered by the clobbers.  This testcase failed since the backend
+   was able to get rid of all FPR saves/restores and since these were
+   the only stack operations also of the entire stack space.  So even
+   the save/restore of the stack pointer was omitted in the end.
+   However, since the frame layout has been fixed before, the prologue
+   still generated the stack pointer decrement making foo return with
+   a modified stack pointer.  */
+
+void abort(void);
+
+void __attribute__((noinline))
+foo (int a)
+{
+  /* This is just to prevent the tbegin code from actually being
+     executed.  That way the test may even run on machines prior to
+     zEC12.  */
+  if (a == 42)
+    return;
+
+  if (__builtin_tbegin (0) == 0)
+    __builtin_tend ();
+}
+
+#ifdef __s390x__
+#define GET_STACK_POINTER(SP)                  \
+  asm volatile ("stg %%r15, %0" : "=QRST" (SP));
+#else
+#define GET_STACK_POINTER(SP)                  \
+  asm volatile ("st %%r15, %0" : "=QR" (SP));
+#endif
+
+int main(void)
+{
+  unsigned long new_sp, old_sp;
+
+  GET_STACK_POINTER (old_sp);
+  foo(42);
+  GET_STACK_POINTER (new_sp);
+
+  if (old_sp != new_sp)
+    abort ();
+
+  return 0;
+}
+
+/* Make sure no FPR saves/restores are emitted.  */
+/* { dg-final { scan-assembler-not "\tstd\t" } } */
+/* { dg-final { scan-assembler-not "\tld\t" } } */