Commit eca98038 by Andreas Krebbel Committed by Andreas Krebbel

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
parent a6a2b532
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
......@@ -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);
......
......@@ -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. */
......
......@@ -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:
......
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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment