Due to a common code change the comparison in the testcase is emitted
via vec_cmp instead of vcond.  The testcase checks for an optimization
currently only available via vcond.

Fixed by implementing the same optimization also in
s390_expand_vec_compare.

Bootstrapped and regression tested on s390x with -march=z15

This fixes the following testsuite fails:

< FAIL: gcc.target/s390/vector/vcond-shift.c scan-assembler-not vzero\\t*
< FAIL: gcc.target/s390/vector/vcond-shift.c scan-assembler-times 
vesrab\\t%v.?,%v.?,7 6
< FAIL: gcc.target/s390/vector/vcond-shift.c scan-assembler-times 
vesraf\\t%v.?,%v.?,31 6
< FAIL: gcc.target/s390/vector/vcond-shift.c scan-assembler-times 
vesrah\\t%v.?,%v.?,15 6

gcc/ChangeLog:

        * config/s390/s390.c (s390_expand_vec_compare): Implement <0
        comparison with arithmetic right shift.
        (s390_expand_vcond): No need for a force_reg anymore.
        s390_vec_compare will do it.
        * config/s390/vector.md ("vec_cmp<mode><tointvec>"): Accept also
        immediate operands.
---
 gcc/config/s390/s390.c    | 20 +++++++++++++++-----
 gcc/config/s390/vector.md |  2 +-
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index f3d0d1ba596..c9aea21fe40 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -6569,6 +6569,7 @@ s390_expand_vec_compare (rtx target, enum rtx_code cond,
 
   if (GET_MODE_CLASS (GET_MODE (cmp_op1)) == MODE_VECTOR_FLOAT)
     {
+      cmp_op2 = force_reg (GET_MODE (cmp_op1), cmp_op2);
       switch (cond)
        {
          /* NE a != b -> !(a == b) */
@@ -6607,6 +6608,19 @@ s390_expand_vec_compare (rtx target, enum rtx_code cond,
     }
   else
     {
+      /* Turn x < 0 into x >> (bits per element - 1)  */
+      if (cond == LT && cmp_op2 == CONST0_RTX (mode))
+       {
+         int shift = GET_MODE_BITSIZE (GET_MODE_INNER (mode)) - 1;
+         rtx res = expand_simple_binop (mode, ASHIFTRT, cmp_op1,
+                                        GEN_INT (shift), target,
+                                        0, OPTAB_DIRECT);
+         if (res != target)
+           emit_move_insn (target, res);
+         return;
+       }
+      cmp_op2 = force_reg (GET_MODE (cmp_op1), cmp_op2);
+
       switch (cond)
        {
          /* NE: a != b -> !(a == b) */
@@ -6824,11 +6838,7 @@ s390_expand_vcond (rtx target, rtx then, rtx els,
   if (!REG_P (cmp_op1))
     cmp_op1 = force_reg (GET_MODE (cmp_op1), cmp_op1);
 
-  if (!REG_P (cmp_op2))
-    cmp_op2 = force_reg (GET_MODE (cmp_op2), cmp_op2);
-
-  s390_expand_vec_compare (result_target, cond,
-                          cmp_op1, cmp_op2);
+  s390_expand_vec_compare (result_target, cond, cmp_op1, cmp_op2);
 
   /* If the results are supposed to be either -1 or 0 we are done
      since this is what our compare instructions generate anyway.  */
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index bc52211c55e..c80d582a300 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -1589,7 +1589,7 @@ (define_expand "vec_cmp<mode><tointvec>"
   [(set (match_operand:<TOINTVEC>  0 "register_operand" "")
        (match_operator:<TOINTVEC> 1 "vcond_comparison_operator"
          [(match_operand:V_HW     2 "register_operand" "")
-          (match_operand:V_HW     3 "register_operand" "")]))]
+          (match_operand:V_HW     3 "nonmemory_operand" "")]))]
   "TARGET_VX"
 {
   s390_expand_vec_compare (operands[0], GET_CODE(operands[1]), operands[2], 
operands[3]);
-- 
2.29.2

Reply via email to