This enables early-exit vectorization on s390x.

Adjust the test suite since s390x does not support variable length
vectors and only supports basic vector load schemes.

gcc/ChangeLog:

        * config/s390/s390-protos.h (s390_expand_vec_compare_gen_cc):
        New function.
        * config/s390/s390.cc (s390_expand_vec_compare_cc): Extract
        part of this function into a ...
        (s390_expand_vec_compare_gen_cc): ... new function.
        * config/s390/vector.md (vec_cbranch_any<mode>): Implement.
        (vec_cbranch_all<mode>): Implement.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/gen-vect-11.c: Adjust.
        * gcc.dg/tree-ssa/gen-vect-11a.c: Adjust.
        * gcc.dg/vect/vect-early-break_52.c: Adjust.
        * gcc.dg/vect/vect-early-break_53.c: Adjust.
        * gcc.dg/vect/vect-early-break_64.c: Adjust.
        * gcc.dg/vect/vect-uncounted_2.c: Adjust.
        * lib/target-supports.exp: Add s390x to early-break
        vectorization

Signed-off-by: Juergen Christ <[email protected]>
---
 gcc/config/s390/s390-protos.h                 |  1 +
 gcc/config/s390/s390.cc                       | 40 ++++++++-----
 gcc/config/s390/vector.md                     | 60 +++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c   |  7 +--
 gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c  |  4 +-
 .../gcc.dg/vect/vect-early-break_52.c         |  2 +-
 .../gcc.dg/vect/vect-early-break_53.c         |  2 +-
 .../gcc.dg/vect/vect-early-break_64.c         |  2 +-
 gcc/testsuite/gcc.dg/vect/vect-uncounted_2.c  |  2 +-
 gcc/testsuite/lib/target-supports.exp         |  4 ++
 10 files changed, 100 insertions(+), 24 deletions(-)

diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index bedce5830720..e885ad1beb19 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -122,6 +122,7 @@ extern void s390_expand_atomic (machine_mode, enum rtx_code,
                                rtx, rtx, rtx, bool);
 extern void s390_expand_tbegin (rtx, rtx, rtx, bool);
 extern void s390_expand_vec_compare (rtx, enum rtx_code, rtx, rtx);
+extern rtx s390_expand_vec_compare_gen_cc (enum rtx_code, rtx, rtx, bool);
 extern void s390_expand_vec_compare_cc (rtx, enum rtx_code, rtx, rtx, bool);
 extern enum rtx_code s390_reverse_condition (machine_mode, enum rtx_code);
 extern void s390_expand_vcond (rtx, rtx, rtx, enum rtx_code, rtx, rtx);
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 1bddd5e454ae..89161674e44a 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -7449,18 +7449,14 @@ s390_expand_vec_compare (rtx target, enum rtx_code cond,
     emit_insn (gen_rtx_SET (target, gen_rtx_NOT (mode, target)));
 }
 
-/* Expand the comparison CODE of CMP1 and CMP2 and copy 1 or 0 into
-   TARGET if either all (ALL_P is true) or any (ALL_P is false) of the
-   elements in CMP1 and CMP2 fulfill the comparison.
-   This function is only used in s390_expand_cstoreti4 and to emit patterns for
-   the vx builtins and therefore only handles comparison codes required by
-   those.  */
-void
-s390_expand_vec_compare_cc (rtx target, enum rtx_code code,
-                           rtx cmp1, rtx cmp2, bool all_p)
+/* Expand the comparison CODE of CMP1 and CMP2 and return a comparison suitable
+   for s390_emit_jump which jumps if all (ALLP is true) or any (ALL_P is false)
+   of the elements in CMP1 and CMP2 fulfill the comparison.  */
+rtx
+s390_expand_vec_compare_gen_cc (enum rtx_code code,
+                               rtx cmp1, rtx cmp2, bool all_p)
 {
   machine_mode cc_producer_mode, cc_consumer_mode, scratch_mode;
-  rtx tmp_reg = gen_reg_rtx (SImode);
   bool swap_p = false;
 
   if (GET_MODE_CLASS (GET_MODE (cmp1)) == MODE_VECTOR_INT
@@ -7543,14 +7539,30 @@ s390_expand_vec_compare_cc (rtx target, enum rtx_code 
code,
                               gen_rtx_COMPARE (cc_producer_mode, cmp1, cmp2)),
                          gen_rtx_CLOBBER (VOIDmode,
                                           gen_rtx_SCRATCH (scratch_mode)))));
+
+  return gen_rtx_fmt_ee (code, VOIDmode,
+                        gen_rtx_REG (cc_consumer_mode, CC_REGNUM),
+                        const0_rtx);
+}
+
+/* Expand the comparison CODE of CMP1 and CMP2 and copy 1 or 0 into
+   TARGET if either all (ALL_P is true) or any (ALL_P is false) of the
+   elements in CMP1 and CMP2 fulfill the comparison.
+   This function is only used in s390_expand_cstoreti4 and to emit patterns for
+   the vx builtins and therefore only handles comparison codes required by
+   those.  */
+void
+s390_expand_vec_compare_cc (rtx target, enum rtx_code code,
+                           rtx cmp1, rtx cmp2, bool all_p)
+{
+  rtx cond = s390_expand_vec_compare_gen_cc (code, cmp1, cmp2, all_p);
+  rtx tmp_reg = gen_reg_rtx (SImode);
+
   emit_move_insn (target, const0_rtx);
   emit_move_insn (tmp_reg, const1_rtx);
 
   emit_move_insn (target,
-                 gen_rtx_IF_THEN_ELSE (SImode,
-                   gen_rtx_fmt_ee (code, VOIDmode,
-                                   gen_rtx_REG (cc_consumer_mode, CC_REGNUM),
-                                   const0_rtx),
+                 gen_rtx_IF_THEN_ELSE (SImode, cond,
                                        tmp_reg, target));
 }
 
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index f0be6f10c1ac..b806f4c3300d 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -3967,3 +3967,63 @@
   operands[8] = gen_reg_rtx (V16QImode);
   operands[9] = gen_reg_rtx (V16QImode);
 })
+
+(define_expand "vec_cbranch_any<mode>"
+  [(set (pc)
+       (if_then_else (match_operator 0 "comparison_operator"
+                      [(match_operand:VIT_HW_VXE3_T 1 "register_operand" "")
+                       (match_operand:VIT_HW_VXE3_T 2 "register_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
+  "TARGET_VX"
+{
+  s390_emit_jump (operands[3],
+    s390_expand_vec_compare_gen_cc (GET_CODE (operands[0]),
+                                   operands[1], operands[2], false));
+  DONE;
+})
+
+(define_expand "vec_cbranch_all<mode>"
+  [(set (pc)
+       (if_then_else (match_operator 0 "comparison_operator"
+                      [(match_operand:VIT_HW_VXE3_T 1 "register_operand" "")
+                       (match_operand:VIT_HW_VXE3_T 2 "register_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
+  "TARGET_VX"
+{
+  s390_emit_jump (operands[3],
+    s390_expand_vec_compare_gen_cc (GET_CODE (operands[0]),
+                                   operands[1], operands[2], true));
+  DONE;
+})
+
+(define_expand "vec_cbranch_any<mode>"
+  [(set (pc)
+       (if_then_else (match_operator 0 "comparison_operator"
+                      [(match_operand:VECF_HW 1 "register_operand" "")
+                       (match_operand:VECF_HW 2 "register_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
+  "TARGET_VX"
+{
+  s390_emit_jump (operands[3],
+    s390_expand_vec_compare_gen_cc (GET_CODE (operands[0]),
+                                   operands[1], operands[2], false));
+  DONE;
+})
+
+(define_expand "vec_cbranch_all<mode>"
+  [(set (pc)
+       (if_then_else (match_operator 0 "comparison_operator"
+                      [(match_operand:VECF_HW 1 "register_operand" "")
+                       (match_operand:VECF_HW 2 "register_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
+  "TARGET_VX"
+{
+  s390_emit_jump (operands[3],
+    s390_expand_vec_compare_gen_cc (GET_CODE (operands[0]),
+                                   operands[1], operands[2], true));
+  DONE;
+})
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c 
b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c
index 6916843f397b..9b5098b50992 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c
@@ -1,10 +1,6 @@
 /* { dg-do run { target vect_cmdline_needed } } */
 /* { dg-options "-O2 -ftree-vectorize -fwrapv -fdump-tree-vect-details 
-fvect-cost-model=dynamic" } */
 /* { dg-additional-options "-mno-sse" { target { i?86-*-* x86_64-*-* } } } */
-/* The IBM Z backend sets the min-vect-loop-bound param to 2 to avoid
-   awkward epilogue code generation in some cases.  This line needs to
-   be removed after finding an alternate way to fix this.  */
-/* { dg-additional-options "--param min-vect-loop-bound=0" { target { 
s390*-*-* } } } */
 
 #include <stdlib.h>
 
@@ -34,4 +30,5 @@ int main ()
 }
 
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { 
! { avr-*-* msp430-*-* pru-*-* } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { 
! { avr-*-* msp430-*-* pru-*-* s390*-*-* } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target { 
s390*-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c 
b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c
index 6326bf75ab02..721a609acffb 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c
@@ -38,4 +38,6 @@ int main ()
 }
 
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { 
! { avr-*-* pru-*-* } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { 
! { avr-*-* msp430-*-* pru-*-* s390*-*-* } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target { 
s390*-*-* } } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_52.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_52.c
index 6abfcd6580e4..f7e6a6c2eb93 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-early-break_52.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_52.c
@@ -18,4 +18,4 @@ int main1 (short X)
     }
 }
 
-/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { 
target { ! "x86_64-*-* i?86-*-* arm*-*-*" } } } } */
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { 
target { ! "x86_64-*-* i?86-*-* arm*-*-* s390*-*-*" } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_53.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_53.c
index d4fd0d39a25a..876baa980272 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-early-break_53.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_53.c
@@ -16,4 +16,4 @@ int main ()
     abort ();
 }
 
-/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { 
target { ! s390*-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_64.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_64.c
index aaa2a46fb67e..52d7ebdd1797 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-early-break_64.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_64.c
@@ -15,4 +15,4 @@ void a() {
     return;
 }
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target 
vect_partial_vectors } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { 
vect_partial_vectors && { ! s390*-*-* } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted_2.c 
b/gcc/testsuite/gcc.dg/vect/vect-uncounted_2.c
index 33fb0ce1f0d0..390bf22ee1fa 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-uncounted_2.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted_2.c
@@ -13,7 +13,7 @@ foo (int *a0, int *aN, int *b0, int *bN)
     *a += *b;
 }
 
-/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" } } 
*/
+/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" { 
target { ! "s390*-*-*" } } } } */
 /* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
 /* Make sure the values used in peeled epilog loop effectively reset the last 
vectorized iteration.  */
 /* { dg-final { scan-tree-dump {<bb ([0-9]+)>[^\n\r]*:.+# (a_[0-9]+) = PHI 
<a_[0-9]+\([0-9]+\).+<bb [0-9]+>[^\n\r]*:.+# a_[0-9]+ = PHI <\2\(\1\)>} "vect" 
} } */
diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index c6ebbed4f4b5..e76b2b77c4c0 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -4713,6 +4713,8 @@ proc check_effective_target_vect_early_break { } {
        || [istarget amdgcn-*-*]
        || [check_effective_target_riscv_v]
        || [check_effective_target_loongarch_sx]
+       || ([istarget s390*-*-*]
+            && [check_effective_target_s390_vx])
        }}]
 }
 
@@ -4730,6 +4732,8 @@ proc check_effective_target_vect_early_break_hw { } {
        || [istarget amdgcn-*-*]
        || [check_effective_target_riscv_v_ok]
        || [check_effective_target_loongarch_sx_hw]
+       || ([istarget s390*-*-*]
+            && [check_effective_target_s390_vx])
        }}]
 }
 
-- 
2.43.7

Reply via email to