aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2020-11-24 23:45:59 +0100
committerIlya Leoshkevich <iii@linux.ibm.com>2020-12-01 12:03:30 +0100
commit3940daff128a995693b405f47dc706b9622c861b (patch)
treede52504f33f2fccc221bd94ad8afc1d0cdb780e6 /gcc/optabs.c
parent0fb378761f2c5eb906bf0a9698112dd65d4dc73b (diff)
downloadgcc-3940daff128a995693b405f47dc706b9622c861b.zip
gcc-3940daff128a995693b405f47dc706b9622c861b.tar.gz
gcc-3940daff128a995693b405f47dc706b9622c861b.tar.bz2
Introduce can_vec_cmp_compare_p
This is the same as dcd2ca63ec5c ("Introduce can_vcond_compare_p function"), but for vec_cmp. The reason it's needed is that since 5d9ade39b872 ("IBM Z: Fix PR97326: Enable fp compares in vec_cmp") and 4acba4859013 ("IBM Z: Restrict vec_cmp<m><n> on z13") s390's vec_cmp expander advertises that it supports floating point comparisons except signaling ones on z13, but the common code ignores the latter restriction. gcc/ChangeLog: 2020-11-25 Ilya Leoshkevich <iii@linux.ibm.com> * optabs-tree.c (vec_cmp_icode_p): New function. (vec_cmp_eq_icode_p): New function. (expand_vec_cmp_expr_p): Use vec_cmp_icode_p and vec_cmp_eq_icode_p. (vcond_icode_p): Use get_rtx_code_1, just to be uniform with vec_cmp_icode_p. * optabs.c (unsigned_optab_p): New function. (insn_predicate_matches_p): New function. (can_vec_cmp_compare_p): New function. (can_vcond_compare_p): Use unsigned_optab_p and insn_predicate_matches_p. (get_rtx_code): Use get_rtx_code_1. (get_rtx_code_1): Version of get_rtx_code that returns UNKNOWN instead of asserting. * optabs.h (can_vec_cmp_compare_p): New function. (get_rtx_code_1): New function.
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c78
1 files changed, 63 insertions, 15 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 3d5b07d..8d89f08 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -4057,23 +4057,59 @@ can_compare_p (enum rtx_code code, machine_mode mode,
return 0;
}
-/* Return whether the backend can emit a vector comparison for code CODE,
- comparing operands of mode CMP_OP_MODE and producing a result with
- VALUE_MODE. */
+/* Return whether RTL code CODE corresponds to an unsigned optab. */
+
+static bool
+unsigned_optab_p (enum rtx_code code)
+{
+ return code == LTU || code == LEU || code == GTU || code == GEU;
+}
+
+/* Return whether the backend-emitted comparison for code CODE, comparing
+ operands of mode VALUE_MODE and producing a result with MASK_MODE, matches
+ operand OPNO of pattern ICODE. */
+
+static bool
+insn_predicate_matches_p (enum insn_code icode, unsigned int opno,
+ enum rtx_code code, machine_mode mask_mode,
+ machine_mode value_mode)
+{
+ rtx reg1 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 1);
+ rtx reg2 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 2);
+ rtx test = alloca_rtx_fmt_ee (code, mask_mode, reg1, reg2);
+ return insn_operand_matches (icode, opno, test);
+}
+
+/* Return whether the backend can emit a vector comparison (vec_cmp/vec_cmpu)
+ for code CODE, comparing operands of mode VALUE_MODE and producing a result
+ with MASK_MODE. */
+
+bool
+can_vec_cmp_compare_p (enum rtx_code code, machine_mode value_mode,
+ machine_mode mask_mode)
+{
+ enum insn_code icode
+ = get_vec_cmp_icode (value_mode, mask_mode, unsigned_optab_p (code));
+ if (icode == CODE_FOR_nothing)
+ return false;
+
+ return insn_predicate_matches_p (icode, 1, code, mask_mode, value_mode);
+}
+
+/* Return whether the backend can emit a vector comparison (vcond/vcondu) for
+ code CODE, comparing operands of mode CMP_OP_MODE and producing a result
+ with VALUE_MODE. */
bool
can_vcond_compare_p (enum rtx_code code, machine_mode value_mode,
machine_mode cmp_op_mode)
{
- enum insn_code icode;
- bool unsigned_p = (code == LTU || code == LEU || code == GTU || code == GEU);
- rtx reg1 = alloca_raw_REG (cmp_op_mode, LAST_VIRTUAL_REGISTER + 1);
- rtx reg2 = alloca_raw_REG (cmp_op_mode, LAST_VIRTUAL_REGISTER + 2);
- rtx test = alloca_rtx_fmt_ee (code, value_mode, reg1, reg2);
-
- return (icode = get_vcond_icode (value_mode, cmp_op_mode, unsigned_p))
- != CODE_FOR_nothing
- && insn_operand_matches (icode, 3, test);
+ enum insn_code icode
+ = get_vcond_icode (value_mode, cmp_op_mode, unsigned_optab_p (code));
+ if (icode == CODE_FOR_nothing)
+ return false;
+
+ return insn_predicate_matches_p (icode, 3, code, value_mode, cmp_op_mode);
}
/* Return whether the backend can emit vector set instructions for inserting
@@ -5626,11 +5662,11 @@ gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
return insn;
}
-/* Return rtx code for TCODE. Use UNSIGNEDP to select signed
+/* Return rtx code for TCODE or UNKNOWN. Use UNSIGNEDP to select signed
or unsigned operation code. */
enum rtx_code
-get_rtx_code (enum tree_code tcode, bool unsignedp)
+get_rtx_code_1 (enum tree_code tcode, bool unsignedp)
{
enum rtx_code code;
switch (tcode)
@@ -5688,11 +5724,23 @@ get_rtx_code (enum tree_code tcode, bool unsignedp)
break;
default:
- gcc_unreachable ();
+ code = UNKNOWN;
+ break;
}
return code;
}
+/* Return rtx code for TCODE. Use UNSIGNEDP to select signed
+ or unsigned operation code. */
+
+enum rtx_code
+get_rtx_code (enum tree_code tcode, bool unsignedp)
+{
+ enum rtx_code code = get_rtx_code_1 (tcode, unsignedp);
+ gcc_assert (code != UNKNOWN);
+ return code;
+}
+
/* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
select signed or unsigned operators. OPNO holds the index of the
first comparison operand for insn ICODE. Do not generate the