diff options
author | Ilya Leoshkevich <iii@linux.ibm.com> | 2020-11-24 23:45:59 +0100 |
---|---|---|
committer | Ilya Leoshkevich <iii@linux.ibm.com> | 2020-12-01 12:03:30 +0100 |
commit | 3940daff128a995693b405f47dc706b9622c861b (patch) | |
tree | de52504f33f2fccc221bd94ad8afc1d0cdb780e6 /gcc/optabs.c | |
parent | 0fb378761f2c5eb906bf0a9698112dd65d4dc73b (diff) | |
download | gcc-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.c | 78 |
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 |