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  <i...@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  <i...@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(-)

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 } } */
 
-- 
2.19.0

Reply via email to