diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2016-12-02 08:22:34 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel@gcc.gnu.org> | 2016-12-02 08:22:34 +0000 |
commit | eca9803844ddf459d3f5992aa88353603f0cb731 (patch) | |
tree | 175e6e75fad8aa9948599146110c6f81308ef43d | |
parent | a6a2b532f9c4e92277e390febc8c07f773becb1b (diff) | |
download | gcc-eca9803844ddf459d3f5992aa88353603f0cb731.zip gcc-eca9803844ddf459d3f5992aa88353603f0cb731.tar.gz gcc-eca9803844ddf459d3f5992aa88353603f0cb731.tar.bz2 |
S/390: Merge compare of compare results
With this patch EQ and NE compares on CC mode reader patterns are
folded. This allows using the result of the vec_all_* and vec_any_*
builtins directly in a conditional jump instruction as in the attached
testcase.
gcc/ChangeLog:
2016-12-02 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/s390-protos.h (s390_reverse_condition): New
prototype.
* config/s390/s390.c (s390_canonicalize_comparison): Fold compares
of CC mode values.
(s390_reverse_condition): New function.
* config/s390/s390.h (REVERSE_CC_MODE, REVERSE_CONDITION): Define
target macros.
gcc/testsuite/ChangeLog:
2016-12-02 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* gcc.target/s390/zvector/vec-cmp-2.c: New test.
From-SVN: r243155
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/s390/s390-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 42 | ||||
-rw-r--r-- | gcc/config/s390/s390.h | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 |
5 files changed, 69 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2d55409..d06661e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2016-12-02 Andreas Krebbel <krebbel@linux.vnet.ibm.com> + * config/s390/s390-protos.h (s390_reverse_condition): New + prototype. + * config/s390/s390.c (s390_canonicalize_comparison): Fold compares + of CC mode values. + (s390_reverse_condition): New function. + * config/s390/s390.h (REVERSE_CC_MODE, REVERSE_CONDITION): Define + target macros. + +2016-12-02 Andreas Krebbel <krebbel@linux.vnet.ibm.com> + * config/s390/s390-modes.def (CCVEQANY, CCVH, CCVHANY, CCVHU) (CCVHUANY): Remove modes. (CCVIH, CCVIHU, CCVIALL, CCVIANY, CCVFALL, CCVFANY): Add modes and diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 7ae98d4..000a677 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -119,6 +119,7 @@ extern void s390_expand_atomic (machine_mode, enum rtx_code, extern void s390_expand_tbegin (rtx, rtx, rtx, bool); extern void s390_expand_vec_compare (rtx, enum rtx_code, rtx, rtx); extern void s390_expand_vec_compare_cc (rtx, enum rtx_code, rtx, rtx, bool); +extern enum rtx_code s390_reverse_condition (machine_mode, enum rtx_code); extern void s390_expand_vcond (rtx, rtx, rtx, enum rtx_code, rtx, rtx); extern void s390_expand_vec_init (rtx, rtx); extern rtx s390_return_addr_rtx (int, rtx); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 445c147..dab4f43 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -1722,6 +1722,31 @@ s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1, } tmp = *op0; *op0 = *op1; *op1 = tmp; } + + /* A comparison result is compared against zero. Replace it with + the (perhaps inverted) original comparison. + This probably should be done by simplify_relational_operation. */ + if ((*code == EQ || *code == NE) + && *op1 == const0_rtx + && COMPARISON_P (*op0) + && CC_REG_P (XEXP (*op0, 0))) + { + enum rtx_code new_code; + + if (*code == EQ) + new_code = reversed_comparison_code_parts (GET_CODE (*op0), + XEXP (*op0, 0), + XEXP (*op1, 0), NULL); + else + new_code = GET_CODE (*op0); + + if (new_code != UNKNOWN) + { + *code = new_code; + *op1 = XEXP (*op0, 1); + *op0 = XEXP (*op0, 0); + } + } } /* Helper function for s390_emit_compare. If possible emit a 64 bit @@ -6343,6 +6368,23 @@ s390_expand_vec_compare_cc (rtx target, enum rtx_code code, tmp_reg, target)); } +/* Invert the comparison CODE applied to a CC mode. This is only safe + if we know whether there result was created by a floating point + compare or not. For the CCV modes this is encoded as part of the + mode. */ +enum rtx_code +s390_reverse_condition (machine_mode mode, enum rtx_code code) +{ + /* Reversal of FP compares takes care -- an ordered compare + becomes an unordered compare and vice versa. */ + if (mode == CCVFALLmode || mode == CCVFANYmode) + return reverse_condition_maybe_unordered (code); + else if (mode == CCVIALLmode || mode == CCVIANYmode) + return reverse_condition (code); + else + gcc_unreachable (); +} + /* Generate a vector comparison expression loading either elements of THEN or ELS into TARGET depending on the comparison COND of CMP_OP1 and CMP_OP2. */ diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 6be4d34..1d6d7b2 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -513,6 +513,18 @@ extern const char *s390_host_detect_local_cpu (int argc, const char **argv); #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ s390_cannot_change_mode_class ((FROM), (TO), (CLASS)) +/* We can reverse a CC mode safely if we know whether it comes from a + floating point compare or not. With the vector modes it is encoded + as part of the mode. + FIXME: It might make sense to do this for other cc modes as well. */ +#define REVERSIBLE_CC_MODE(MODE) \ + ((MODE) == CCVIALLmode || (MODE) == CCVIANYmode \ + || (MODE) == CCVFALLmode || (MODE) == CCVFANYmode) + +/* Given a condition code and a mode, return the inverse condition. */ +#define REVERSE_CONDITION(CODE, MODE) s390_reverse_condition (MODE, CODE) + + /* Register classes. */ /* We use the following register classes: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2ecf8f9..dc269ef 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2016-12-02 Andreas Krebbel <krebbel@linux.vnet.ibm.com> + * gcc.target/s390/zvector/vec-cmp-2.c: New test. + +2016-12-02 Andreas Krebbel <krebbel@linux.vnet.ibm.com> + * gcc.target/s390/vector/vec-scalar-cmp-1.c: Fix and harden the pattern checks. * gcc.target/s390/zvector/vec-cmp-1.c: New test. |