IBM Z: Fix vcond-shift.c testcase.
authorAndreas Krebbel <krebbel@linux.ibm.com>
Mon, 8 Mar 2021 11:49:22 +0000 (12:49 +0100)
committerAndreas Krebbel <krebbel@linux.ibm.com>
Mon, 8 Mar 2021 11:49:36 +0000 (12:49 +0100)
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.

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
gcc/config/s390/vector.md

index f3d0d1b..c9aea21 100644 (file)
@@ -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.  */
index bc52211..c80d582 100644 (file)
   [(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]);