The following expands the double-conversion match patterns to also
cover integer vectors (it already supports float vectors), adding
required guards for supportability. I have simplified
supportable_convert_operation by eliding the useless output code
argument (it's always the same as the input code).
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
* match.pd ((convert (convert @0))): Allow integer vector
types, unify {inside,intrer,final}_vec, guard patterns that
are not correct for vectors and those that are with
checks the resulting conversion is supported by the target.
* optabs-tree.h (supportable_convert_operation): Remove
useless last argument.
* optabs-tree.cc (supportable_convert_operation): Likewise.
(supportable_half_widening_operation): Adjust.
* tree-vect-stmts.cc (vectorizable_conversion): Likewise.
(supportable_indirect_convert_operation): Likewise.
* tree-vect-generic.cc (expand_vector_conversion): Likewise.
* tree-vect-data-refs.cc (vect_gather_scatter_fn_p): Likewise.
* tree-ssa-forwprop.cc (simplify_vector_constructor): Likewise.
Co-Authored-By: H.J. Lu <[email protected]>
---
gcc/match.pd | 38 ++++++++++++++++++++++++--------------
gcc/optabs-tree.cc | 28 ++++++----------------------
gcc/optabs-tree.h | 8 +++-----
gcc/tree-ssa-forwprop.cc | 6 ++----
gcc/tree-vect-data-refs.cc | 5 ++---
gcc/tree-vect-generic.cc | 5 ++---
gcc/tree-vect-stmts.cc | 32 ++++++++++++++------------------
7 files changed, 53 insertions(+), 69 deletions(-)
diff --git a/gcc/match.pd b/gcc/match.pd
index beea45357e2..0a324bef62e 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -5816,24 +5816,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{
tree inside_type = TREE_TYPE (@0);
tree inter_type = TREE_TYPE (@1);
- int inside_int = INTEGRAL_TYPE_P (inside_type);
+ int inside_int = ANY_INTEGRAL_TYPE_P (inside_type);
int inside_ptr = POINTER_TYPE_P (inside_type);
int inside_float = FLOAT_TYPE_P (inside_type);
- int inside_vec = VECTOR_TYPE_P (inside_type);
unsigned int inside_prec = element_precision (inside_type);
int inside_unsignedp = TYPE_UNSIGNED (inside_type);
- int inter_int = INTEGRAL_TYPE_P (inter_type);
+ int inter_int = ANY_INTEGRAL_TYPE_P (inter_type);
int inter_ptr = POINTER_TYPE_P (inter_type);
int inter_float = FLOAT_TYPE_P (inter_type);
- int inter_vec = VECTOR_TYPE_P (inter_type);
unsigned int inter_prec = element_precision (inter_type);
int inter_unsignedp = TYPE_UNSIGNED (inter_type);
- int final_int = INTEGRAL_TYPE_P (type);
+ int final_int = ANY_INTEGRAL_TYPE_P (type);
int final_ptr = POINTER_TYPE_P (type);
int final_float = FLOAT_TYPE_P (type);
- int final_vec = VECTOR_TYPE_P (type);
unsigned int final_prec = element_precision (type);
int final_unsignedp = TYPE_UNSIGNED (type);
+ int is_vec = VECTOR_TYPE_P (type);
+ gcc_checking_assert (is_vec == VECTOR_TYPE_P (inside_type)
+ && is_vec == VECTOR_TYPE_P (inter_type));
}
(switch
/* In addition to the cases of two conversions in a row
@@ -5845,7 +5845,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (inside_type)))
&& (((inter_int || inter_ptr) && final_int)
|| (inter_float && final_float))
- && inter_prec >= final_prec)
+ && inter_prec >= final_prec
+ && (! is_vec
+ || supportable_convert_operation (ocvt, type, TREE_TYPE (@0))))
(ocvt @0))
/* Likewise, if the intermediate and initial types are either both
@@ -5856,7 +5858,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (((inter_int && inside_int) || (inter_float && inside_float))
&& (final_int || final_float)
&& inter_prec >= inside_prec
- && (inter_float || inter_unsignedp == inside_unsignedp))
+ && (inter_float || inter_unsignedp == inside_unsignedp)
+ && (! is_vec
+ || supportable_convert_operation (ocvt, type, TREE_TYPE (@0))))
(ocvt @0))
/* If we have a sign-extension of a zero-extended value, we can
@@ -5869,7 +5873,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& inside_unsignedp && !inter_unsignedp)
|| final_prec == inter_prec
|| (inside_prec < inter_prec && inter_prec > final_prec
- && !inside_unsignedp && inter_unsignedp)))
+ && !inside_unsignedp && inter_unsignedp))
+ && (! is_vec
+ || supportable_convert_operation (ocvt, type, TREE_TYPE (@0))))
(ocvt @0))
/* Two conversions in a row are not needed unless:
@@ -5884,7 +5890,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
- the final type is a pointer type and the precisions of the
initial and intermediate types differ. */
(if (! inside_float && ! inter_float && ! final_float
- && ! inside_vec && ! inter_vec && ! final_vec
+ && ! is_vec
&& (inter_prec >= inside_prec || inter_prec >= final_prec)
&& ! (inside_int && inter_int
&& inter_unsignedp != inside_unsignedp
@@ -5902,13 +5908,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
a sign change of the type. */
(if (inside_int && inter_int && final_int
&& final_prec <= inside_prec
- && inter_prec >= inside_prec)
+ && inter_prec >= inside_prec
+ && (! is_vec
+ || supportable_convert_operation (ocvt, type, TREE_TYPE (@0))))
(convert @0))
/* A truncation to an unsigned type (a zero-extension) should be
canonicalized as bitwise and of a mask. */
(if (GIMPLE /* PR70366: doing this in GENERIC breaks -Wconversion. */
&& final_int && inter_int && inside_int
+ && ! is_vec
&& final_prec >= inside_prec
&& inside_prec > inter_prec
&& inter_unsignedp)
@@ -5921,9 +5930,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
represent it exactly and back to an integer, we can skip the
floating-point conversion. */
(if (GIMPLE /* PR66211 */
- && inside_int && inter_float && final_int &&
- (unsigned) significand_size (TYPE_MODE (inter_type))
- >= inside_prec - !inside_unsignedp)
+ && inside_int && inter_float && final_int
+ && ! is_vec
+ && ((unsigned) significand_size (TYPE_MODE (inter_type))
+ >= inside_prec - !inside_unsignedp))
(convert @0)))))))
/* (float_type)(integer_type) x -> trunc (x) if the type of x matches
diff --git a/gcc/optabs-tree.cc b/gcc/optabs-tree.cc
index 1b80cac85c7..3c9329a2f71 100644
--- a/gcc/optabs-tree.cc
+++ b/gcc/optabs-tree.cc
@@ -315,7 +315,6 @@ supportable_half_widening_operation (enum tree_code code,
tree vectype_out,
tree vectype_in, enum tree_code *code1)
{
machine_mode m1,m2;
- enum tree_code dummy_code;
optab op;
gcc_assert (VECTOR_TYPE_P (vectype_out) && VECTOR_TYPE_P (vectype_in));
@@ -342,8 +341,7 @@ supportable_half_widening_operation (enum tree_code code,
tree vectype_out,
return false;
}
- if (!supportable_convert_operation (NOP_EXPR, vectype_out, vectype_in,
- &dummy_code))
+ if (!supportable_convert_operation (NOP_EXPR, vectype_out, vectype_in))
return false;
op = optab_for_tree_code (*code1, vectype_out, optab_vector);
@@ -359,16 +357,11 @@ supportable_half_widening_operation (enum tree_code code,
tree vectype_out,
Convert operations we currently support directly are FIX_TRUNC and FLOAT.
This function checks if these operations are supported
- by the target platform directly (via vector tree-codes).
-
- Output:
- - CODE1 is code of vector operation to be used when
- vectorizing the operation, if available. */
+ by the target platform directly (via vector tree-codes). */
bool
supportable_convert_operation (enum tree_code code,
- tree vectype_out, tree vectype_in,
- enum tree_code *code1)
+ tree vectype_out, tree vectype_in)
{
machine_mode m1,m2;
bool truncp;
@@ -388,24 +381,15 @@ supportable_convert_operation (enum tree_code code,
|| (code == FLOAT_EXPR
&& can_float_p (m1,m2,TYPE_UNSIGNED (vectype_in))
!= CODE_FOR_nothing))
- {
- *code1 = code;
- return true;
- }
+ return true;
if (GET_MODE_UNIT_PRECISION (m1) > GET_MODE_UNIT_PRECISION (m2)
&& can_extend_p (m1, m2, TYPE_UNSIGNED (vectype_in)))
- {
- *code1 = code;
- return true;
- }
+ return true;
if (GET_MODE_UNIT_PRECISION (m1) < GET_MODE_UNIT_PRECISION (m2)
&& convert_optab_handler (trunc_optab, m1, m2) != CODE_FOR_nothing)
- {
- *code1 = code;
- return true;
- }
+ return true;
return false;
}
diff --git a/gcc/optabs-tree.h b/gcc/optabs-tree.h
index dad9ed9b0ba..fb9469aaece 100644
--- a/gcc/optabs-tree.h
+++ b/gcc/optabs-tree.h
@@ -37,11 +37,9 @@ enum optab_subtype
the second argument. The third argument distinguishes between the types of
vector shifts and rotates. */
optab optab_for_tree_code (enum tree_code, const_tree, enum optab_subtype);
-bool
-supportable_half_widening_operation (enum tree_code, tree, tree,
- enum tree_code *);
-bool supportable_convert_operation (enum tree_code, tree, tree,
- enum tree_code *);
+bool supportable_half_widening_operation (enum tree_code, tree, tree,
+ enum tree_code *);
+bool supportable_convert_operation (enum tree_code, tree, tree);
bool expand_vec_cmp_expr_p (tree, tree, enum tree_code);
bool expand_vec_cond_expr_p (tree, tree);
void init_tree_optimization_optabs (tree);
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 75f06c6ba41..0531311444b 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -4112,8 +4112,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
if (conv_code == ERROR_MARK && nelts != refnelts)
conv_src_type = type;
if (conv_code != ERROR_MARK
- && !supportable_convert_operation (conv_code, type, conv_src_type,
- &conv_code))
+ && !supportable_convert_operation (conv_code, type, conv_src_type))
{
/* Only few targets implement direct conversion patterns so try
some simple special cases via VEC_[UN]PACK[_FLOAT]_LO_EXPR. */
@@ -4275,8 +4274,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
tree mask_type, perm_type;
perm_type = TREE_TYPE (orig[0]);
if (conv_code != ERROR_MARK
- && !supportable_convert_operation (conv_code, type, conv_src_type,
- &conv_code))
+ && !supportable_convert_operation (conv_code, type, conv_src_type))
return false;
/* Now that we know the number of elements of the source build the
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index 92aecc656e1..1aa0303d266 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -4726,7 +4726,6 @@ vect_gather_scatter_fn_p (vec_info *vinfo, bool read_p,
bool masked_p,
/* Second pass: No direct match. This means we try to find a sign-swapped
offset vectype. */
- enum tree_code tmp;
for (unsigned int i = 0; i < configs.length (); i++)
{
unsigned int precision
@@ -4735,7 +4734,7 @@ vect_gather_scatter_fn_p (vec_info *vinfo, bool read_p,
bool masked_p,
&& precision >= needed_precision
&& (supportable_convert_operation (CONVERT_EXPR,
configs[i].offset_vectype,
- offset_vectype, &tmp)
+ offset_vectype)
|| (needed_precision == offset_precision
&& tree_nop_conversion_p (configs[i].offset_vectype,
offset_vectype))))
@@ -4789,7 +4788,7 @@ vect_gather_scatter_fn_p (vec_info *vinfo, bool read_p,
bool masked_p,
&& precision >= needed_precision
&& (supportable_convert_operation (CONVERT_EXPR,
configs[i].offset_vectype,
- offset_vectype, &tmp)
+ offset_vectype)
|| (needed_precision == offset_precision
&& tree_nop_conversion_p (configs[i].offset_vectype,
offset_vectype))))
diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc
index a8c31974973..b1491bd39ad 100644
--- a/gcc/tree-vect-generic.cc
+++ b/gcc/tree-vect-generic.cc
@@ -1929,12 +1929,11 @@ expand_vector_conversion (gimple_stmt_iterator *gsi)
{
tree ret1_type = build_vector_type (TREE_TYPE (ret_type), nelts);
tree arg1_type = build_vector_type (TREE_TYPE (arg_type), nelts);
- if (supportable_convert_operation (code, ret1_type, arg1_type,
- &code1))
+ if (supportable_convert_operation (code, ret1_type, arg1_type))
{
new_rhs = expand_vector_piecewise (gsi, do_vec_conversion,
ret_type, arg1_type, arg,
- NULL_TREE, code1, false);
+ NULL_TREE, code, false);
g = gimple_build_assign (lhs, new_rhs);
gsi_replace (gsi, g, false);
return;
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 50fa0e4bc42..a023977bc51 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -5554,12 +5554,11 @@ vectorizable_conversion (vec_info *vinfo,
if (GET_MODE_SIZE (rhs_mode) == fltsz)
{
- tc1 = ERROR_MARK;
gcc_assert (code.is_tree_code ());
if (!supportable_convert_operation ((tree_code) code, vectype_out,
- cvt_type, &tc1))
+ cvt_type))
goto unsupported;
- codecvt1 = tc1;
+ codecvt1 = code;
}
else if (!supportable_widening_operation (code, vectype_out,
cvt_type, evenodd_ok,
@@ -5610,9 +5609,9 @@ vectorizable_conversion (vec_info *vinfo,
cvt_type = get_same_sized_vectype (cvt_type, vectype_in);
if (cvt_type == NULL_TREE)
goto unsupported;
- if (supportable_convert_operation ((tree_code) code, cvt_type,
vectype_in,
- &tc1))
- codecvt1 = tc1;
+ if (supportable_convert_operation ((tree_code) code, cvt_type,
+ vectype_in))
+ codecvt1 = code;
else
goto unsupported;
if (supportable_narrowing_operation (NOP_EXPR, vectype_out, cvt_type,
@@ -5652,9 +5651,9 @@ vectorizable_conversion (vec_info *vinfo,
&interm_types))
goto unsupported;
if (supportable_convert_operation ((tree_code) code, vectype_out,
- cvt_type, &tc1))
+ cvt_type))
{
- codecvt1 = tc1;
+ codecvt1 = code;
modifier = NARROW_SRC;
break;
}
@@ -14300,17 +14299,16 @@ supportable_indirect_convert_operation (code_helper
code,
bool found_mode = false;
scalar_mode lhs_mode = GET_MODE_INNER (TYPE_MODE (vectype_out));
scalar_mode rhs_mode = GET_MODE_INNER (TYPE_MODE (vectype_in));
- tree_code tc1, tc2, code1, code2;
+ tree_code code1, code2;
tree cvt_type = NULL_TREE;
poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (vectype_in);
if (supportable_convert_operation ((tree_code) code,
vectype_out,
- vectype_in,
- &tc1))
+ vectype_in))
{
- converts.safe_push (std::make_pair (vectype_out, tc1));
+ converts.safe_push (std::make_pair (vectype_out, (tree_code) code));
return true;
}
@@ -14412,11 +14410,9 @@ supportable_indirect_convert_operation (code_helper
code,
if (cvt_type == NULL_TREE
|| maybe_ne (TYPE_VECTOR_SUBPARTS (cvt_type), nelts)
|| !supportable_convert_operation ((tree_code) code1,
- vectype_out,
- cvt_type, &tc1)
+ vectype_out, cvt_type)
|| !supportable_convert_operation ((tree_code) code2,
- cvt_type,
- vectype_in, &tc2))
+ cvt_type, vectype_in))
continue;
found_mode = true;
@@ -14425,9 +14421,9 @@ supportable_indirect_convert_operation (code_helper
code,
if (found_mode)
{
- converts.safe_push (std::make_pair (cvt_type, tc2));
+ converts.safe_push (std::make_pair (cvt_type, code2));
if (TYPE_MODE (cvt_type) != TYPE_MODE (vectype_out))
- converts.safe_push (std::make_pair (vectype_out, tc1));
+ converts.safe_push (std::make_pair (vectype_out, code1));
return true;
}
}
--
2.51.0