Re: [PATCH v3] S/390: Fix conditional returns on z196+

2018-09-24 Thread Ulrich Weigand
Ilya Leoshkevich wrote:

> gcc/ChangeLog:
> 
> 2018-09-19  Ilya Leoshkevich  
> 
>   PR target/80080
>   * config/s390/s390.c (s390_emit_epilogue): Do not use PARALLEL
>   RETURN+USE when returning via %r14.
> 
> gcc/testsuite/ChangeLog:
> 
> 2018-09-19  Ilya Leoshkevich  
> 
>   PR target/80080
>   * gcc.target/s390/risbg-ll-3.c: Expect conditional returns.
>   * gcc.target/s390/zvector/vec-cmp-2.c: Likewise.

This is OK.

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  ulrich.weig...@de.ibm.com



[PATCH v3] S/390: Fix conditional returns on z196+

2018-09-24 Thread Ilya Leoshkevich
S/390 epilogue ends with (parallel [(return) (use %r14)]) instead of
the more usual (return) or (simple_return).  This sequence is not
recognized by the conditional return logic in try_optimize_cfg ().

This was introduced for processors older than z196, where it is
sometimes profitable to use call-clobbered register for returning
instead of %r14.  On newer processors we always return via %r14,
for which the fact that it's used is already reflected by
EPILOGUE_USES.  In this case a simple (return) suffices.

This patch changes return_use () to emit simple (return)s when
returning via %r14.  The resulting sequences are recognized by the
conditional return logic in try_optimize_cfg ().

gcc/ChangeLog:

2018-09-19  Ilya Leoshkevich  

PR target/80080
* config/s390/s390.c (s390_emit_epilogue): Do not use PARALLEL
RETURN+USE when returning via %r14.

gcc/testsuite/ChangeLog:

2018-09-19  Ilya Leoshkevich  

PR target/80080
* gcc.target/s390/risbg-ll-3.c: Expect conditional returns.
* gcc.target/s390/zvector/vec-cmp-2.c: Likewise.
---
 gcc/config/s390/s390.c| 20 +---
 gcc/testsuite/gcc.target/s390/risbg-ll-3.c|  6 +--
 .../gcc.target/s390/zvector/vec-cmp-2.c   | 48 +--
 3 files changed, 41 insertions(+), 33 deletions(-)

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 541b032ac63..71039fe6ce9 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -11082,7 +11082,7 @@ s390_emit_prologue (void)
 void
 s390_emit_epilogue (bool sibcall)
 {
-  rtx frame_pointer, return_reg, cfa_restores = NULL_RTX;
+  rtx frame_pointer, return_reg = NULL_RTX, cfa_restores = NULL_RTX;
   int area_bottom, area_top, offset = 0;
   int next_offset;
   int i;
@@ -11191,10 +11191,6 @@ s390_emit_epilogue (bool sibcall)
 
 }
 
-  /* Return register.  */
-
-  return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
-
   /* Restore call saved gprs.  */
 
   if (cfun_frame_layout.first_restore_gpr != -1)
@@ -11284,7 +11280,19 @@ s390_emit_epilogue (bool sibcall)
   s390_restore_gprs_from_fprs ();
 
   if (! sibcall)
-emit_jump_insn (gen_return_use (return_reg));
+{
+  if (!return_reg && !s390_can_use_return_insn ())
+/* We planned to emit (return), be we are not allowed to.  */
+return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
+
+  if (return_reg)
+/* Emit (return) and (use).  */
+emit_jump_insn (gen_return_use (return_reg));
+  else
+/* The fact that RETURN_REGNUM is used is already reflected by
+   EPILOGUE_USES.  Emit plain (return).  */
+emit_jump_insn (gen_return ());
+}
 }
 
 /* Implement TARGET_SET_UP_BY_PROLOGUE.  */
diff --git a/gcc/testsuite/gcc.target/s390/risbg-ll-3.c 
b/gcc/testsuite/gcc.target/s390/risbg-ll-3.c
index 838f1ffbd91..2a2db543cd9 100644
--- a/gcc/testsuite/gcc.target/s390/risbg-ll-3.c
+++ b/gcc/testsuite/gcc.target/s390/risbg-ll-3.c
@@ -23,7 +23,7 @@ i64 f1 (i64 v_a, i64 v_b)
 extern i64 f2_foo();
 i64 f2 (i64 v_a, i64 v_b)
 {
-/* { dg-final { scan-assembler "f2:\n\trisbg\t%r2,%r3,60,62,0\n\tje\t" { 
target { lp64 } } } } */
+/* { dg-final { scan-assembler 
"f2:\n\trisbg\t%r2,%r3,60,62,0\n\tbner\t%r14\n\tjg\tf2_foo\n" { target { lp64 } 
} } } */
 /* { dg-final { scan-assembler 
"f2:\n\trisbgn\t%r3,%r2,0,0\\\+32-1,64-0-32\n\trisbg\t%r3,%r5,60,62,0" { target 
{ ! lp64 } } } } */
   i64 v_anda = v_a & -15;
   i64 v_andb = v_b & 14;
@@ -37,8 +37,8 @@ i64 f2 (i64 v_a, i64 v_b)
 void f2_bar ();
 void f2_cconly (i64 v_a, i64 v_b)
 {
-/* { dg-final { scan-assembler "f2_cconly:\n\trisbg\t%r3,%r2,63,59,0\n\tjne\t" 
 { target { lp64 } } } } */
-/* { dg-final { scan-assembler 
"f2_cconly:\n\trisbgn\t%r3,%r2,0,0\\\+32-1,64-0-32\n\trisbg\t%r3,%r5,60,62,0\n\tjne\t"
 { target { ! lp64 } } } } */
+/* { dg-final { scan-assembler 
"f2_cconly:\n\trisbg\t%r3,%r2,63,59,0\n\tber\t%r14\n\tjg\tf2_bar\n" { target { 
lp64 } } } } */
+/* { dg-final { scan-assembler 
"f2_cconly:\n\trisbgn\t%r3,%r2,0,0\\\+32-1,64-0-32\n\trisbg\t%r3,%r5,60,62,0\n\tber\t%r14\n\tjg\tf2_bar\n"
 { target { ! lp64 } } } } */
   if ((v_a & -15) | (v_b & 14))
 f2_bar();
 }
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec-cmp-2.c 
b/gcc/testsuite/gcc.target/s390/zvector/vec-cmp-2.c
index 1e63defa063..09a15eb25f0 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec-cmp-2.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec-cmp-2.c
@@ -15,7 +15,7 @@ all_eq_double (vector double a, vector double b)
   if (__builtin_expect (vec_all_eq (a, b), 1))
 g = 2;
 }
-/* { dg-final { scan-assembler-times 
all_eq_double:\n\tvfcedbs\t%v\[0-9\]*,%v24,%v26\n\tjne 1 } } */
+/* { dg-final { scan-assembler-times 
all_eq_double:\n\tvfcedbs\t%v\[0-9\]*,%v24,%v26\n\tbner\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_ne_double (vector double a, vector double b)
@@ -23,7 +23,7 @@ all_ne_double (vector double a, vector double b)
   if (__builtin_expect (vec_all_ne