summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/gcc.target/s390/htm-nofloat-1.c')
-rw-r--r--gcc/testsuite/gcc.target/s390/htm-nofloat-1.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c b/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c
new file mode 100644
index 0000000000..6022efb97f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-require-effective-target htm } */
+/* { dg-options "-O3 -march=zEC12 -mzarch --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)
+{
+ 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" } } */