diff options
author | Andreas Krebbel <krebbel@linux.ibm.com> | 2021-03-08 12:49:22 +0100 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.ibm.com> | 2021-03-08 12:49:36 +0100 |
commit | e99b25df68d4528141f6079e1e3af8ef20bbcb00 (patch) | |
tree | 87695d5df61ee32b16c4c06d151d00a88c12b9e9 /gcc | |
parent | b48d76c4e6bd3b88f23979ede4ff12f875e0ad60 (diff) | |
download | gcc-e99b25df68d4528141f6079e1e3af8ef20bbcb00.zip gcc-e99b25df68d4528141f6079e1e3af8ef20bbcb00.tar.gz gcc-e99b25df68d4528141f6079e1e3af8ef20bbcb00.tar.bz2 |
IBM Z: Fix vcond-shift.c testcase.
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/s390/s390.c | 20 | ||||
-rw-r--r-- | 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 f3d0d1b..c9aea21 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 bc52211..c80d582 100644 --- a/gcc/config/s390/vector.md +++ b/gcc/config/s390/vector.md @@ -1589,7 +1589,7 @@ [(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]); |