aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.ibm.com>2021-03-08 12:49:22 +0100
committerAndreas Krebbel <krebbel@linux.ibm.com>2021-03-08 12:49:36 +0100
commite99b25df68d4528141f6079e1e3af8ef20bbcb00 (patch)
tree87695d5df61ee32b16c4c06d151d00a88c12b9e9 /gcc
parentb48d76c4e6bd3b88f23979ede4ff12f875e0ad60 (diff)
downloadgcc-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.c20
-rw-r--r--gcc/config/s390/vector.md2
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]);