diff mbox series

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

Message ID 20180919181924.66513-1-iii@linux.ibm.com
State New
Headers show
Series [v2] S/390: Fix conditional returns on z196+ | expand

Commit Message

Ilya Leoshkevich Sept. 19, 2018, 6:19 p.m. UTC
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  <iii@linux.ibm.com>

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

gcc/testsuite/ChangeLog:

2018-09-19  Ilya Leoshkevich  <iii@linux.ibm.com>

	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.md                       |  7 +++
 gcc/testsuite/gcc.target/s390/risbg-ll-3.c    |  6 +--
 .../gcc.target/s390/zvector/vec-cmp-2.c       | 48 +++++++++----------
 3 files changed, 34 insertions(+), 27 deletions(-)

Comments

Segher Boessenkool Sept. 21, 2018, 2:01 p.m. UTC | #1
On Fri, Sep 21, 2018 at 12:50:40PM +0200, Ulrich Weigand wrote:
> Ilya Leoshkevich wrote:
> 
> > 2018-09-19  Ilya Leoshkevich  <iii@linux.ibm.com>
> > 
> > 	PR target/80080
> > 	* config/s390/s390.md: Do not use PARALLEL RETURN+USE when
> > 	returning via %r14.
> 
> This makes sense to me.  I'm just wondering if it wouldn't be
> simpler to do the check for r14 right in s390_emit_epilogue
> and then just call gen_return instead of gen_return_use
> directly there?

I had the same thought :-)

> > +++ b/gcc/config/s390/s390.md
> > @@ -10831,6 +10831,13 @@
> >       (use (match_operand 0 "register_operand" "a"))])]
> >    ""
> >  {
> > +  if (REGNO (operands[0]) == RETURN_REGNUM && s390_can_use_return_insn ())
> 
> This probably cannot happen in practice in this specific case,
> but in general a register_operand may also be e.g. a SUBREG,
> so you shouldn't use REGNO without first verifying that this
> is a REG.  (If you move the check to s390_emit_epilogue as above,
> this point is moot; you don't even need to generate a REG RTX
> if it's for r14 then.)

There is reg_or_subregno exactly for this.


Segher
diff mbox series

Patch

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 35d22eb50cc..eb363e6d7f8 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -10831,6 +10831,13 @@ 
      (use (match_operand 0 "register_operand" "a"))])]
   ""
 {
+  if (REGNO (operands[0]) == RETURN_REGNUM && s390_can_use_return_insn ())
+    {
+      /* The fact that RETURN_REGNUM is used is already reflected by
+         EPILOGUE_USES.  Emit plain (return).  */
+      emit_jump_insn (gen_return ());
+      DONE;
+    }
   if (!TARGET_CPU_Z10
       && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION)
     {
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 (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_ne_double:\n\tvfcedbs\t%v\[0-9\]*,%v24,%v26\n\tjle 1 } } */
+/* { dg-final { scan-assembler-times all_ne_double:\n\tvfcedbs\t%v\[0-9\]*,%v24,%v26\n\tbler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_gt_double (vector double a, vector double b)
@@ -31,7 +31,7 @@  all_gt_double (vector double a, vector double b)
   if (__builtin_expect (vec_all_gt (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_gt_double:\n\tvfchdbs\t%v\[0-9\]*,%v24,%v26\n\tjne 1 } } */
+/* { dg-final { scan-assembler-times all_gt_double:\n\tvfchdbs\t%v\[0-9\]*,%v24,%v26\n\tbner\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_lt_double (vector double a, vector double b)
@@ -39,7 +39,7 @@  all_lt_double (vector double a, vector double b)
   if (__builtin_expect (vec_all_lt (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_lt_double:\n\tvfchdbs\t%v\[0-9\]*,%v26,%v24\n\tjne 1 } } */
+/* { dg-final { scan-assembler-times all_lt_double:\n\tvfchdbs\t%v\[0-9\]*,%v26,%v24\n\tbner\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_ge_double (vector double a, vector double b)
@@ -47,7 +47,7 @@  all_ge_double (vector double a, vector double b)
   if (__builtin_expect (vec_all_ge (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_ge_double:\n\tvfchedbs\t%v\[0-9\]*,%v24,%v26\n\tjne 1 } } */
+/* { dg-final { scan-assembler-times all_ge_double:\n\tvfchedbs\t%v\[0-9\]*,%v24,%v26\n\tbner\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_le_double (vector double a, vector double b)
@@ -55,7 +55,7 @@  all_le_double (vector double a, vector double b)
   if (__builtin_expect (vec_all_le (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_le_double:\n\tvfchedbs\t%v\[0-9\]*,%v26,%v24\n\tjne 1 } } */
+/* { dg-final { scan-assembler-times all_le_double:\n\tvfchedbs\t%v\[0-9\]*,%v26,%v24\n\tbner\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_eq_double (vector double a, vector double b)
@@ -63,7 +63,7 @@  any_eq_double (vector double a, vector double b)
   if (__builtin_expect (vec_any_eq (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_eq_double:\n\tvfcedbs\t%v\[0-9\]*,%v24,%v26\n\tjnle 1 } } */
+/* { dg-final { scan-assembler-times any_eq_double:\n\tvfcedbs\t%v\[0-9\]*,%v24,%v26\n\tbnler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_ne_double (vector double a, vector double b)
@@ -71,7 +71,7 @@  any_ne_double (vector double a, vector double b)
   if (__builtin_expect (vec_any_ne (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_ne_double:\n\tvfcedbs\t%v\[0-9\]*,%v24,%v26\n\tje 1 } } */
+/* { dg-final { scan-assembler-times any_ne_double:\n\tvfcedbs\t%v\[0-9\]*,%v24,%v26\n\tber\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_gt_double (vector double a, vector double b)
@@ -79,7 +79,7 @@  any_gt_double (vector double a, vector double b)
   if (__builtin_expect (vec_any_gt (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_gt_double:\n\tvfchdbs\t%v\[0-9\]*,%v24,%v26\n\tjnle 1 } } */
+/* { dg-final { scan-assembler-times any_gt_double:\n\tvfchdbs\t%v\[0-9\]*,%v24,%v26\n\tbnler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_lt_double (vector double a, vector double b)
@@ -87,7 +87,7 @@  any_lt_double (vector double a, vector double b)
   if (__builtin_expect (vec_any_lt (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_lt_double:\n\tvfchdbs\t%v\[0-9\]*,%v26,%v24\n\tjnle 1 } } */
+/* { dg-final { scan-assembler-times any_lt_double:\n\tvfchdbs\t%v\[0-9\]*,%v26,%v24\n\tbnler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_ge_double (vector double a, vector double b)
@@ -95,7 +95,7 @@  any_ge_double (vector double a, vector double b)
   if (__builtin_expect (vec_any_ge (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_ge_double:\n\tvfchedbs\t%v\[0-9\]*,%v24,%v26\n\tjnle 1 } } */
+/* { dg-final { scan-assembler-times any_ge_double:\n\tvfchedbs\t%v\[0-9\]*,%v24,%v26\n\tbnler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_le_double (vector double a, vector double b)
@@ -103,7 +103,7 @@  any_le_double (vector double a, vector double b)
   if (__builtin_expect (vec_any_le (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_le_double:\n\tvfchedbs\t%v\[0-9\]*,%v26,%v24\n\tjnle 1 } } */
+/* { dg-final { scan-assembler-times any_le_double:\n\tvfchedbs\t%v\[0-9\]*,%v26,%v24\n\tbnler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_eq_int (vector int a, vector int b)
@@ -111,7 +111,7 @@  all_eq_int (vector int a, vector int b)
   if (__builtin_expect (vec_all_eq (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_eq_int:\n\tvceqfs\t%v\[0-9\]*,%v24,%v26\n\tjne 1 } } */
+/* { dg-final { scan-assembler-times all_eq_int:\n\tvceqfs\t%v\[0-9\]*,%v24,%v26\n\tbner\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_ne_int (vector int a, vector int b)
@@ -119,7 +119,7 @@  all_ne_int (vector int a, vector int b)
   if (__builtin_expect (vec_all_ne (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_ne_int:\n\tvceqfs\t%v\[0-9\]*,%v24,%v26\n\tjle 1 } } */
+/* { dg-final { scan-assembler-times all_ne_int:\n\tvceqfs\t%v\[0-9\]*,%v24,%v26\n\tbler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_gt_int (vector int a, vector int b)
@@ -127,7 +127,7 @@  all_gt_int (vector int a, vector int b)
   if (__builtin_expect (vec_all_gt (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_gt_int:\n\tvchfs\t%v\[0-9\]*,%v24,%v26\n\tjne 1 } } */
+/* { dg-final { scan-assembler-times all_gt_int:\n\tvchfs\t%v\[0-9\]*,%v24,%v26\n\tbner\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_lt_int (vector int a, vector int b)
@@ -135,7 +135,7 @@  all_lt_int (vector int a, vector int b)
   if (__builtin_expect (vec_all_lt (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_lt_int:\n\tvchfs\t%v\[0-9\]*,%v26,%v24\n\tjne 1 } } */
+/* { dg-final { scan-assembler-times all_lt_int:\n\tvchfs\t%v\[0-9\]*,%v26,%v24\n\tbner\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_ge_int (vector int a, vector int b)
@@ -143,7 +143,7 @@  all_ge_int (vector int a, vector int b)
   if (__builtin_expect (vec_all_ge (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_ge_int:\n\tvchfs\t%v\[0-9\]*,%v26,%v24\n\tjle 1 } } */
+/* { dg-final { scan-assembler-times all_ge_int:\n\tvchfs\t%v\[0-9\]*,%v26,%v24\n\tbler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 all_le_int (vector int a, vector int b)
@@ -151,7 +151,7 @@  all_le_int (vector int a, vector int b)
   if (__builtin_expect (vec_all_le (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times all_le_int:\n\tvchfs\t%v\[0-9\]*,%v24,%v26\n\tjle 1 } } */
+/* { dg-final { scan-assembler-times all_le_int:\n\tvchfs\t%v\[0-9\]*,%v24,%v26\n\tbler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_eq_int (vector int a, vector int b)
@@ -159,7 +159,7 @@  any_eq_int (vector int a, vector int b)
   if (__builtin_expect (vec_any_eq (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_eq_int:\n\tvceqfs\t%v\[0-9\]*,%v24,%v26\n\tjnle 1 } } */
+/* { dg-final { scan-assembler-times any_eq_int:\n\tvceqfs\t%v\[0-9\]*,%v24,%v26\n\tbnler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_ne_int (vector int a, vector int b)
@@ -167,7 +167,7 @@  any_ne_int (vector int a, vector int b)
   if (__builtin_expect (vec_any_ne (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_ne_int:\n\tvceqfs\t%v\[0-9\]*,%v24,%v26\n\tje 1 } } */
+/* { dg-final { scan-assembler-times any_ne_int:\n\tvceqfs\t%v\[0-9\]*,%v24,%v26\n\tber\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_gt_int (vector int a, vector int b)
@@ -175,7 +175,7 @@  any_gt_int (vector int a, vector int b)
   if (__builtin_expect (vec_any_gt (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_gt_int:\n\tvchfs\t%v\[0-9\]*,%v24,%v26\n\tjnle 1 } } */
+/* { dg-final { scan-assembler-times any_gt_int:\n\tvchfs\t%v\[0-9\]*,%v24,%v26\n\tbnler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_lt_int (vector int a, vector int b)
@@ -183,7 +183,7 @@  any_lt_int (vector int a, vector int b)
   if (__builtin_expect (vec_any_lt (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_lt_int:\n\tvchfs\t%v\[0-9\]*,%v26,%v24\n\tjnle 1 } } */
+/* { dg-final { scan-assembler-times any_lt_int:\n\tvchfs\t%v\[0-9\]*,%v26,%v24\n\tbnler\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_ge_int (vector int a, vector int b)
@@ -191,7 +191,7 @@  any_ge_int (vector int a, vector int b)
   if (__builtin_expect (vec_any_ge (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_ge_int:\n\tvchfs\t%v\[0-9\]*,%v26,%v24\n\tje 1 } } */
+/* { dg-final { scan-assembler-times any_ge_int:\n\tvchfs\t%v\[0-9\]*,%v26,%v24\n\tber\t%r14\n 1 } } */
 
 void __attribute__((noinline,noclone))
 any_le_int (vector int a, vector int b)
@@ -199,5 +199,5 @@  any_le_int (vector int a, vector int b)
   if (__builtin_expect (vec_any_le (a, b), 1))
     g = 2;
 }
-/* { dg-final { scan-assembler-times any_le_int:\n\tvchfs\t%v\[0-9\]*,%v24,%v26\n\tje 1 } } */
+/* { dg-final { scan-assembler-times any_le_int:\n\tvchfs\t%v\[0-9\]*,%v24,%v26\n\tber\t%r14\n 1 } } */