Introduce can_vcond_compare_p function
z13 supports only non-signaling vector comparisons. This means we cannot vectorize LT, LE, GT, GE and LTGT when compiling for z13. However, we cannot express this restriction today: the code only checks whether vcond$a$b optab exists, but this does not say anything about the operation. Introduce a function that checks whether back-end supports vector comparisons with individual rtx codes by matching vcond expander's third argument with a fake comparison with the corresponding rtx code. gcc/ChangeLog: 2019-10-07 Ilya Leoshkevich <iii@linux.ibm.com> PR target/77918 * optabs-tree.c (vcond_icode_p): New function. (vcond_eq_icode_p): Likewise. (expand_vec_cond_expr_p): Use vcond_icode_p and vcond_eq_icode_p. * optabs.c (can_vcond_compare_p): New function. * optabs.h (can_vcond_compare_p): Likewise. From-SVN: r276660
This commit is contained in:
parent
70e2a30ac8
commit
dcd2ca63ec
@ -1,3 +1,13 @@
|
||||
2019-10-07 Ilya Leoshkevich <iii@linux.ibm.com>
|
||||
|
||||
PR target/77918
|
||||
* optabs-tree.c (vcond_icode_p): New function.
|
||||
(vcond_eq_icode_p): Likewise.
|
||||
(expand_vec_cond_expr_p): Use vcond_icode_p and
|
||||
vcond_eq_icode_p.
|
||||
* optabs.c (can_vcond_compare_p): New function.
|
||||
* optabs.h (can_vcond_compare_p): Likewise.
|
||||
|
||||
2019-10-07 Ilya Leoshkevich <iii@linux.ibm.com>
|
||||
|
||||
PR target/77918
|
||||
|
@ -23,7 +23,10 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "coretypes.h"
|
||||
#include "target.h"
|
||||
#include "insn-codes.h"
|
||||
#include "rtl.h"
|
||||
#include "tree.h"
|
||||
#include "memmodel.h"
|
||||
#include "optabs.h"
|
||||
#include "optabs-tree.h"
|
||||
#include "stor-layout.h"
|
||||
|
||||
@ -329,6 +332,31 @@ expand_vec_cmp_expr_p (tree value_type, tree mask_type, enum tree_code code)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return true iff vcond_optab/vcondu_optab can handle a vector
|
||||
comparison for code CODE, comparing operands of type CMP_OP_TYPE and
|
||||
producing a result of type VALUE_TYPE. */
|
||||
|
||||
static bool
|
||||
vcond_icode_p (tree value_type, tree cmp_op_type, enum tree_code code)
|
||||
{
|
||||
return can_vcond_compare_p (get_rtx_code (code, TYPE_UNSIGNED (cmp_op_type)),
|
||||
TYPE_MODE (value_type), TYPE_MODE (cmp_op_type));
|
||||
}
|
||||
|
||||
/* Return true iff vcondeq_optab can handle a vector comparison for code CODE,
|
||||
comparing operands of type CMP_OP_TYPE and producing a result of type
|
||||
VALUE_TYPE. */
|
||||
|
||||
static bool
|
||||
vcond_eq_icode_p (tree value_type, tree cmp_op_type, enum tree_code code)
|
||||
{
|
||||
if (code != EQ_EXPR && code != NE_EXPR)
|
||||
return false;
|
||||
|
||||
return get_vcond_eq_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type))
|
||||
!= CODE_FOR_nothing;
|
||||
}
|
||||
|
||||
/* Return TRUE iff, appropriate vector insns are available
|
||||
for vector cond expr with vector type VALUE_TYPE and a comparison
|
||||
with operand vector types in CMP_OP_TYPE. */
|
||||
@ -347,14 +375,13 @@ expand_vec_cond_expr_p (tree value_type, tree cmp_op_type, enum tree_code code)
|
||||
|| maybe_ne (GET_MODE_NUNITS (value_mode), GET_MODE_NUNITS (cmp_op_mode)))
|
||||
return false;
|
||||
|
||||
if (get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type),
|
||||
TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing
|
||||
&& ((code != EQ_EXPR && code != NE_EXPR)
|
||||
|| get_vcond_eq_icode (TYPE_MODE (value_type),
|
||||
TYPE_MODE (cmp_op_type)) == CODE_FOR_nothing))
|
||||
if (TREE_CODE_CLASS (code) != tcc_comparison)
|
||||
/* This may happen, for example, if code == SSA_NAME, in which case we
|
||||
cannot be certain whether a vector insn is available. */
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return vcond_icode_p (value_type, cmp_op_type, code)
|
||||
|| vcond_eq_icode_p (value_type, cmp_op_type, code);
|
||||
}
|
||||
|
||||
/* Use the current target and options to initialize
|
||||
|
19
gcc/optabs.c
19
gcc/optabs.c
@ -3819,6 +3819,25 @@ 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. */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* This function is called when we are going to emit a compare instruction that
|
||||
compares the values found in X and Y, using the rtl operator COMPARISON.
|
||||
|
||||
|
@ -242,6 +242,12 @@ enum can_compare_purpose
|
||||
(without splitting it into pieces). */
|
||||
extern int can_compare_p (enum rtx_code, machine_mode,
|
||||
enum can_compare_purpose);
|
||||
|
||||
/* 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. */
|
||||
extern bool can_vcond_compare_p (enum rtx_code, machine_mode, machine_mode);
|
||||
|
||||
extern rtx prepare_operand (enum insn_code, rtx, int, machine_mode,
|
||||
machine_mode, int);
|
||||
/* Emit a pair of rtl insns to compare two rtx's and to jump
|
||||
|
Loading…
Reference in New Issue
Block a user