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