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