diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2018-01-03 21:42:12 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-01-03 21:42:12 +0000 |
commit | 928686b1c6d0a8b791ec08b2588a5fb8118d191c (patch) | |
tree | 88cbf9a40cb8344238ea471bb4c046691b5a1e40 /gcc/tree-vect-stmts.c | |
parent | edab8e10e3cc127335ae4fa7a5935a28acfae0a9 (diff) | |
download | gcc-928686b1c6d0a8b791ec08b2588a5fb8118d191c.zip gcc-928686b1c6d0a8b791ec08b2588a5fb8118d191c.tar.gz gcc-928686b1c6d0a8b791ec08b2588a5fb8118d191c.tar.bz2 |
poly_int: TYPE_VECTOR_SUBPARTS
This patch changes TYPE_VECTOR_SUBPARTS to a poly_uint64. The value is
encoded in the 10-bit precision field and was previously always stored
as a simple log2 value. The challenge was to use this 10 bits to
encode the number of elements in variable-length vectors, so that
we didn't need to increase the size of the tree.
In practice the number of vector elements should always have the form
N + N * X (where X is the runtime value), and as for constant-length
vectors, N must be a power of 2 (even though X itself might not be).
The patch therefore uses the low 8 bits to encode log2(N) and bit
8 to select between constant-length and variable-length vectors.
Targets without variable-length vectors continue to use the old scheme.
A new valid_vector_subparts_p function tests whether a given number
of elements can be encoded. This is false for the vector modes that
represent an LD3 or ST3 vector triple (which we want to treat as arrays
of vectors rather than single vectors).
Most of the patch is mechanical; previous patches handled the changes
that weren't entirely straightforward.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* tree.h (TYPE_VECTOR_SUBPARTS): Turn into a function and handle
polynomial numbers of units.
(SET_TYPE_VECTOR_SUBPARTS): Likewise.
(valid_vector_subparts_p): New function.
(build_vector_type): Remove temporary shim and take the number
of units as a poly_uint64 rather than an int.
(build_opaque_vector_type): Take the number of units as a
poly_uint64 rather than an int.
* tree.c (build_vector_from_ctor): Handle polynomial
TYPE_VECTOR_SUBPARTS.
(type_hash_canon_hash, type_cache_hasher::equal): Likewise.
(uniform_vector_p, vector_type_mode, build_vector): Likewise.
(build_vector_from_val): If the number of units is variable,
use build_vec_duplicate_cst for constant operands and
VEC_DUPLICATE_EXPR otherwise.
(make_vector_type): Remove temporary is_constant ().
(build_vector_type, build_opaque_vector_type): Take the number of
units as a poly_uint64 rather than an int.
(check_vector_cst): Handle polynomial TYPE_VECTOR_SUBPARTS and
VECTOR_CST_NELTS.
* cfgexpand.c (expand_debug_expr): Likewise.
* expr.c (count_type_elements, categorize_ctor_elements_1): Likewise.
(store_constructor, expand_expr_real_1): Likewise.
(const_scalar_mask_from_tree): Likewise.
* fold-const-call.c (fold_const_reduction): Likewise.
* fold-const.c (const_binop, const_unop, fold_convert_const): Likewise.
(operand_equal_p, fold_vec_perm, fold_ternary_loc): Likewise.
(native_encode_vector, vec_cst_ctor_to_array): Likewise.
(fold_relational_const): Likewise.
(native_interpret_vector): Likewise. Change the size from an
int to an unsigned int.
* gimple-fold.c (gimple_fold_stmt_to_constant_1): Handle polynomial
TYPE_VECTOR_SUBPARTS.
(gimple_fold_indirect_ref, gimple_build_vector): Likewise.
(gimple_build_vector_from_val): Use VEC_DUPLICATE_EXPR when
duplicating a non-constant operand into a variable-length vector.
* hsa-brig.c (hsa_op_immed::emit_to_buffer): Handle polynomial
TYPE_VECTOR_SUBPARTS and VECTOR_CST_NELTS.
* ipa-icf.c (sem_variable::equals): Likewise.
* match.pd: Likewise.
* omp-simd-clone.c (simd_clone_subparts): Likewise.
* print-tree.c (print_node): Likewise.
* stor-layout.c (layout_type): Likewise.
* targhooks.c (default_builtin_vectorization_cost): Likewise.
* tree-cfg.c (verify_gimple_comparison): Likewise.
(verify_gimple_assign_binary): Likewise.
(verify_gimple_assign_ternary): Likewise.
(verify_gimple_assign_single): Likewise.
* tree-pretty-print.c (dump_generic_node): Likewise.
* tree-ssa-forwprop.c (simplify_vector_constructor): Likewise.
(simplify_bitfield_ref, is_combined_permutation_identity): Likewise.
* tree-vect-data-refs.c (vect_permute_store_chain): Likewise.
(vect_grouped_load_supported, vect_permute_load_chain): Likewise.
(vect_shift_permute_load_chain): Likewise.
* tree-vect-generic.c (nunits_for_known_piecewise_op): Likewise.
(expand_vector_condition, optimize_vector_constructor): Likewise.
(lower_vec_perm, get_compute_type): Likewise.
* tree-vect-loop.c (vect_determine_vectorization_factor): Likewise.
(get_initial_defs_for_reduction, vect_transform_loop): Likewise.
* tree-vect-patterns.c (vect_recog_bool_pattern): Likewise.
(vect_recog_mask_conversion_pattern): Likewise.
* tree-vect-slp.c (vect_supported_load_permutation_p): Likewise.
(vect_get_constant_vectors, vect_transform_slp_perm_load): Likewise.
* tree-vect-stmts.c (perm_mask_for_reverse): Likewise.
(get_group_load_store_type, vectorizable_mask_load_store): Likewise.
(vectorizable_bswap, simd_clone_subparts, vectorizable_assignment)
(vectorizable_shift, vectorizable_operation, vectorizable_store)
(vectorizable_load, vect_is_simple_cond, vectorizable_comparison)
(supportable_widening_operation): Likewise.
(supportable_narrowing_operation): Likewise.
* tree-vector-builder.c (tree_vector_builder::binary_encoded_nelts):
Likewise.
* varasm.c (output_constant): Likewise.
gcc/ada/
* gcc-interface/utils.c (gnat_types_compatible_p): Handle
polynomial TYPE_VECTOR_SUBPARTS.
gcc/brig/
* brigfrontend/brig-to-generic.cc (get_unsigned_int_type): Handle
polynomial TYPE_VECTOR_SUBPARTS.
* brigfrontend/brig-util.h (gccbrig_type_vector_subparts): Likewise.
gcc/c-family/
* c-common.c (vector_types_convertible_p, c_build_vec_perm_expr)
(convert_vector_to_array_for_subscript): Handle polynomial
TYPE_VECTOR_SUBPARTS.
(c_common_type_for_mode): Check valid_vector_subparts_p.
* c-pretty-print.c (pp_c_initializer_list): Handle polynomial
VECTOR_CST_NELTS.
gcc/c/
* c-typeck.c (comptypes_internal, build_binary_op): Handle polynomial
TYPE_VECTOR_SUBPARTS.
gcc/cp/
* constexpr.c (cxx_eval_array_reference): Handle polynomial
VECTOR_CST_NELTS.
(cxx_fold_indirect_ref): Handle polynomial TYPE_VECTOR_SUBPARTS.
* call.c (build_conditional_expr_1): Likewise.
* decl.c (cp_finish_decomp): Likewise.
* mangle.c (write_type): Likewise.
* typeck.c (structural_comptypes): Likewise.
(cp_build_binary_op): Likewise.
* typeck2.c (process_init_constructor_array): Likewise.
gcc/fortran/
* trans-types.c (gfc_type_for_mode): Check valid_vector_subparts_p.
gcc/lto/
* lto-lang.c (lto_type_for_mode): Check valid_vector_subparts_p.
* lto.c (hash_canonical_type): Handle polynomial TYPE_VECTOR_SUBPARTS.
gcc/go/
* go-lang.c (go_langhook_type_for_mode): Check valid_vector_subparts_p.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256197
Diffstat (limited to 'gcc/tree-vect-stmts.c')
-rw-r--r-- | gcc/tree-vect-stmts.c | 103 |
1 files changed, 56 insertions, 47 deletions
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 71bc3c1..14ffdd4 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1721,13 +1721,11 @@ compare_step_with_zero (gimple *stmt) static tree perm_mask_for_reverse (tree vectype) { - int i, nunits; - - nunits = TYPE_VECTOR_SUBPARTS (vectype); + poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); /* The encoding has a single stepped pattern. */ vec_perm_builder sel (nunits, 1, 3); - for (i = 0; i < 3; ++i) + for (int i = 0; i < 3; ++i) sel.quick_push (nunits - 1 - i); vec_perm_indices indices (sel, 1, nunits); @@ -1760,7 +1758,7 @@ get_group_load_store_type (gimple *stmt, tree vectype, bool slp, bool single_element_p = (stmt == first_stmt && !GROUP_NEXT_ELEMENT (stmt_info)); unsigned HOST_WIDE_INT gap = GROUP_GAP (vinfo_for_stmt (first_stmt)); - unsigned nunits = TYPE_VECTOR_SUBPARTS (vectype); + poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); /* True if the vectorized statements would access beyond the last statement in the group. */ @@ -1784,7 +1782,7 @@ get_group_load_store_type (gimple *stmt, tree vectype, bool slp, /* Try to use consecutive accesses of GROUP_SIZE elements, separated by the stride, until we have a complete vector. Fall back to scalar accesses if that isn't possible. */ - if (nunits % group_size == 0) + if (multiple_p (nunits, group_size)) *memory_access_type = VMAT_STRIDED_SLP; else *memory_access_type = VMAT_ELEMENTWISE; @@ -2112,7 +2110,8 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi, mask_vectype = get_mask_type_for_scalar_type (TREE_TYPE (vectype)); if (!mask_vectype || !VECTOR_BOOLEAN_TYPE_P (mask_vectype) - || TYPE_VECTOR_SUBPARTS (mask_vectype) != TYPE_VECTOR_SUBPARTS (vectype)) + || maybe_ne (TYPE_VECTOR_SUBPARTS (mask_vectype), + TYPE_VECTOR_SUBPARTS (vectype))) return false; if (gimple_call_internal_fn (stmt) == IFN_MASK_STORE) @@ -2269,8 +2268,8 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi, if (!useless_type_conversion_p (idxtype, TREE_TYPE (op))) { - gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op)) - == TYPE_VECTOR_SUBPARTS (idxtype)); + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op)), + TYPE_VECTOR_SUBPARTS (idxtype))); var = vect_get_new_ssa_name (idxtype, vect_simple_var); op = build1 (VIEW_CONVERT_EXPR, idxtype, op); new_stmt @@ -2295,8 +2294,9 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi, mask_op = vec_mask; if (!useless_type_conversion_p (masktype, TREE_TYPE (vec_mask))) { - gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask_op)) - == TYPE_VECTOR_SUBPARTS (masktype)); + gcc_assert + (known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask_op)), + TYPE_VECTOR_SUBPARTS (masktype))); var = vect_get_new_ssa_name (masktype, vect_simple_var); mask_op = build1 (VIEW_CONVERT_EXPR, masktype, mask_op); new_stmt @@ -2312,8 +2312,8 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi, if (!useless_type_conversion_p (vectype, rettype)) { - gcc_assert (TYPE_VECTOR_SUBPARTS (vectype) - == TYPE_VECTOR_SUBPARTS (rettype)); + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (vectype), + TYPE_VECTOR_SUBPARTS (rettype))); op = vect_get_new_ssa_name (rettype, vect_simple_var); gimple_call_set_lhs (new_stmt, op); vect_finish_stmt_generation (stmt, new_stmt, gsi); @@ -2507,11 +2507,14 @@ vectorizable_bswap (gimple *stmt, gimple_stmt_iterator *gsi, tree op, vectype; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); - unsigned ncopies, nunits; + unsigned ncopies; + unsigned HOST_WIDE_INT nunits, num_bytes; op = gimple_call_arg (stmt, 0); vectype = STMT_VINFO_VECTYPE (stmt_info); - nunits = TYPE_VECTOR_SUBPARTS (vectype); + + if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant (&nunits)) + return false; /* Multiple types in SLP are handled by creating the appropriate number of vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in @@ -2527,7 +2530,9 @@ vectorizable_bswap (gimple *stmt, gimple_stmt_iterator *gsi, if (! char_vectype) return false; - unsigned int num_bytes = TYPE_VECTOR_SUBPARTS (char_vectype); + if (!TYPE_VECTOR_SUBPARTS (char_vectype).is_constant (&num_bytes)) + return false; + unsigned word_bytes = num_bytes / nunits; /* The encoding uses one stepped pattern for each byte in the word. */ @@ -3226,7 +3231,7 @@ vect_simd_lane_linear (tree op, struct loop *loop, static unsigned HOST_WIDE_INT simd_clone_subparts (tree vectype) { - return TYPE_VECTOR_SUBPARTS (vectype); + return TYPE_VECTOR_SUBPARTS (vectype).to_constant (); } /* Function vectorizable_simd_clone_call. @@ -4745,7 +4750,7 @@ vectorizable_assignment (gimple *stmt, gimple_stmt_iterator *gsi, op = TREE_OPERAND (op, 0); tree vectype = STMT_VINFO_VECTYPE (stmt_info); - unsigned int nunits = TYPE_VECTOR_SUBPARTS (vectype); + poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); /* Multiple types in SLP are handled by creating the appropriate number of vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in @@ -4770,7 +4775,7 @@ vectorizable_assignment (gimple *stmt, gimple_stmt_iterator *gsi, if ((CONVERT_EXPR_CODE_P (code) || code == VIEW_CONVERT_EXPR) && (!vectype_in - || TYPE_VECTOR_SUBPARTS (vectype_in) != nunits + || maybe_ne (TYPE_VECTOR_SUBPARTS (vectype_in), nunits) || (GET_MODE_SIZE (TYPE_MODE (vectype)) != GET_MODE_SIZE (TYPE_MODE (vectype_in))))) return false; @@ -4919,8 +4924,8 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi, int ndts = 2; gimple *new_stmt = NULL; stmt_vec_info prev_stmt_info; - int nunits_in; - int nunits_out; + poly_uint64 nunits_in; + poly_uint64 nunits_out; tree vectype_out; tree op1_vectype; int ncopies; @@ -4987,7 +4992,7 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi, nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); nunits_in = TYPE_VECTOR_SUBPARTS (vectype); - if (nunits_out != nunits_in) + if (maybe_ne (nunits_out, nunits_in)) return false; op1 = gimple_assign_rhs2 (stmt); @@ -5287,8 +5292,8 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi, int ndts = 3; gimple *new_stmt = NULL; stmt_vec_info prev_stmt_info; - int nunits_in; - int nunits_out; + poly_uint64 nunits_in; + poly_uint64 nunits_out; tree vectype_out; int ncopies; int j, i; @@ -5400,7 +5405,7 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi, nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); nunits_in = TYPE_VECTOR_SUBPARTS (vectype); - if (nunits_out != nunits_in) + if (maybe_ne (nunits_out, nunits_in)) return false; if (op_type == binary_op || op_type == ternary_op) @@ -5972,8 +5977,8 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, if (!useless_type_conversion_p (srctype, TREE_TYPE (src))) { - gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (src)) - == TYPE_VECTOR_SUBPARTS (srctype)); + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (src)), + TYPE_VECTOR_SUBPARTS (srctype))); var = vect_get_new_ssa_name (srctype, vect_simple_var); src = build1 (VIEW_CONVERT_EXPR, srctype, src); new_stmt = gimple_build_assign (var, VIEW_CONVERT_EXPR, src); @@ -5983,8 +5988,8 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, if (!useless_type_conversion_p (idxtype, TREE_TYPE (op))) { - gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op)) - == TYPE_VECTOR_SUBPARTS (idxtype)); + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op)), + TYPE_VECTOR_SUBPARTS (idxtype))); var = vect_get_new_ssa_name (idxtype, vect_simple_var); op = build1 (VIEW_CONVERT_EXPR, idxtype, op); new_stmt = gimple_build_assign (var, VIEW_CONVERT_EXPR, op); @@ -7023,8 +7028,8 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, if (!useless_type_conversion_p (idxtype, TREE_TYPE (op))) { - gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op)) - == TYPE_VECTOR_SUBPARTS (idxtype)); + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (op)), + TYPE_VECTOR_SUBPARTS (idxtype))); var = vect_get_new_ssa_name (idxtype, vect_simple_var); op = build1 (VIEW_CONVERT_EXPR, idxtype, op); new_stmt @@ -7038,8 +7043,8 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, if (!useless_type_conversion_p (vectype, rettype)) { - gcc_assert (TYPE_VECTOR_SUBPARTS (vectype) - == TYPE_VECTOR_SUBPARTS (rettype)); + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (vectype), + TYPE_VECTOR_SUBPARTS (rettype))); op = vect_get_new_ssa_name (rettype, vect_simple_var); gimple_call_set_lhs (new_stmt, op); vect_finish_stmt_generation (stmt, new_stmt, gsi); @@ -7936,7 +7941,8 @@ vect_is_simple_cond (tree cond, vec_info *vinfo, return false; if (vectype1 && vectype2 - && TYPE_VECTOR_SUBPARTS (vectype1) != TYPE_VECTOR_SUBPARTS (vectype2)) + && maybe_ne (TYPE_VECTOR_SUBPARTS (vectype1), + TYPE_VECTOR_SUBPARTS (vectype2))) return false; *comp_vectype = vectype1 ? vectype1 : vectype2; @@ -8353,7 +8359,7 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi, loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); enum vect_def_type dts[2] = {vect_unknown_def_type, vect_unknown_def_type}; int ndts = 2; - unsigned nunits; + poly_uint64 nunits; int ncopies; enum tree_code code, bitop1 = NOP_EXPR, bitop2 = NOP_EXPR; stmt_vec_info prev_stmt_info = NULL; @@ -8413,7 +8419,8 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi, return false; if (vectype1 && vectype2 - && TYPE_VECTOR_SUBPARTS (vectype1) != TYPE_VECTOR_SUBPARTS (vectype2)) + && maybe_ne (TYPE_VECTOR_SUBPARTS (vectype1), + TYPE_VECTOR_SUBPARTS (vectype2))) return false; vectype = vectype1 ? vectype1 : vectype2; @@ -8422,10 +8429,10 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi, if (!vectype) { vectype = get_vectype_for_scalar_type (TREE_TYPE (rhs1)); - if (TYPE_VECTOR_SUBPARTS (vectype) != nunits) + if (maybe_ne (TYPE_VECTOR_SUBPARTS (vectype), nunits)) return false; } - else if (nunits != TYPE_VECTOR_SUBPARTS (vectype)) + else if (maybe_ne (nunits, TYPE_VECTOR_SUBPARTS (vectype))) return false; /* Can't compare mask and non-mask types. */ @@ -9656,8 +9663,8 @@ supportable_widening_operation (enum tree_code code, gimple *stmt, vector types having the same QImode. Thus we add additional check for elements number. */ return (!VECTOR_BOOLEAN_TYPE_P (vectype) - || (TYPE_VECTOR_SUBPARTS (vectype) / 2 - == TYPE_VECTOR_SUBPARTS (wide_vectype))); + || known_eq (TYPE_VECTOR_SUBPARTS (vectype), + TYPE_VECTOR_SUBPARTS (wide_vectype) * 2)); /* Check if it's a multi-step conversion that can be done using intermediate types. */ @@ -9678,8 +9685,10 @@ supportable_widening_operation (enum tree_code code, gimple *stmt, intermediate_mode = insn_data[icode1].operand[0].mode; if (VECTOR_BOOLEAN_TYPE_P (prev_type)) { + poly_uint64 intermediate_nelts + = exact_div (TYPE_VECTOR_SUBPARTS (prev_type), 2); intermediate_type - = build_truth_vector_type (TYPE_VECTOR_SUBPARTS (prev_type) / 2, + = build_truth_vector_type (intermediate_nelts, current_vector_size); if (intermediate_mode != TYPE_MODE (intermediate_type)) return false; @@ -9709,8 +9718,8 @@ supportable_widening_operation (enum tree_code code, gimple *stmt, if (insn_data[icode1].operand[0].mode == TYPE_MODE (wide_vectype) && insn_data[icode2].operand[0].mode == TYPE_MODE (wide_vectype)) return (!VECTOR_BOOLEAN_TYPE_P (vectype) - || (TYPE_VECTOR_SUBPARTS (intermediate_type) / 2 - == TYPE_VECTOR_SUBPARTS (wide_vectype))); + || known_eq (TYPE_VECTOR_SUBPARTS (intermediate_type), + TYPE_VECTOR_SUBPARTS (wide_vectype) * 2)); prev_type = intermediate_type; prev_mode = intermediate_mode; @@ -9798,8 +9807,8 @@ supportable_narrowing_operation (enum tree_code code, vector types having the same QImode. Thus we add additional check for elements number. */ return (!VECTOR_BOOLEAN_TYPE_P (vectype) - || (TYPE_VECTOR_SUBPARTS (vectype) * 2 - == TYPE_VECTOR_SUBPARTS (narrow_vectype))); + || known_eq (TYPE_VECTOR_SUBPARTS (vectype) * 2, + TYPE_VECTOR_SUBPARTS (narrow_vectype))); /* Check if it's a multi-step conversion that can be done using intermediate types. */ @@ -9865,8 +9874,8 @@ supportable_narrowing_operation (enum tree_code code, if (insn_data[icode1].operand[0].mode == TYPE_MODE (narrow_vectype)) return (!VECTOR_BOOLEAN_TYPE_P (vectype) - || (TYPE_VECTOR_SUBPARTS (intermediate_type) * 2 - == TYPE_VECTOR_SUBPARTS (narrow_vectype))); + || known_eq (TYPE_VECTOR_SUBPARTS (intermediate_type) * 2, + TYPE_VECTOR_SUBPARTS (narrow_vectype))); prev_mode = intermediate_mode; prev_type = intermediate_type; |